You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by Brian Toal <br...@gmail.com> on 2017/10/03 07:01:31 UTC

Tomcat 9.0.1 - StandardJarScanner only scanning for HandlesTypes due to classloader issues

In my embedded tomcat app, StandardJarScanner is doing a minimal Servlet
3.0 annotation scanning, specifically only HandlesTypes.  After digging in,
it appears that because the classloader that loaded StandardJarScanner is
the same that loaded StandardContext and ContextConfig
StandardJarScanner.isWebappClassLoader always returns false.   Then
StandardJarScanner.scan will set htOnly to true since fragment.getWebappJar
is false.


           // Only need to scan for @HandlesTypes matches if any of the
            // following are true:
            // - it has already been determined only @HandlesTypes is
required
            //   (e.g. main web.xml has metadata-complete="true"
            // - this fragment is for a container JAR (Servlet 3.1 section
8.1)
            // - this fragment has metadata-complete="true"
            boolean htOnly = handlesTypesOnly || !fragment.getWebappJar() ||
                    fragment.isMetadataComplete();

My embedded app looks as follows:


Tomcat tomcat = new Tomcat();

File docBase = new File(System.getProperty("java.io.tmpdir"));
tomcat.setBaseDir(docBase.getAbsolutePath());

tomcat.setSilent(false);
tomcat.setPort(8080);

// init http connector
tomcat.getConnector();

logger.info("Class loader = " +
Thread.currentThread().getContextClassLoader());

Context ctx = tomcat.addContext("", docBase.getAbsolutePath());
((StandardJarScanner) ctx.getJarScanner()).setScanClassPath(true);
((StandardJarScanner) ctx.getJarScanner()).setScanAllDirectories(true);
((StandardJarScanner) ctx.getJarScanner()).setScanAllFiles(true);

ContextConfig contextConfig = new ContextConfig();
ctx.addLifecycleListener(contextConfig);
contextConfig.setDefaultWebXml(Constants.NoDefaultWebXml);

tomcat.start();
tomcat.getServer().await();
} catch (LifecycleException e) {
throw new RuntimeException("Unable to launch tomcat ", e);
}

What do I need to do, in order to have StandardJarScanner loaded by a
seperate loader than the classes that are loaded when tomcat.start() so
that StandardJarScanner will honor searching for the remaining Servlet 3.0
annotations?