2

I fail to understand why in the following minimal project my implementation of Spring's WebApplicationInitializer interface is found when running tests within Eclipse and IntelliJ, but not when using Maven (mvn clean test).

With Eclipse and IntellIJ I see INFO: Spring WebApplicationInitializers detected on classpath: [com.example.pack.DummyInitializer@26d678a4]

With mvn clean test I see INFO: No Spring WebApplicationInitializer types detected on classpath.

In the test I start an Embedded Tomcat:

String pathToWebXML = new File("src/main/webapp/").getAbsolutePath();
tomcat = new Tomcat();
tomcat.setBaseDir("embedded_tomcat");
tomcat.setPort(0);
tomcat.addWebapp("", pathToWebXML);
tomcat.start();

The web.xml references a ServletContextListener implementation which creates a new (and empty) AnnotationConfigWebApplicationContext.

I uploaded the example project to GitHub: https://github.com/C-Otto/webapplicationinitializer

C-Otto
  • 5,615
  • 3
  • 29
  • 62
  • What version of java are you using in IntelliJ. Do you use java 8?I noticed that in the pom file you use java 8 – Periklis Douvitsas May 11 '16 at 10:55
  • @Periklis Yes, I use Java 8. Did you see any hint that I don't run Java 8? I'm confused about your question. – C-Otto May 11 '16 at 12:34
  • Sorry for the confusion, I just wanted to make sure that the java version you are using in IntelliJ is the same version that you have defined in pom.xml. Whenever, I have time I would download your application and I' ll give it a try – Periklis Douvitsas May 11 '16 at 12:39
  • OK. As far as I know, IntellIJ automatically imports the Maven settings (including the Java version). – C-Otto May 11 '16 at 13:09
  • The design decision is related to Spring Boot, which I do not use. However, the referenced Tomcat issue is insightful. Based on https://bz.apache.org/bugzilla/show_bug.cgi?id=52853#c19 do you see a way to make Tomcat find/scan/... correctly in the Maven case? – C-Otto May 11 '16 at 14:30
  • I just found out that setting `useSystemClassLoader` to `false` in Surefire's configuration solves this specific issue. However, I do not fully understand the consequences, and I'd appreciate an explanation of the issue at hand. Also see https://maven.apache.org/surefire/maven-surefire-plugin/examples/class-loading.html – C-Otto May 12 '16 at 14:30
  • Alternatively it helps to disable `useManfestOnlyJar`. Still, this is something I do not understand. I'll give the bounty to anyone who explains this, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=447790 :) – C-Otto May 12 '16 at 14:32

2 Answers2

0

As indicated in the comments, the classpath used by Maven Surefire (and Maven Failsafe) in the default setting is not scanned by Tomcat. Most classes are referenced using a MANIFEST.MF file inside a JAR file.

One option is to disable the useSystemClassLoader setting of the Maven plugins. However, this changes the details of the classloader, which may cause other problems.

As another option one could disable useManifestOnlyJar, which may cause problems on Windows machine.

In our project we decided to remove the initializer classes, and instead register whatever they were supposed to do manually. In a concrete example, as our implementation of AbstractSecurityWebApplicationInitializer was not found, we now register the security filter manually inside the contextInitialized method:

String filterName = AbstractSecurityWebApplicationInitializer.DEFAULT_FILTER_NAME);
servletContext.addFilter(filterName, new DelegatingFilterProxy(filterName)).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/*");
C-Otto
  • 5,615
  • 3
  • 29
  • 62
  • Another option is to make Tomcat also include the jars that are referenced via the manifest file in the jar created by surefire. This can be done in context.xml setting the Jar Scanner attribute scanManifest to true – user1304680 Jan 16 '17 at 07:04
0

You can tell Tomcat to include the jars that are referenced via the manifest file in the jar created by surefire. This can be done in context.xml setting the Jar Scanner attribute scanManifest to true. This is the default in newer versions of Tomcat as stated here: https://bz.apache.org/bugzilla/show_bug.cgi?id=59961.

user1304680
  • 700
  • 2
  • 5
  • 18