如何在modulairzed java 11应用程序中动态加载Libreoffice jars而不从自定义类加载器中获得ClassCastException?

问题描述 投票:1回答:1

我试图在运行时从一个模块化的java 11应用程序中加载和访问libreoffice uno jars。

为了在编译时使用libreoffice类,并避免出现分割包的问题,我们将所有的jar合并到一个名为 "Libreoffice uno "的程序中。单个 有一个自动模块名称 org.jabref.thirdparty.libreoffice.

要从libreoffice安装目录中加载jars(例如:.com)。C:\Program Files\LibreOffice\program\classes 为了确保从程序文件而不是从模块路径加载jars,我创建了一个自定义Classloader。

   URL[] urls = jarUrls.toArray(new URL[3]);
    Class<Bootstrap> clazz  = (Class<Bootstrap>) Class.forName("com.sun.star.comp.helper.Bootstrap", true, new ChildFirstClassLoader(urls, this.getClass().getClassLoader()));
    Boostrap boot = clazz.getDeclaredConstructor().newInstance();
    XComponentContext xContext = boot.bootstrap():

现在这给了我以下错误。

 java.lang.ClassCastException: class com.sun.star.comp.helper.Bootstrap cannot be cast to class com.sun.star.comp.helper.Bootstrap (com.sun.star.comp.helper.Bootstrap is in unnamed module of loader org.jabref.logic.openoffice.ChildFirstClassLoader @13c4b54c; com.sun.star.comp.helper.Bootstrap is in module org.jabref.thirdparty.libreoffice of loader 'app')

我确实理解这里的问题,也读了很多关于这个问题的东西,但是找不到解决这个问题的方法。关键的问题是,我必须使用LO文件夹中的jar,因为否则它就找不到libreoffice实例。我想过把模块化的jar也放到LO文件夹里,但不知道这样做是否可行。

在Java 8下,我们使用典型的 "反射+addUrls "的方法,因为所有的东西都在classpath上。

这就是自定义类laoder。

public class ChildFirstClassLoader extends URLClassLoader {

    public ChildFirstClassLoader(URL[] urls, ClassLoader parent) {
        super(urls, parent);
    }

    @Override
    protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException {
        // has the class loaded already?
        Class<?> loadedClass = findLoadedClass(name);
        if (loadedClass == null) {
            try {
                // find the class from given jar urls 
                loadedClass = findClass(name);
            } catch (ClassNotFoundException e) {
                // Hmmm... class does not exist in the given urls.
                // Let's try finding it in our parent classloader.
                // this'll throw ClassNotFoundException in failure.                  
                loadedClass = super.loadClass(name, resolve);
            }
        }
        if (resolve) { // marked to resolve
            resolveClass(loadedClass);
        }
        return loadedClass;
    }
}
java classloader libreoffice jigsaw
1个回答
1
投票

从LibreOffice 7.0开始,现在有一个与Java模块系统相结合的libreoffice.jar。

© www.soinside.com 2019 - 2024. All rights reserved.