7

We recently migrated to Servlet API 3.0. Since we are developing a framework which sometimes needs a few changes in the web.xml, projects which are based on our framework need to update their web.xml whenever a change in the framework is made.

Servlet API 3.0 introduces the new Web Fragments, which make this behaviour more loosely coupled and dynamic. I create a web-fragment.xml and move all our stuff from the web.xml in there. So the projects now have only to define the following web.xml and their own additional declarations.

<?xml version="1.0" encoding="UTF-8"?>
<web-app 
   version="3.0"
   metadata-complete="false"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
        http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
</web-app>

We have to use metadata-complete="false" to enable the Fragment search in JARs (our framework has the web-fragment.xml in META-INF/.

Since we have many dependencies to other frameworks and libraries (about 80-90) and the metadata-complete="false" also triggers searching for Annotations it takes up to unacceptable 12 seconds to search through all libraries.

The mechanism as it is works great and I like the fact that we are more decoupled from our framework, but the startup time is fatal! Also we have to increase the available memory for Tomcat from -Xms256m -Xmx512m to -Xms512m -Xmx1024m to get it started without getting a java.lang.OutOfMemoryError: Java heap space (caused by the inefficiently implemented annotation processor of the Tomcat (about 50.000 classes are cached)).


I know that we can disable the annotation search within a library, but as we use mostly third-party which don't have the metadata-complete="true" flag, this also isn't an option.

Can we do anything to disable the search for annotations? Or can we force the Servlet Container to only search in declared libraries for the web-fragment.xml?

I would really like to use the new web fragment feature, but with the increased startup time and memory this isn't possible.

Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
Christopher Klewes
  • 11,181
  • 18
  • 74
  • 102

2 Answers2

3

You can disable annotation processing by configuration for certain JAR files. I used it for JAR files only, it may not work for exploded WARs. Look at <tomcat>/conf/catalina.properties, line 76 (Tomcat 7.0.22):

# List of JAR files that should not be scanned for configuration information
# such as web fragments, TLD files etc. It must be a comma separated list of
# JAR file names.
# The JARs listed below include:
# - Tomcat Bootstrap JARs
# - Tomcat API JARs
# - Catalina JARs
# - Jasper JARs
# - Tomcat JARs
# - Common non-Tomcat JARs
# - Sun JDK JARs
# - Apple JDK JARs
home
  • 12,468
  • 5
  • 46
  • 54
  • This is indeed a solution, thank you! Unfortunately this would be a servlet container dependent solution. We target to run on every servlet container, so this solution isn't a good choice for us. – Christopher Klewes Mar 09 '12 at 10:04
  • @codevour How have you solved your problem in the meantime? – phant0m Jul 11 '17 at 07:26
0

There are some system properties in Tomcat that enable controlling JAR scanning since 7.0.30. Check the doc page here.

Basically these ones are:

  • tomcat.util.scan.DefaultJarScanner.jarsToSkip
  • org.apache.catalina.startup.ContextConfig.jarsToSkip
  • org.apache.catalina.startup.TldConfig.jarsToSkip

Not sure what is the earliest time you may set them, maybe ContextListener?

Rade_303
  • 905
  • 11
  • 28