【发布时间】:2015-04-26 10:52:45
【问题描述】:
我在 OpenJDK 和 Oracle JDK 上测试了三台 Windows 机器和两台 linux VPS,在不同版本的 Java 上。它运行良好,然后突然之间,它只在我的 IDE 中运行,虽然我没有更改任何相关代码,我无法想象是什么原因造成的。
系统流行代码:
Class<?> cls = (session == null ? secjlcl : session.getJLCL()).loadClass(name);
Logger.log(JavaLoader.class.isAssignableFrom(cls) + " - " + cls + " - " + cls.getSuperclass().getName());
if (JavaLoader.class.isAssignableFrom(cls)) {
还有我的 ClassLoader:
public class JavaLoaderClassLoader extends URLClassLoader {
public JavaLoaderClassLoader(URL[] url, ClassLoader parent) {
super(url);
}
private HashMap<String, Class<?>> javaLoaders = new HashMap<String, Class<?>>();
public String addClass(byte[] data) throws LinkageError {
Class<?> cls = defineClass(null, data, 0, data.length);
javaLoaders.put(cls.getName(), cls);
return cls.getName();
}
public Class<?> loadClass(String name, boolean resolve) {
if (javaLoaders.containsKey(name)) return javaLoaders.get(name);
try {
Class<?> see = super.loadClass(name, resolve);
if (see != null) return see;
}catch (ClassNotFoundException e) {
Logger.logError(e);
}
return null;
}
public void finalize() throws Throwable {
super.finalize();
javaLoaders = null;
}
}
请注意,我希望许多类加载器会以相同的名称/包加载不同的文件,因此我使用单独的类加载器将它们分开,但是在测试中,这没有经过测试。
现在,这在过去完美无缺,我零知道它为什么停止了。我会假设我破坏了某些东西,但代码仍然可以在我的 IDE 中运行?
【问题讨论】:
-
你有多个类加载器。
System.out.println(cls.getClassLoader()+" "+JavaLoader.class.getClassLoader());打印什么 - 两个不同的东西,还是同样的东西两次? -
@immibis 在非IDE环境中,我加载的一个是我自定义的ClassLoader,一个是标准的URLClassLoader。但是,在我的 IDE 中,它使用来自 sun.misc.Launcher 的 AppClassLoader。这似乎表明了问题,我可以使用我的父类加载器,或者用我的类加载器加载我的 JavaLoader 类。我会调查的。
-
您是否正在运行一个包含其他 JAR 的 JAR?例如,在 Eclipse 中,您导出一个可运行的 JAR 并选择“将所需的库打包到生成的 JAR 中”?如果是这样,那么查看 Eclipse 的 JAR-in-JAR 类加载器,它设置了自己的默认 StreamHandlerFactory。另一个问题可能是搜索类的顺序。
-
您是否在某个托管环境中运行(例如 Servlet 容器,或者可能是某个 EJB 容器)?
标签: java linux class unix classloader