无法在JavaFX JavaScript中使用URLClassLoader加载自定义类

时间:2013-11-21 21:28:51

标签: java javafx-2 javafx fxml

我正在尝试在FXML JS中加载我的自定义类。

首先,我已将URLClassLoader与我的JAR添加到FXMLLoader实例中:

FXMLLoader loader = new FXMLLoader();
loader.setController(TabController.this);

URLClassLoader fxmlClassLoader = (URLClassLoader) loader.getClassLoader();
loader.setClassLoader(URLClassLoader.newInstance((URL[]) ArrayUtils.addAll(new URL[]{ new File("/home/sk_/projects/mjolnirr/.hive/static/calculator/origJar.jar").toURI().toURL() }, fxmlClassLoader.getURLs())));

然后在FXML JavaScript中:

importClass(com.mjolnirr.sample.SomeTestClass);

失败并显示错误:

sun.org.mozilla.javascript.internal.EvaluatorException: Function importClass must be called with a class; had "[JavaPackage com.mjolnirr.sample.SomeTestClass]" instead. (<Unknown source>#2) in <Unknown source> at line number 2

有人面对吗?

2 个答案:

答案 0 :(得分:0)

好的,我找到了一个黑客解决方案there。简而言之 - 我刚刚将我的URL动态添加到系统类加载器中,如下所示:

public static void addURLToSystemClassLoader(URL url) throws IntrospectionException {
    URLClassLoader systemClassLoader = (URLClassLoader) ClassLoader.getSystemClassLoader();
    Class<URLClassLoader> classLoaderClass = URLClassLoader.class;

    try {
        Method method = classLoaderClass.getDeclaredMethod("addURL", new Class[]{URL.class});
        method.setAccessible(true);
        method.invoke(systemClassLoader, new Object[]{url});
    } catch (Throwable t) {
        t.printStackTrace();
        throw new IntrospectionException("Error when adding url to system ClassLoader ");
    }
}

然后在我的渲染方法中

FXMLLoader loader = new FXMLLoader();
loader.setController(TabController.this);

try {
    addURLToSystemClassLoader(new URL("hive://" + pageURL.getHost() + ":" + pageURL.getPort() + "/" + pageURL.getApplicationName() + "/origJar.jar"));
} catch (Exception e) {
    e.printStackTrace();
}

但这看起来很糟糕。

我认为最初的问题是 - JavaFX脚本引擎有不同的类加载器,FXML加载器不会将它自己传递给脚本引擎。任何人都知道如何为脚本引擎设置类加载器?

答案 1 :(得分:0)

如何将当前线程加载的类显式设置为新的类加载器?

例如:

URL[] urlsForJarFiles = getUrls();
ClassLoader myClassLoader = new URLClassLoader(urlsForJarFiles, ClassLoader.getSystemClassLoader();
Thread.currentThread.setContextClassLoader(myClassLoader);