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… 🙂