从jar加载一个类

时间:2013-12-12 16:53:37

标签: java classloader

我正在尝试从jar加载一个类,我正在使用classLoader。

我有这部分代码用于准备classLoader:

private void loadClass(){

    try{
        JarFile jarFile = new JarFile( Path);
        Enumeration e = jarFile.entries();

        URL[] urls = { new URL("jar:file:" + Path +"!/") };
        classLoader = URLClassLoader.newInstance(urls);


    } catch (MalformedURLException ex) {
        // TODO Auto-generated catch block
        ex.printStackTrace();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

}

现在我加载一个类,然后尝试获取一个新实例

....           
           loadClass();

           Class device = classLoader.loadClass( "org.myPackage.MyClass");

           MyMotherClass Device = ( MyMotherClass) device.newInstance();
...

MyClass扩展了MyMotherClass,当我执行classLoader.loadClass(“org.myPackage.MyClass”)时,MyMotherClass位于classLoader中。 此刻,没事。

现在,在device.newInstance()中,我得到一个例外。问题是MyClass使用的其他类不在类路径中。

我该怎么办?

我有另一个方法在classLoader中加载所有需要的类,但是当我得到新实例时它不起作用。 我不能改变MyClass和其他人

1 个答案:

答案 0 :(得分:2)

这是我用来在运行时动态加载jar的一些代码。我利用反射来规避你不应该这样做的事实(即,在JVM启动后修改类路径)。只需将my.proprietary.exception更改为合理的内容即可。

    /*
     * Adds the supplied library to java.class.path.
     * This is benign if the library is already loaded.
     */
    public static synchronized void loadLibrary(java.io.File jar) throws my.proprietary.exception
    {
        try {
            /*We are using reflection here to circumvent encapsulation; addURL is not public*/
            java.net.URLClassLoader loader = (java.net.URLClassLoader)ClassLoader.getSystemClassLoader();
            java.net.URL url = jar.toURI().toURL();
            /*Disallow if already loaded*/
            for (java.net.URL it : java.util.Arrays.asList(loader.getURLs())){
                if (it.equals(url)){
                    return;
                }
            }
            java.lang.reflect.Method method = java.net.URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{java.net.URL.class});
            method.setAccessible(true); /*promote the method to public access*/
            method.invoke(loader, new Object[]{url});
        } catch (final NoSuchMethodException | 
            java.lang.IllegalAccessException | 
            java.net.MalformedURLException | 
            java.lang.reflect.InvocationTargetException e){
            throw new my.proprietary.exception(e.getMessage());
        }
    }