Java 类加载器仅从类路径而不是url工作

Java 类加载器仅从类路径而不是url工作,java,classloader,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 { publi

所以我试图从一个链接加载一个文件并在内存中运行它。一切正常,但只有当.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});

    }

}
import java.lang.reflect.Method;
导入java.net.MalformedURLException;
导入java.net.URL;
导入java.net.URLClassLoader;
导入java.util.jar.JarInputStream;
公共班机{
公共静态URL getURL(字符串字符串)引发错误的URL异常{
试一试{
返回新的URL(字符串);
}catch(MalformedURLException x){返回新URL(“文件:+字符串);}
}
公共静态void main(字符串args[])引发异常{
字符串位置=”http://www.google.ca/file.jar";
URL=新的URL(地址);
getURL(jarLocation);
JarInputStream jis=新的JarInputStream(url.openStream());
字符串main=jis.getManifest().getMainAttributes().getValue(“主类”);
字符串类路径[]=jis.getManifest().getMainAttributes().getValue(“类路径”).split(“”);
for(字符串类路径:类路径){
getURL(类路径);
}
URLClassLoader=新URLClassLoader((新URL[0]);
Class cls=装入器。装入器类(主);
Thread.currentThread().setContextClassLoader(加载器);
方法m=cls.getMethod(“main”,新类[]{newstring[0].getClass()});
m、 调用(null,新对象[]{args});
}
}
问题是,无论链接是什么,.jar都只会在项目的类路径中运行如何从链接加载文件而不是从类路径加载文件?

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

下面是一个示例,说明如何修改代码以将jar URL传递给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});

    }

}
公共类主{
公共静态URL getURL(字符串字符串)引发错误的URL异常{
试一试{
返回新的URL(字符串);
}catch(MalformedURLException x){返回新URL(“文件:+字符串);}
}
公共静态void main(字符串args[])引发异常{
字符串位置=”http://www.google.ca/file.jar";
列表URL=新的ArrayList();
URL=新的URL(地址);
add(getURL(jarLocation));
JarInputStream jis=新的JarInputStream(url.openStream());
字符串main=jis.getManifest().getMainAttributes().getValue(“主类”);
字符串类路径[]=jis.getManifest().getMainAttributes().getValue(“类路径”).split(“”);
for(字符串类路径:类路径){
add(getURL(classpath));
}
URLClassLoader=新URLClassLoader(URL.toArray(新URL[URL.size()]);
Class cls=装入器。装入器类(主);
Thread.currentThread().setContextClassLoader(加载器);
方法m=cls.getMethod(“main”,新类[]{newstring[0].getClass()});
m、 调用(null,新对象[]{args});
}
}