1

I have a very simple Gradle (7.0-rc-1) script to initialise a single Spring 5 "hello world" endpoint using an embedded Tomcat instance. The original code is taken from a random example I found on the internet. My example Gradle project can be found here.

I'm not sure how it works but somehow the web server knows to call the WebApplicationInitializer.onStartup(ServletContext) method on startup so that Spring is intialised.

This works correctly on Java 8; but fails when I change the following toolchain specification in the Gradle build definition to Java 16.

java {
    toolchain {
//        languageVersion = JavaLanguageVersion.of(16)
        languageVersion = JavaLanguageVersion.of(8)
    }
}

When using Java 8, Spring is intialised correctly and the endpoint works.

When using Java 16, The onStartup() method is not called, so Spring is not initialised and the endpoint doesn't work (though Tomcat is still started and responds with an error).

The logging shows a message like, there is no stacktrace though:

INFO: No Spring WebApplicationInitializer types detected on classpath

What do I need to do to make this work on Java 16?

Note that I don't want to use spring-boot, please don't suggest it.

Shorn
  • 19,077
  • 15
  • 90
  • 168
  • you have not understood something very important. You have an embedded tomcat. You are in spring boot!!! Maybe not an official SpringBoot as the article that you posted seems to take the spring framework, and tries to manually embed a TomcatServer. That is what spring boot officially does though – Panagiotis Bougioukos Mar 27 '21 at 19:33
  • 1
    No, I am intentionally not using spring-boot. – Shorn Mar 27 '21 at 22:25

1 Answers1

2

I've found a workaround that gets Spring configured and responding to the /hello endpoint. But I don't know why it works or if it's the right thing to do.

If someone can answer the question with an explanation of what's going on with Java 16 - I will gladly mark that as the accepted answer.


Workaround

My work around is to programmatically add the ServletContainerInitializer class.

So where before I was just calling the addWebapp() method:

tomcat.addWebapp("", appBase);

I now add my Spring intializer explicitly:

Context appContext = tomcat.addWebapp("", appBase);
appContext.addServletContainerInitializer(new SpringAppConfig(), null);

Updated code on Github.

Shorn
  • 19,077
  • 15
  • 90
  • 168