我有以下文件:
src/
|- cltest/
| |- Main.class
| |- Test.class
| `- TestingClassLoader.class
`- data (a class cltest.LoadedClass without an extension)
Main.java:
package cltest;
public class Main {
protected static String field = "TestTestTest";
public static void main(String[] args) throws Exception {
Class.forName("cltest.Test");
Class.forName("cltest.LoadedClass", true, new TestingClassLoader());
}
}
Test.java和/ data
package cltest;
public class Test /* or LoadedClass for /data file */ {
static {
System.out.println(Main.field);
}
}
TestingClassLoader.java
package cltest;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.CodeSource;
import java.security.ProtectionDomain;
public class TestingClassLoader extends ClassLoader {
public Class<?> findClass(String name) throws ClassNotFoundException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = this.getClass().getResourceAsStream("/data");
byte[] buf = new byte[256]; int r;
while ((r = is.read(buf)) != -1) baos.write(buf, 0, r);
byte[] data = baos.toByteArray();
return defineClass(null, data, 0, data.length);
} catch (Exception e) {
throw new ClassNotFoundException(name, e);
}
}
}
此代码在行Class.forName("cltest.LoadedClass", true, new TestingClassLoader());
上给出了错误:
TestTestTest // (output of 1st Class.forName() call)
Exception in thread "main" java.lang.IllegalAccessError: tried to access field cltest.Main.field from class cltest.LoadedClass
at cltest.LoadedClass.<clinit>(LoadedClass.java:5)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Unknown Source)
at cltest.Main.main(Main.java:7)
我该如何解决?
答案 0 :(得分:2)
实现此功能的唯一方法是将LoadedClass和Main放在同一个类加载器中(如果类具有相同的包名和类加载器,则它们只在同一个包中。)
你正在谈论一个&#34;插件&#34;需要访问main的受保护方法。这是一个插件系统的糟糕设计。如果您控制这些类,则将必要的方法设为public而不是protected。