【问题标题】:Java Class.isAssignableFrom ALWAYS returning false... only outside IDEJava Class.isAssignableFrom 总是返回 false... 仅在 IDE 之外
【发布时间】: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


【解决方案1】:

这似乎是你的错误:

public JavaLoaderClassLoader(URL[] url, ClassLoader parent) {
    super(url);
}

您没有通过超级构造函数将parent 安装为父类加载器。

【讨论】:

    猜你喜欢
    • 2015-09-14
    • 2017-04-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2015-08-08
    • 1970-01-01
    相关资源
    最近更新 更多