jar-in-jar 类加载问题 [英] jar-in-jar class loading issue

查看:75
本文介绍了jar-in-jar 类加载问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我遵循了

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

特别是jar"目标处理包装.

i followed the steps described at Create cross platform Java SWT Application . i create a jar which has a swt_browser.jar containing only my class using swt library. then i added other platrom-specific swt jars. i use the below code to load the swt_browser.jar and the platform specific swt library jar. but somehow the call for loading class SWTBrowser complains :

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

can you tell what i am doing wrong?

-----code for loading swt jars-------

   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});

解决方案

Your jar has the following file structure:

You are setting up the following ClassLoaders:

  • Main classloader
    • SWT classloader

The Main classloader has all of the following on its classpath:

  • Your app classes
  • The jar-in-jar classloader

The SWT classloader is constructed at runtime and has the following on its classpath:

  • The SWT classes for your platform

Your loading code asks the SWT classloader to load an SWT class and that works. However, you then ask it to load an application class. It doesn't know about your application class so it delegates to its parent, the Main classloader. This manages to load your application class which then tries to reference an SWT class. This reference is handled by the classloader which loaded your application class - the Main classloader. This doesn't know about the SWT class and throws an exception.

You need to package your application differently. You need to have the following classloaders.

  • Main classloader
    • SWT classloader

The Main classloader has all of the following on its classpath:

  • A single app class which handles building the SWT classloader
  • The jar-in-jar classloader

The SWT classloader is constructed at runtime and has the following on its classpath:

  • The SWT classes for your platform
  • Your app classes

This means that when you load your app class it will be loaded by the SWT classloader. This means that when your app refers to SWT classes the correct classloader is used.

For a working example of this, you can download and examine the following jar: https://github.com/downloads/mchr3k/org.intrace/intrace-ui.jar

EDIT: The ant build file which produced intrace-ui.jar can be seen here: https://github.com/mchr3k/org.intrace/blob/master/org.intrace/build.xml

In particular, the "jar" target handles the packaging.

这篇关于jar-in-jar 类加载问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆