I would like to create a WAR package with maven, that can be deployed under Tomcat (9 or above) and also can be executed on the command line (= CLI). I already realised to make a package, that could be deployed either under Tomcat or could be executed on the CLI, but not both in the same package. This article says:
This new class can now be used to run the application using embeddedd Jetty or Tomcat, internally, and it can be deployed to any Servlet 3 container.
But it didn't work for me (neither under Tomcat nor in CLI).
I have the following project structure:
pom.xml
src/main/java/My/App.java
src/main/webapp/WEB-INF/config
src/main/webapp/WEB-INF/web.xml
src/main/webapp/doc
src/main/webapp/resources
src/test/java/My/AppTest.java
src/test/config
src/test/resources
In the generated .WAR there is the following structure:
WEB-INF/classes/My/App.class
WEB-INF/config //configs of My.App
WEB-INF/lib //dependencies of My.App as .JAR
WEB-INF/web.xml //required by Tomcat
doc //some docs accessible within the running application
resources //resources of My.App
This is almost good for deploying under Tomcat; the only problem is that My/App.class should also be in a .JAR file under WEB-INF/lib.
I also can't start the .WAR in the CLI (with java -jar), because the JVM can't find the dependencies of My/App.class, even if MANIFEST.MF has ClassPath with entries e.g.:
WEB-INF/lib/dp1.jar
WEB-INF/lib/dp2.jar
Can someone help me please to achieve this ?
The content of App.java (based on the example in the article above):
package My;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardVirtualThreadExecutor;
import org.apache.catalina.startup.Tomcat;
import org.apache.commons.io.FileUtils;
import org.apache.tomcat.util.descriptor.web.ContextEnvironment;
import org.apache.tomcat.util.descriptor.web.FilterDef;
import org.apache.tomcat.util.descriptor.web.FilterMap;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import java.util.logging.Logger;
public class App extends SpringBootServletInitializer {
private static final Logger LOGGER = Logger.getLogger(App.class.getName());
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(App.class);
}
public static void main(String[] args) throws LifecycleException, UnknownHostException {
Tomcat tomcat = createAndConfigureTomcat();
tomcat.start();
tomcat.getServer().await();
}
public static Tomcat createAndConfigureTomcat() throws UnknownHostException {
Tomcat tomcat = new Tomcat();
String docBase = new File(System.getProperty("java.io.tmpdir") + "/tomcat-" + Math.random()).getAbsolutePath();
tomcat.setBaseDir(docBase);
tomcat.getHost().setAppBase(docBase);
tomcat.enableNaming();
// ... etc
}
}
The content of pom.xml:
4.0.0
My.app
My.app
0.1
war
17
17
UTF-8
UTF-8
7.0.0-M7
2.4
9.0.104
3.13.0
3.4.0
3.4.2
0.8.12
org.springframework
spring-aop
${spring.version}
org.springframework
spring-core
${spring.version}
org.springframework
spring-context
${spring.version}
org.springframework
spring-expression
${spring.version}
org.springframework
spring-web
${spring.version}
org.yaml
snakeyaml
${snakeyaml.version}
org.apache.tomcat.embed
tomcat-embed-core
${tomcat.version}
org.apache.tomcat.embed
tomcat-embed-el
${tomcat.version}
org.apache.tomcat.embed
tomcat-embed-jasper
9.0.44
maven-compiler-plugin
${maven-compiler-plugin.version}
org.apache.maven.plugins
maven-jar-plugin
${maven-jar-plugin.version}
maven-war-plugin
${maven-war-plugin.version}
src/main/webapp/WEB-INF/web.xml
false
true
true
WEB-INF/lib/
${project.version}
${maven.build.timestamp}
WEB-INF/classes/
My.App
org.jacoco
jacoco-maven-plugin
${jacoco.version}
src/test/config
coverage
org.jacoco
jacoco-maven-plugin
prepare-agent
prepare-agent
report
report