java - 使用反射启动 JavaFX 项目

标签 java javafx reflection

我有一个程序,可以下载 Git 存储库、构建它并启动定义的 Main 类。它可以在普通项目中正常工作,但是当我想启动 JavaFX 项目时,我会收到奇怪的错误,例如:

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at Main.main(Main.java:31)
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: app.UI_Main
    at javafx.application.Application.launch(Application.java:260)
    at app.UI_Main.main(UI_Main.java:31)
    ... 5 more
Caused by: java.lang.ClassNotFoundException: app.UI_Main
    at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:349)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at javafx.application.Application.launch(Application.java:248)
    ... 6 more

我的主要类(class)是:

public class Main {
    private static final String GIT_ADDRESS = "https://github.com/lerryv/CheckCheckerDesktop";
    private static final String MAIN_PATH = "app/";
    private static final String MAIN_CLASS = "app.UI_Main";
    public static void main(String[] args) throws GitAPIException, IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Git.cloneRepository().setURI(GIT_ADDRESS).setDirectory(Paths.get("./dir/").toFile()).call();
        Collection<String> result = compile(Paths.get("./dir/src/").toFile());
        String command = System.getProperty("java.home") + "/../bin/javac -d dirOut -cp \".:json-simple-1.1.jar\" " + result.join(" ");
        Runtime.getRuntime().exec(command);
        URLClassLoader urlClassLoader = URLClassLoader.newInstance(
                new URL[]{
                        new File("dirOut/").toURI().toURL()
                }
        );
        Class clazz = urlClassLoader.loadClass(MAIN_CLASS);
        Method main = clazz.getDeclaredMethod("main", String[].class);
        assert Modifier.isStatic(main.getModifiers());
        main.invoke(null, (Object) args);
    }
    private static Collection<String> compile(File directory) {
        assert directory.isDirectory();
        Collection<String> result = new Collection<>();
        boolean hasFiles = false;
        for (File file: directory.listFiles()) {
            if (file.isDirectory()) {
                result.addAll(compile(file));
            } else {
                if (!hasFiles) {
                    String path = file.getAbsolutePath();
                    String extension = path.substring(path.lastIndexOf(".") + 1);
                    if (extension.equals("java")) hasFiles = true;
                }
            }
        }
        if (hasFiles) result.add(directory.getAbsolutePath() + "/*.java");
        return result;
    };
}

起初我以为它找不到该类,但是当我删除method.invoke语句时,错误就消失了。为什么会发生这种情况?有解决方法吗?

最佳答案

Runtime.getRuntime().exec(command)

这是启动另一个进程,因此执行此行后编译尚未完成,您需要等待此进程结束,并且可能您还应该处理进程的输出/错误流以检查它是否成功.

Process compileProc = Runtime.getRuntime().exec(command);
compileProc.waitFor();

另外,我不知道你想做什么,但请记住,并不是每个人都有可用的编译器并配置了 java.hame 属性,或者将其配置为不同的 java 版本。 (就像较旧的代码,您的代码将无法编译,或者较新的代码,您的代码将无法运行)

关于java - 使用反射启动 JavaFX 项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57287366/

相关文章:

java - Android:将 Parcelable 对象传递给另一个 Activity 时出错

java - 具有缩放、触摸滑动等功能的 Android 图片库 View 的来源

java - 如何在 JUNIT 的wiremock 中匹配精确的 json

javafx - 如何在 SceneBuilder 中更改 TabPane 的标题颜色?

C#,使用反射获取switch中的每个case名称

c# - 如何将 DbSet<T> 转换为 List<T>

java - 我们可以根据 GUI 组件的大小设置/调整 JTable 列的大小吗?

java - NumberAxis.getDisplayPosition(...) 返回 0

JavaFX 11 替换 column.impl_setWidth()?

reflection - 使用构造函数参数通过反射实例化对象