Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to solve the conflict between Java class loader and class

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly introduces the Java class loader and class conflict resolution related knowledge, the content is detailed and easy to understand, the operation is simple and fast, has a certain reference value, I believe you will have something to gain after reading this Java class loader and class conflict resolution article, let's take a look.

Two different versions of a class library are included in the same project

At this time, you may encounter strange problems.

The logic of the code is not as expected.

NoSuchMethodError appears

...

In conclusion, there is no doubt that the current version of class is not consistent with what you expected.

Here we use apache's commons-codec class library to analyze the problem scenario.

When implementing a function, you introduce the dependency of the library through maven:

Commons-codec

Commons-codec

1.10

At this point, a class in the class library that handles Base64 is used in the code, and there is such an implementation

Public static byte [] decodeBase64 (String base64String) {

Return (new Base64 ()) .decode (base64String)

}

Then it wasn't long before other functions were added to the system and a dependency was introduced when it was docked with other systems. When we happily complete the task and submit the code, one day we will encounter a problem raised by QA, and the XX feature is not available now.

What's going on, WTF?

Then rerun the function, and sure enough. What happened. It turns out that the commons-codec-1.10 version we used before was not used, but the com.springsource.org.apache.commons.codec-1.3.0 version was used.

What happened?

When we access other systems, we introduce some dependencies, of which he relies on a

Org.apache.commons

Com.springsource.org.apache.commons.httpclient

And he will bring in the com.springsource.org.apache.commons.codec-1.3.0 above.

At this point, there will be two packages about commons-codec in the system.

However, the old version of the corresponding Base64 class only supports passing an array, not String.

Is Maven so stupid that he can't solve it?

He will choose whether to use it based on the order before and after the dependency declaration or the nearest based on the introduced version and the version of maven used. But this does not solve our above problem, because maven will use the above dependency mechanism for the same groupId and artifactId, so the same groupId and artifactId dependencies will be directly ignored and end up using only one. You can see it on the dependency tree:

Look at the hint above, omitted for duplicate. The above dependence on codec is because artifactId has been replaced with org.springsource.org.apache.commons, so that the mechanism of maven will not work, resulting in two jar of codec in the project. Moreover, although codec.jar is specified for org.springsource, although artifactId is this, the package name in it is still the same as org.apache.commons, so it is the same as two identical Jar, but with different versions.

At this time, it's time for the classloader to play. When the class loader loads the class and initializes it, it needs to load the class that the current class depends on. At this time, the class that depends on the lower version of codec is loaded first, which leads to the loading of the lower version of codec.

When classes are needed later where codec is needed, although WebappClassloader can be loaded with sub-priority to isolate resources for different applications, classes with the same package in the same application will not be loaded repeatedly. At this point, when the same request comes, an earlier version of codec is found in the loaded resources, and it is used directly, and there is no method in this class that we want to call, so the familiar NoSuchMethodError appears.

Solve

The problem is clear, so how to solve it? when introducing a dependency, you can't check the pom statement of jar one by one.

When the above problems occur, if you do not use maven to manage dependencies, like before SSH, when you add a bunch of jar to the lib directory at once, after you have identified the corresponding problem jar, just delete it directly.

If you are using maven to manage dependencies, you need to know that you brought this kid here. At this point, use maven's command tool:

Mvn dependency:tree

Then generate the results into a file, you can see who brought in the jar that introduced the conflict, and after finding out the truth, you can rule out the dependency.

Something like this:

Com.xxx

Xxx

1.0.4

Org.apache.commons

Com.springsource.org.apache.commons.codec

This is the end of the article on "how to resolve conflicts between Java class loaders and classes". Thank you for reading! I believe you all have a certain understanding of the knowledge of "how to resolve the conflict between Java class loaders and classes". If you want to learn more, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report