Caused by: java.lang.NoSuchMethodError: org.apache.xml.serializer.Encodings.isRecognizedEncoding(Ljava/lang/String;)Z at org.apache.xml.serializer.dom3.LSSerializerImpl.write(LSSerializerImpl.java:926) at ...
If you’ved ever had the unpleasant task of figuring out which of the 200+ JAR dependencies in your project that are causing the a NoSuchMethodError (usually in some XML or webservice code), then this is the trick for you:
Consider the following POM (distilled from a real-world scenario):
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>net.bystrup</groupId> <artifactId>nsm-example</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>xalan</groupId> <artifactId>xalan</artifactId> <version>2.7.0</version> </dependency> <dependency> <groupId>xalan</groupId> <artifactId>serializer</artifactId> <version>2.7.1</version> </dependency> </dependencies> </project>
When parsing an XML document, the error at the top of the post might occur… You know the symptom, you know the probable root cause – but how do you find the conflicting JARs?
ClassLoader.getResources() to the rescue! The following snippet will list all resources/JARs containing the clas with the missing method:
import java.net.URL; import java.util.Enumeration; public class Main { /** * The project depends on both xalan:2.7.0 and serializer:2.7.1 which both * contain the org.apache.xml.serializer.Encodings class, albeit with different * signatures... * * @param argv */ public static void main( String argv[] ) throws Exception { Enumeration<URL> res = new Main().getClass().getClassLoader().getResources( "org/apache/xml/serializer/Encodings.class" ); while ( res.hasMoreElements() ) { URL url = res.nextElement(); System.out.println( url.toExternalForm() ); } } }
The operative piece of code
this.getClass().getClassLoader().getResources( "org/apache/xml/serializer/Encodings.class" )
might even be evaluated in eg. IDEAs “Evaluate Expression” window (Alt-F8) if you’re in a debugging situation.
The only problem remaining is: How does one remember where to find this guide next time the problem occurs… 🙂