#java #classloader
#java #classloader
Вопрос:
Итак, я пытаюсь загрузить файл по ссылке и запустить его в памяти. Все работает, работает нормально, но только тогда, когда файл .jar находится в classpath проекта. Мой код выглядит следующим образом:
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 будет запускаться, только если она находится в classpath проекта. Как я могу загрузить файл по ссылке, а не из наличия его в classpath?
Ответ №1:
Это потому, что вы не передаете свои URL-адреса .jar в URLClassLoader. В вашем коде он принимает пустой массив, поэтому я не знаю, как загружать классы из вашего jar-файла.
Вот пример того, как вы можете изменить свой код, чтобы передавать URL-адреса 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});
}
}