【问题标题】:java.lang.ClassCastException when using custom classloader使用自定义类加载器时出现 java.lang.ClassCastException
【发布时间】: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


【解决方案1】:

是的,DynamicClassLoader 需要委托给加载 MyInterface 的 ClassLoader。

new DynamicClassLoader(MyInterface.class.getClassLoader()) 应该没问题。

【讨论】:

猜你喜欢
  • 2013-02-27
  • 2017-09-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多