Today, after sorting out the pom.xml file of maven, we integrated multiple projects with Maven. As a result, when we started tomcat, we encountered a wonderful error:
when we started Tomcat
Warning: Servlet[spring]inwebapplication[/AbcWeb]threwload()exception
java.lang.IncompatibleClassChangeError:classorg.springframework.core.type.classreading.ClassMetadataReadingVisitorhasinterfaceorg.springframework.asm.ClassVisitorassuperclass
atjava.lang.ClassLoader.defineClass1(NativeMethod)
atjava.lang.ClassLoader.defineClass(ClassLoader.java:800)
atjava.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
atorg.apache.catalina.loader.WebappClassLoaderBase.findClassInternal(WebappClassLoaderBase.java:2495)
atorg.apache.catalina.loader.WebappClassLoaderBase.findClass(WebappClassLoaderBase.java:859)
atorg.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1301)
atorg.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1166)
atjava.lang.ClassLoader.defineClass1(NativeMethod)
Restart Tomcat, Project>Clean are played all over, but did not find where the problem is. So Google it, the results from this page found this paragraph:
Your newly packaged libraryis not backward binary compatible(BC) with old version. For this reason some of the library clients that are not recompiled may throw the exception.
This is acompletelist of changes in Java library API that may cause clients built with an old version of the library to throw java.lang.IncompatibleClassChangeErrorif they run on a new one (i.e. breaking BC):
Non-final field become static,
Non-constant field become non-static,
Class become interface,
Interface become class,
if you add a new field to class/interface (or add new super-class/super-interface) then a static field from a super-interface of a client class C may hide an added field (with the same name) inherited from the super-class of C (very rare case).
In fact, a closer look reveals that the error description is actually quite clear:
java.lang.IncompatibleClassChangeError:classorg.springframework.core.type.classreading.ClassMetadataReadingVisitorhasinterfaceorg.springframework.asm.ClassVisitorassuperclass
That is to say, has a class called classmetadatareadingvisitor, which takes an interface called classvisitor as its parent class . But we all know that the relationship between class and interface in java can only be realized, not inherited . So why is this class?I try to open this error reporting class in Eclipse:
As you can see, two versions of classmetadatareadingvisitor classes (3.2.6 and 4.0.0) can be found in my workspace. Open these two classes respectively (Maven will download the source code automatically). You can see that the class declaration is:
classClassMetadataReadingVisitorextendsClassVisitorimplementsClassMetadata
So I opened the classvisitor class mentioned in the error description, and the result is as follows:
As you can see, eclipse found three such classes in workspace, and the package name and class name are all exactly the same. As you can see, in version 3.1.4 of spring, this class called classvisitor is actually an interface, which is placed in the spring ASM module. In versions 3.2.6 and 4.0.0, the classvisitor becomes an abstract class
After finding this difference, I checked the version of my spring core module:
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.6</version>
</dependency>
But at the same time, there is a dependency of such a package in my pom.xml
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-asm</artifactId>
<version>3.1.4.RELEASE</version>
</dependency>
It happens that the 3.1.4 interface is in workspace, so the classvisitor is included in both packages. After deleting the spring ASM module, the error disappears and the problem is solved
The spring ASM package doesn’t know when it was imported, which tells us:
when using Maven to process dependent packages, you must not arbitrarily add dependencies. Only used packages are imported, and statements that do not use packages should be deleted in time
when integrating multiple Maven projects, you should pay attention to the version of the dependency package, because some classes (fields that may be included in the package) may have different declarations in different versions, and wrong class or field declarations will lead to incompatible classchangeerror
Similar Posts:
- Springboot startup error start bean ‘eurekaautoserviceregistration’ NullPointerException
- Springboot always reports an error when importing JSP dependencies
- [Solved] SpringBoot1.5.10 Project Start Error: Exception in thread “main” java.lang.ClassCastException: class …
- Unregistering JMX-exposed beans on shutdown Solution
- Eureka server project startup error handling
- [Solved] java.lang.NoSuchMethodError: javax.persistence.spi.PersistenceUni
- Property ‘dataSource’ threw exception; nested exception is java.lang.NoClassDefFoundError: org/springframework/jdbc/datasource/TransactionAwareDataSourceProxy
- [How to Solve] RestController cannot be recognized in spring boot
- Factory method ‘eurekaClient’ threw exception; nested exception is java.lang.RuntimeException: Failed to initialize DiscoveryClient!
- [Solved] Jsonobject has no from object, idea has no Maven dependency, jsonobject Maven dependency package