Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embed Tomcat with App in One Fat Jar

I was hoping to combine/embed Tomcat and my web app as onejar aka fat jar but I'm not sure if its possible. Its possible with Jetty using the Maven Shade plugin and Winstone but I tried something similar with Tomcat 7 and could not get it to load properly. The goal is to be able to do something like: java -jar mywebapp.jar.

The problem is that Tomcat wants to load things from the file system and not from the classpath. That is you can embed Tomcat but it will expect your WAR files to be available as files.

I tried many of the techniques on previous SO Posts for embedding Tomcat 6 & 7. While I can get it embedded and started it can't access my app.

I guess one option is having the JAR on boot unzip itself so that AppBase and DocBase are files on the file system. I haven't tried that yet but will.

There is a duplicate of the question here that I finally found: Self-contained war file with Tomcat embedded? (please vote to close as duplicate)

like image 714
Adam Gent Avatar asked Nov 11 '12 18:11

Adam Gent


People also ask

Can tomcat run jar?

It should be noted that since Tomcat runs on a Java installation, it also has access to any JAR file placed on the classpath of the JVM.

What is tomcat embed Jasper?

Anyway, the tomcat-embed-jasper is marked as provided , so indicates that you expect the JDK or a container to provide the dependency at runtime. This scope is only available on the compilation and test classpath, and is not transitive.


1 Answers

I have no idea how I kept missing this but the Tomcat Maven Plugin now supports make an executable WAR:

http://tomcat.apache.org/maven-plugin-2.0/executable-war-jar.html

UPDATE if you need Tomcat 8 you need a special configuration. You must use the 2.0 version of the plugin as the 2.2 Tomcat 7 plugin will not work and you will need the third party plugin tomcat8-war-runner. Below I have attached the maven configuration you will need which also allow you to select the correct version of Tomcat 8 you want (tomcat.version property).

The Tomcat8 maven plugin is in a messy state and still hasn't been released (please go vote on jira and complain to them to finish it).

Finally one major caveat with this maven plugin approach is that the plugin pseudo embeds. That is your app will not be running in the same classloader as Tomcat and is actually deployed during initialization. There are pros and cons to this approach.

Spring Boot and this example from Oracle on the other hand will run Tomcat in the same classloader as your app (that is it is truly embedded I think).

    <plugin>
      <groupId>org.apache.tomcat.maven</groupId>
      <artifactId>tomcat7-maven-plugin</artifactId>
      <version>2.0</version>
      <configuration>
        <port>${tomcat.port}</port>
        <path>/</path>
      </configuration>
      <executions>
        <execution>
          <id>tomcat-run</id>
          <goals>
            <goal>exec-war-only</goal>
          </goals>
          <phase>package</phase>
          <configuration>
            <path>/</path>
            <port>${tomcat.port}</port>
            <attachArtifactClassifierType>war</attachArtifactClassifierType>
            <mainClass>org.apache.tomcat.maven.runner.Tomcat8RunnerCli</mainClass>
            <extraDependencies>
              <extraDependency>
                <groupId>com.nitorcreations</groupId>
                <artifactId>tomcat8-war-runner</artifactId>
                <version>1.0</version>
              </extraDependency>
            </extraDependencies>
          </configuration>
        </execution>
      </executions>
      <dependencies>
        <dependency>
          <groupId>org.apache.tomcat.embed</groupId>
          <artifactId>tomcat-embed-core</artifactId>
          <version>${tomcat.version}</version>
        </dependency>
        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-util</artifactId>
          <version>${tomcat.version}</version>
        </dependency>
        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-coyote</artifactId>
          <version>${tomcat.version}</version>
        </dependency>
        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-api</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-jdbc</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-dbcp</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-servlet-api</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-jsp-api</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-jasper</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-jasper-el</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-el-api</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-catalina</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-tribes</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-catalina-ha</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-annotations-api</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat</groupId>
          <artifactId>tomcat-juli</artifactId>
          <version>${tomcat.version}</version>
        </dependency>

        <dependency>
          <groupId>org.apache.tomcat.embed</groupId>
          <artifactId>tomcat-embed-logging-juli</artifactId>
          <version>${tomcat.version}</version>
        </dependency>
        <dependency>
          <groupId>org.apache.tomcat.embed</groupId>
          <artifactId>tomcat-embed-logging-log4j</artifactId>
          <version>${tomcat.version}</version>
        </dependency>
      </dependencies>
    </plugin>
like image 53
Adam Gent Avatar answered Oct 06 '22 16:10

Adam Gent