繁体   English   中英

jar-in-jar类加载问题

[英]jar-in-jar class loading issue

我按照创建跨平台Java SWT应用程序中描述的步骤进行操作。 我使用swt库创建了一个包含swt_browser.jar的jar,其中只包含我的类。 然后我添加了其他特定于platrom的swt罐子。 我使用下面的代码加载swt_browser.jar和特定于平台的swt库jar。 但不知何故,加载类SWTBrowser的调用抱怨:

java.lang.ClassNotFoundException: org.eclipse.swt.widgets.Layout

你能说出我做错了什么吗?

-----加载swt罐子的代码-------

   ClassLoader parent = Main.class.getClassLoader();
            URL.setURLStreamHandlerFactory(new RsrcURLStreamHandlerFactory(parent));
            URL swtBrowserFileUrl = new URL("rsrc:swt_browser.jar");
            URL swtFileUrl = new URL("rsrc:" + swtFileName);

            ClassLoader cl = new URLClassLoader(new URL[]{swtBrowserFileUrl, swtFileUrl}, parent);
            Method addUrlMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
            addUrlMethod.setAccessible(true);
            addUrlMethod.invoke(cl, swtBrowserFileUrl);
            addUrlMethod.invoke(cl, swtFileUrl);
            Thread.currentThread().setContextClassLoader(cl);
            try {
                // Check we can now load the SWT class -this check passes!
                Class.forName("org.eclipse.swt.widgets.Layout", true, cl);
            } catch (ClassNotFoundException exx) {
                System.err.println("Launch failed: Failed to load SWT class from jar: " + swtFileName);
                throw new RuntimeException(exx);
            }

           //this line below throws exception : java.lang.ClassNotFoundException:     org.eclipse.swt.widgets.Layout 

            Class<?> c = Class.forName("com.sun.star.google.gui.SWTBrowser", true, cl);

            Object obj = c.newInstance();
            Method run = c.getMethod("run", url.getClass()); //$NON-NLS-1$
            run.invoke(obj, new Object[]{url});

你的jar有以下文件结构:

文件结构

您正在设置以下ClassLoaders:

  • 主要的类加载器
    • SWT类加载器

Main类加载器在其类路径中具有以下所有内容:

  • 你的应用课程
  • jar-in-jar类加载器

SWT类加载器在运行时构造,并在其类路径上具有以下内容:

  • 适合您平台的SWT课程

您的加载代码要求SWT类加载器加载SWT类并且可以正常工作。 但是,您要求它加载应用程序类。 它不知道您的应用程序类,因此它委托给它的父类Main类加载器。 这设法加载您的应用程序类,然后尝试引用SWT类。 此引用由加载应用程序类的类加载器(Main类加载器)处理。 这不知道SWT类并抛出异常。

您需要以不同方式打包应用程序。 您需要具有以下类加载器。

  • 主要的类加载器
    • SWT类加载器

Main类加载器在其类路径中具有以下所有内容:

  • 一个应用程序类,用于处理构建SWT类加载器
  • jar-in-jar类加载器

SWT类加载器在运行时构造,并在其类路径上具有以下内容:

  • 适合您平台的SWT课程
  • 你的应用课程

这意味着当您加载应用程序类时,它将由SWT类加载器加载。 这意味着当您的应用引用SWT类时,将使用正确的类加载器。

有关此示例,您可以下载并检查以下jar: https//github.com/downloads/mchr3k/org.intrace/intrace-ui.jar

编辑:生成intrace-ui.jar的ant构建文件可以在这里看到: https//github.com/mchr3k/org.intrace/blob/master/org.intrace/build.xml

特别是,“罐子”目标处理包装。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM