Issue
I face a so strange problem that occurs below on the remote tomcat server but works well on the local.
org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.NoSuchMethodError: org.apache.doris.analysis.SqlParser.getSymbolFactory()Ljava_cup/runtime/SymbolFactory;
I know most related topics about this issue are package duplicate、dependency conflict、 etc. But actually, I've tried to eliminate these factors. The war is identical on both local and remote. I also decompile the jar which includes SqlParser class, and It's truly existed and includes the getSymbolFactory function.
The most strange thing is when I copy that to local for running it's ok. At first, I suspected it was about the version of tomcat. But after using the same version of the Tomcat on the remote, the error still exists.
By the way, the jar includes warning class that is imported by the system jar type. The jars are placed the resource/lib/* . It's related to this?
Maven config for import system jar
<dependency>
<groupId>net.sourceforge.czt.dev</groupId>
<artifactId>java-cup</artifactId>
<version>0.11-a-czt02-cdh</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/java-cup-runtime-0.11-a-czt01-cdh.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.doris</groupId>
<artifactId>fe-core</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/fe-core-1.0-SNAPSHOT.jar</systemPath>
</dependency>
<dependency>
<groupId>org.apache.doris</groupId>
<artifactId>fe-common</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>system</scope>
<systemPath>${basedir}/src/main/resources/lib/fe-common-1.0-SNAPSHOT.jar</systemPath>
</dependency>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>ftl</nonFilteredFileExtension>
</nonFilteredFileExtensions>
<outputDirectory>target</outputDirectory>
<webResources>
<resource>
<filtering>true</filtering>
<directory>src/main/webapp/WEB-INF</directory>
<includes>
<include>**/*.xml</include>
</includes>
<targetPath>/WEB-INF</targetPath>
</resource>
<resource>
<directory>src/main/resources/lib</directory>
<targetPath>WEB-INF/lib</targetPath>
</resource>
</webResources>
</configuration>
</plugin>
For now, the most relevant thread I found is this: java.lang.NoSuchMethodError when the method definitely exists I have no clue how to troubleshoot this, anyone can help me?
Solution
I am back and solved it. That was very careless of me. The root cause indeed is getSymbolFactory method loaded from another jar, I'm only verified SqlParser class, and missing verifiy the getSymbolFactory method which is inherited from the parent class java_cup.runtime.lr_parser. The key is this class loaded from another jar and I didn't notice.
Why it works well on the local machine is the method is loaded from the correct jar. I am using tomcat 8, and I've searched for the loading mechanism of tomcat. It turns out the loading order of tomcat 8 is not guaranteed. Here, even though this is a basic issue, I want to summarize the things when I troubleshoot.
- Open the loading jar log and look over Catalina.out
Configure Tomcat to Log all Jar Files and/or Classes Loaded at Startup
I using this
-XX:+TraceClassLoading
- find the jar that contains the specified class or method
grep "xxx" web-inf/lib/jars
- check the signature of the class
javap -classpath jar com.xxx.xxx
- some tomcat loading relate posts
Order of loading jar files from lib directory
https://tomcat.apache.org/tomcat-8.0-doc/class-loader-howto.html
how tomcat will load the class if duplicate classes exist with same package structure
hope these can help other people.
Answered By - Yang Xu
Answer Checked By - David Marino (JavaFixing Volunteer)