简体   繁体   中英

How can I create executable jars with embedded tomcat 9?

Has anyone tried the plugin to build an executable war/jar using Tomcat 9?

I attempted to do so however ran into:

 Exception in thread "main" java.lang.NoSuchMethodError: org.apache.catalina.startup.Catalina.setConfig(Ljava/lang/String;)V at org.apache.tomcat.maven.runner.Tomcat7Runner.run(Tomcat7Runner.java:240) at org.apache.tomcat.maven.runner.Tomcat7RunnerCli.main(Tomcat7RunnerCli.java:204)

I looked at the source and changed Catalina.setConfig() to Catalina.setConfigFile() based on docs here . After doing so the .extract dir is just empty:

use extractDirectory:.extract populateWebAppWarPerContext warValue:ROOT.war|ROOT populateWebAppWarPerContext contextValue/warFileName:ROOT/ROOT.war webappWarPerContext entry key/value: ROOT/ROOT.war expand to file:.extract/webapps/ROOT.war Exception in thread "main" java.lang.Exception: FATAL: impossible to create directories:.extract/webapps at org.apache.tomcat.maven.runner.Tomcat7Runner.extract(Tomcat7Runner.java:586) at org.apache.tomcat.maven.runner.Tomcat7Runner.run(Tomcat7Runner.java:204) at org.apache.tomcat.maven.runner.Tomcat7RunnerCli.main(Tomcat7RunnerCli.java:204)

.... although there is a ROOT.war, server.xml, web.xml in the *-exec-war.jar.

Is there a better way to be creating exec-jars with embedded tomcat 9?

For those looking for a solution it was fairly straight forward to checkout the code for the plugin and make a few changes to get this to work. Namely: Update POM to change the depends to Tomcat 9 Fix compile errors which generally stem from deprecated methods. The lookup on these methods can be found here . For example:

-                container.setConfig( serverXml.getAbsolutePath() );
+                container.setConfigFile( serverXml.getAbsolutePath() );

... and ...

-            staticContext.addServletMapping( "/", "staticContent" );
+            staticContext.addServletMappingDecoded( "/", "staticContent" );

There are a few others but generally not difficult to resolve. After doing so I updated my app's pom to use the modified version and was able to generate a Tomcat 9 exec jar.

I would love to hear what others are doing here. I know some are programmatically initializing Tomcat via a new Tomcat() instance however curious what other solutions exist ready made. Thanks

For future searchs, one solution is to use the DirResourceSet or JarResourceSet.

    String webAppMount = "/WEB-INF/classes";
    WebResourceSet webResourceSet;
    if (!isJar()) {
        webResourceSet = new DirResourceSet(webResourceRoot, webAppMount, getResourceFromFs(), "/");
    } else {
        webResourceSet = new JarResourceSet(webResourceRoot, webAppMount, getResourceFromJarFile(), "/");
    }
    webResourceRoot.addJarResources(webResourceSet);
    context.setResources(webResourceRoot);


public static boolean isJar() {
    URL resource = Main.class.getResource("/");
    return resource == null;
}

public static String getResourceFromJarFile() {
    File jarFile = new File(System.getProperty("java.class.path"));
    return jarFile.getAbsolutePath();
}

public static String getResourceFromFs() {
    URL resource = Main.class.getResource("/");
    return resource.getFile();
}

When add the webapp, use root path "/" for docBase:

tomcat.addWebapp("", "/")

Credits for: https://nkonev.name/post/101

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM