【发布时间】:2017-01-17 07:54:50
【问题描述】:
我需要在运行时动态加载一个 java 类。为此,我使用https://github.com/trung/InMemoryJavaCompiler。
我需要加载的类实现了一个接口,该接口已经是我的应用程序的一部分(因此该接口由系统类加载器加载)。类加载完成后,我将其强制转换为接口。
更新:抱歉,我对 docker 的看法是错误的。这当然与 docker 无关,但事实上我是通过命令行启动应用程序的:java -jar ...。当应用程序从 intellij 启动时,它可以工作。当它通过命令行启动时,当我尝试投射时抛出 java.lang.ClassCastException。
真实接口的类加载器是org.springframework.boot.loader.LaunchedURLClass Loader@2a84aee7,而动态加载接口的类加载器是sun.misc.Launcher$AppClassLoader@55f96302。感谢您帮助我找出问题。
我可以做些什么来确保使用相同的类加载器?
总是将自定义类加载器设为接口类加载器的子类是否是个好主意:new DynamicClassLoader(MyInterface.class.getClassLoader())?
【问题讨论】:
-
检查
generatedInstance.getClass().getInterfaces()是否包含YourInterface以及这些接口的类加载器是否等于YourInterface.class.getClassLoader()。 -
@apangin 是对的。首先检查类和接口是否由同一个类加载器加载。 :)
-
Docker 不应该改变 JVM 加载类的方式。
-
感谢大家的反馈。我更新了问题。真实接口的类加载器是
org.springframework.boot.loader.LaunchedURLClass Loader@2a84aee7,而动态加载的接口的类加载器是sun.misc.Launcher$AppClassLoader@55f96302。感谢您帮助我找出问题所在。我怎样才能确保使用相同的类加载器?
标签: java jvm classloader