// // UPDATE
现在我可以加载一个Jar,但是如何从中运行方法呢?
答案 0 :(得分:1)
这有两个部分。首先,您需要导入jar。这可以在运行时使用轻微的hack with reflection:
完成import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
public void importJar(File file) {
Method addURL = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addURL.setAccessible(True);
addURL.invoke(URLClassLoader.getSystemClassLoader(), new Object[] {file.toURI().toURL()});
}
现在您可以在运行时导入jar。如果您只是拥有jar的路径,则可以轻松将其转换为File
:
importJar(new File("path/to/jar"));
其次,您需要找到jar中定义的类。似乎没有内置的方法来执行此操作,因此您必须手动检查jar本身的类。
import java.lang.Class;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.jar.JarFile;
import java.util.jar.JarEntry;
public List<Class<?>> findJarClasses(File file) {
ArrayList<Class<?>> classes = new ArrayList<Class<?>>();
JarFile jar = new JarFile(file);
Enumeration<JarEntry> entries = jar.entries();
while (entries.hasMoreElements()) {
JarEntry entry = entries.nextElement();
String name = entry.getName();
if (name.endsWith(".class")) {
name = name.substring(0, name.lastIndexOf('.'));
Class<?> cls = Class.forName(name);
classes.add(cls);
}
}
return classes;
}
最后,您可以迭代这些类,以确定它们中是否有任何一个实现了您想要的界面。
File jarFile = new File("path/to/Games.jar");
importJar(jarFile);
List<Class<?>> classes = findJarClasses(jarFile);
for (Class<?> cls : classes) {
if (cls.isInstance(YourInterface.class)) {
// Instantiate class.
YearInterface obj = (YourInterface)cls.newInstance();
// Call `loaded()` method.
obj.loaded();
}
}
答案 1 :(得分:0)
答案 2 :(得分:0)
从您需要插入games.jar
的主JAR文件:
games.jar
文件的网址(使用File.toURI().toURL()
)并将其放入数组中(让我们调用数组urlArray
)。接下来获取URLClassLoader
个实例以加载games.jar
:
URLClassLoader urlClassLoader = URLClassLoader.newInstance(urlArray);
现在,如果您将刚刚创建的新类加载器作为第三个参数传递,则可以使用games.jar
从Class.forName
实例化任何类:
Class<? extends Main> mainClass = (Class<? extends Main>)
Class.forName("Main", true, urlClassLoader);
在mainClass
,您现在可以调用您的方法:mainClass.loaded();