[英]gson.JsonObject and class loading creating very odd situations
我有一些依赖的maven项目回到:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.1</version>
</dependency>
导致下载单个gson-2.8.1.jar文件。 我使用“clean package”maven构建检索此文件的副本,因此我可以为我的Web应用程序动态加载的类使用的共享库引用单个目录。
由于war文件构建策略(使用“clean install deploy”maven build),war文件也在其WEB-INF / lib目录中获取gson-2.8.1.jar文件的副本。 据我所知,这些都来自同一个jar文件。
但是,在运行Web应用程序并使用如下调用时:
JsonObject retVal = null;
try {
paramData.add(0, userID);
paramData.add(0, session);
retVal = (JsonObject) method.invoke(null,
paramData.toArray(new Object[0]));
} catch (Exception e) {
我得到一个奇怪的例外:
"Caused by: java.lang.ClassCastException: com.google.gson.JsonObject cannot be cast to com.google.gson.JsonObject"
我不明白为什么从共享库目录中的gson-2.8.1.jar文件加载的相同JsonObject类与可能从战争中的gson-2.8.1.jar加载的JsonObject类不兼容文件。 它们具有相同的大小等,并且是同一类...因为它们都来自相同的gson-2.8.1.jar文件...
我试图隔离这些类,因此只调用共享库目录中的一个jar文件(例如,将其从war文件中删除)。 但是,在某些情况下,我会在尝试动态加载类时创建一个未找到类的类。
我意识到我的描述很难理解。 是否有一些原因从这个jar加载的JsonObject会导致Java认为它有两个不兼容的类,因为它们可能已被不同的类加载器加载时加载的是同一个对象?
您正在观察的是预期的类加载行为。 如果从两个不同的源加载相同的Foo
类,从JVM的角度来看,这是两个不同的类,因此不能相互转换(即Foo cannot be cast to Foo
)。 同样,如果您从两个不同的类加载器加载了相同的类Foo
,则这些类也不能相互转换。
要解决此问题,只需删除其中一个副本即可。 由于您已经完成了设置共享库(这是首选方法)的工作,只需通过将maven依赖项的范围更改为“提供”,从应用程序WEB-INF / lib目录中删除gson jar。
例如:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.1</version>
<scope>provided</scope>
</dependency>
这告诉maven在编译时包含这个依赖项,但不是在运行时(因为我们知道它将由共享库提供)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.