Search code examples
javatomcatjakarta-eecxfjava-11

A lot of InvocationTargetException after starting tomcat


When I start tomcat with my apps I see a lot of:

02-Aug-2021 16:49:24.011 WARNING [main] org.apache.tomcat.util.scan.StandardJarScanner.processURLs Failed to scan [file:/opt/tomcat/apache-tomcat-9.0.50/lib/jakarta.annotation-api.jar] from classloader >
        java.io.IOException: java.lang.reflect.InvocationTargetException
                at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:209)
Caused by: java.lang.reflect.InvocationTargetException
                at java.base/jdk.internal.reflect.GeneratedConstructorAccessor7.newInstance(Unknown Source)
                at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
                at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
                at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:206)
                ... 51 more
        Caused by: java.nio.file.NoSuchFileException: /opt/tomcat/apache-tomcat-9.0.50/lib/jakarta.annotation-api.jar
                at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)

WARNING: Failed to scan [file:/opt/tomcat/apache-tomcat-9.0.50/lib/woodstox-core.jar] from classloader hierarchy
java.io.IOException: java.lang.reflect.InvocationTargetException
Caused by: java.lang.reflect.InvocationTargetException
        at java.base/jdk.internal.reflect.GeneratedConstructorAccessor7.newInstance(Unknown Source)
        at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
        at org.apache.tomcat.util.compat.Jre9Compat.jarFileNewInstance(Jre9Compat.java:206)
        ... 49 more
Caused by: java.nio.file.NoSuchFileException: /opt/tomcat/apache-tomcat-9.0.50/lib/woodstox-core.jar
        at java.base/sun.nio.fs.UnixException.translateToIOException(UnixException.java:92)

and many, many more. In /opt/tomcat/apache-tomcat-9.0.50/lib I have jars but instead of jakarta.annotation-api.jar there is -rwxr-x--- 1 root root 25K sie 2 16:49 jakarta.annotation-api-1.3.5.jar. I think that's the problem - it's looking for jars without versions, but I have no idea why. How to force tomcat to take proper jars?


Solution

  • Check the *.loader properties in catalina.properties to see if you didn't hardcode those URLs. By default only the common.loader property is set to a non-empty value:

    common.loader="${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"
    

    Another source for these messages might be the manifest scanning feature (cf. source code), which also scans JAR files in the same folder mentioned in another JAR file's manifest. To check if this is the case run:

    for jar in /opt/tomcat/apache-tomcat-9.0.50/lib/*.jar; do
        unzip -p "$jar" META-INF/MANIFEST.MF | grep '^Class-Path';
    done
    

    To solve the problem you can disable manifest scanning completely, by adding to $CATALINA_BASE/conf/context.xml:

    <Context>
      ...
      <JarScanner scanManifest="false"/>
      ...
    </Context>
    

    (cf. Tomcat's documentation)

    Remark: Unless you are running Tomcat as root, your permissions prevent any other user from reading those JAR files. You should at least add read (r) permission to the user running Tomcat.