Java gson.JsonObject和类加载创建了非常奇怪的情况

Java gson.JsonObject和类加载创建了非常奇怪的情况,java,maven,gson,code-injection,websphere-liberty,Java,Maven,Gson,Code Injection,Websphere Liberty,我有一些maven项目,其依赖关系可追溯到: <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.1</version> </dependency> 我有一个奇怪的例外,比如: "Caused by

我有一些maven项目,其依赖关系可追溯到:

    <dependency>
        <groupId>com.google.code.gson</groupId>
        <artifactId>gson</artifactId>
        <version>2.8.1</version>
    </dependency>
我有一个奇怪的例外,比如:

"Caused by: java.lang.ClassCastException: com.google.gson.JsonObject cannot be cast to com.google.gson.JsonObject"
我不明白为什么从共享库目录中的gson-2.8.1.jar文件加载的同一个JsonObject类与war文件中可能从gson-2.8.1.jar加载的JsonObject类不兼容。他们有相同的大小等,是同一类。。。因为它们都来自同一个gson-2.8.1.jar文件

我试图隔离这些类,以便只调用共享库目录中的一个jar文件(例如,将其从war文件中删除)。但是,在某些情况下,在尝试动态加载类时,我会创建一个类not found异常


我意识到我的描述很难理解。从这个jar加载的JsonObject会导致Java认为它有两个不兼容的类,这是因为当加载的是同一个对象时,它们可能是由不同的类加载器加载的吗?

您观察到的是预期的类加载行为。如果从两个不同的源加载相同的
Foo
类,则从JVM的角度来看,这是两个不同的类,因此不能相互转换(即
Foo不能转换为Foo
)。同样,如果您从两个不同的类加载器加载了相同的类
Foo
,那么这些类也不能相互转换

要解决此问题,只需删除其中一个副本。由于您已经完成了设置共享库的工作(这是首选方法),只需将maven依赖项的范围更改为`提供',即可从您的apps WEB-INF/lib dir中删除gson jar

例如:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.1</version>
    <scope>provided</scope>
</dependency>

com.google.code.gson
格森
2.8.1
假如

这告诉maven在编译时包含此依赖项,但不要在运行时包含(因为我们知道它将由共享库提供)。

感谢您的详细解释。这完全有道理。我推送并回滚了更改,只在OpenWhisk所需的方法中添加了JsonObject,并从此转换为JsonObject,以减少对JsonObject的依赖,使其只依赖于从共享库目录加载gson-2.8.1.jar的一个类。但我可能会尝试重新使用以前的代码,看看这是否有效。我认为我将jar从war文件中移出的方法是等效的。它不太可能工作,因为jar是为战争而加载的,并且是由注入的类加载的,所以=类加载器
<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.8.1</version>
    <scope>provided</scope>
</dependency>