ClassLoader只能在classpath中工作而不是url

时间:2014-07-06 16:52:59

标签: java classloader

所以我正在尝试从链接加载文件并在内存中运行它。一切正常工作正常,但只有.jar在项目的类路径中。我的代码如下:

import java.lang.reflect.Method;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.jar.JarInputStream;

public class Main {

    public static URL getURL(String string) throws MalformedURLException {
        try {
            return new URL(string);
        } catch (MalformedURLException x) { return new URL("file:" + string); }
    }

    public static void main(String args[]) throws Exception {

        String jarLocation = "http://www.google.ca/file.jar";
        URL url = new URL(jarLocation);
        getURL(jarLocation);
        JarInputStream jis = new JarInputStream(url.openStream());
        String main = jis.getManifest().getMainAttributes().getValue("Main-Class");
        String classpaths[] = jis.getManifest().getMainAttributes().getValue("Class-Path").split(" ");
        for (String classpath: classpaths) {
            getURL(classpath);
        }
        URLClassLoader loader = new URLClassLoader((new URL[0]));
        Class<?> cls = loader.loadClass(main);
        Thread.currentThread().setContextClassLoader(loader);
        Method m = cls.getMethod("main", new Class[]{new String[0].getClass()});
        m.invoke(null, new Object[]{args});

    }

}

问题在于,无论链接是什么,.jar只会在项目的类路径中运行。 如何从链接加载文件而不是在类路径中加载?

1 个答案:

答案 0 :(得分:1)

这是因为您将.jar网址传递给URLClassloader。在你的代码中它需要一个空数组,所以我不知道如何从jar文件中加载类。

以下是如何修改代码以将jar网址传递给URLClassloader的示例:

public class Main {

    public static URL getURL(String string) throws MalformedURLException {
        try {
            return new URL(string);
        } catch (MalformedURLException x) { return new URL("file:" + string); }
    }

    public static void main(String args[]) throws Exception {

        String jarLocation = "http://www.google.ca/file.jar";
        List<URL> urls = new ArrayList<>();
        URL url = new URL(jarLocation);
        urls.add(getURL(jarLocation));
        JarInputStream jis = new JarInputStream(url.openStream());
        String main = jis.getManifest().getMainAttributes().getValue("Main-Class");
        String classpaths[] = jis.getManifest().getMainAttributes().getValue("Class-Path").split(" ");
        for (String classpath: classpaths) {
            urls.add(getURL(classpath));
        }
        URLClassLoader loader = new URLClassLoader(urls.toArray(new URL[urls.size()]));
        Class<?> cls = loader.loadClass(main);
        Thread.currentThread().setContextClassLoader(loader);
        Method m = cls.getMethod("main", new Class[]{new String[0].getClass()});
        m.invoke(null, new Object[]{args});

    }

}