我想在我的java程序运行时从jar加载一些类文件。在Java 8之前,我使用以下代码来做到这一点:
public class MiKoLoader {
public void loadJar(File jarfile)
{
try {
URL url = jarfile.toURI().toURL();
URLClassLoader uc = (URLClassLoader) ClassLoader.getSystemClassLoader();
Method m = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
m.setAccessible(true);
m.invoke(uc, url);
} catch (MalformedURLException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Object findObject(String klasse)
{
Class<?> c;
try {
c = Class.forName(klasse);
return c.newInstance();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
public void methodeAufObjektAnwenden(String methodenname, String klasse, Object o, Object...params)
{
Class<?>[] klassen = null;
if (params!=null)
{
klassen = new Class<?>[params.length];
for (int i=0; i<params.length; i++)
{
klassen[i]=params[i].getClass();
}
}
try {
Method m = Class.forName(klasse).getMethod(methodenname, klassen);
m.invoke(o, params);
} catch (NoSuchMethodException | SecurityException | ClassNotFoundException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
我有一个jar文件,其中包含“ Auto”类和一个starter类,该类进行了一些测试。
MiKoLoader m = new MiKoLoader();
m.loadJar(jar);
Object auto = m.findObject("Auto");
m.methodeAufObjektAnwenden("fahren", "Auto", auto, null);
m.methodeAufObjektAnwenden("fahren", "Auto", auto, new String("blau"));
在Java 9及更高版本中,我不得不将loadJar方法更改为
public void loadJar(File jarfile)
{
try {
URL url = jarfile.toURI().toURL();
URLClassLoader uc = new URLClassLoader(new URL[0]);
Method sysMethod = URLClassLoader.class.getDeclaredMethod("addURL", new Class[]{URL.class});
sysMethod.setAccessible(true);
sysMethod.invoke(uc, new Object[]{url});
} catch (MalformedURLException | NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
如果我尝试运行新代码,则会收到以下警告和异常:
警告:发生了非法的反射访问操作警告: MiKoLoader的非法反射访问 (文件:/ home / mk / nas / home / workspace%20rt / asvspace / MiKoLoader / bin /)到 方法java.net.URLClassLoader.addURL(java.net.URL)警告:请 考虑将其报告给MiKoLoader的维护人员警告:使用 --illegal-access =警告启用进一步的非法反射访问操作的警告警告:所有非法访问操作都将 在以后的版本中被拒绝
java.lang.ClassNotFoundException:自动在 java.base / jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:583) 在 java.base / jdk.internal.loader.ClassLoaders $ AppClassLoader.loadClass(ClassLoaders.java:178) 在java.base / java.lang.ClassLoader.loadClass(ClassLoader.java:521) 在java.base / java.lang.Class.forName0(本机方法)处 java.base / java.lang.Class.forName(Class.java:315)在 MiKoLoader.findObject(MiKoLoader.java:43)在 Starter.main(Starter.java:9)上的Starter.work(Starter.java:16)
我真的不明白,为什么我的班级找不到了。