Oslo City Hall from Tjuvholmen |
tomcat7:exec-war
maven goal that does just that. It takes your WAR artifact and packages it together with all Tomcat dependencies. At the end it also includes Tomcat7RunnerCli
Main-class to manifest.Curious to try it? Take your existing WAR project and add the following to your
pom.xml
:<plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.0</version> <executions> <execution> <id>tomcat-run</id> <goals> <goal>exec-war-only</goal> </goals> <phase>package</phase> <configuration> <path>/standalone</path> <enableNaming>false</enableNaming> <finalName>standalone.jar</finalName> <charset>utf-8</charset> </configuration> </execution> </executions> </plugin>Run
mvn package
and few seconds later you'll find shiny standalone.jar
in your target
directory. Running your web application was never that simple:$ java -jar target/standalone.jar...and you can browse
localhost:8080/standalone
. Although the documentation of path
parameter says (emphasis mine):The webapp context path to use for the web application being run. The name to store webapp in exec jar. Do not use /just between the two of us,
<path>/</path>
seems to work after all. It turns out that built in main
class is actually a little bit more flexible. For example you can say (I hope it's self-explanatory):$ java -jar standalone.jar -httpPort=7070What this runnable JAR does is it first unpacks WAR file inside of it to some directory (
.extract
by default1) and deploys it to Tomcat - all required Tomcat JARs are also included. Empty standalone.jar
(with few KiB WAR inside) weights around 8.5 MiB - not that much if you claim that pushing whole Tomcat with every release alongside your application is wasteful.Talking about Tomcat JARs, you should wonder how to choose Tomcat version included in this runnable? Unfortunately I couldn't find any simple option, so we must fall back to explicitly redefining plugin dependencies (version 2.0 has hardcoded 7.0.30 Tomcat). It's quite boring, but not that complicated and might be useful for future reference:
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <tomcat7Version>7.0.33</tomcat7Version> </properties> <build> <plugins> <plugin> <groupId>org.apache.tomcat.maven</groupId> <artifactId>tomcat7-maven-plugin</artifactId> <version>2.0</version> <executions> <execution> <id>tomcat-run</id> <goals> <goal>exec-war-only</goal> </goals> <phase>package</phase> <configuration> <path>/standalone</path> <enableNaming>false</enableNaming> <finalName>standalone.jar</finalName> <charset>utf-8</charset> </configuration> </execution> </executions> <dependencies> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-util</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-coyote</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-api</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-dbcp</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-servlet-api</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jsp-api</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jasper-el</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-el-api</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-tribes</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-catalina-ha</artifactId> <version>${tomcat7Version}</version> </dependency> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-annotations-api</artifactId> <version>${tomcat7Version}</version> </dependency> </dependencies> </plugin> </plugins> </build>In the next article we will learn how to tame these pesky Tomcat internal logs appearing in the terminal (
java.util.logging
...) In the meantime I discovered and reported MTOMCAT-186 Closing executable JAR does not call ServletContextListener.contextDestroyed() - have look if this is a deal breaker for you.1 - it might be a good idea to specify different directory using
-extractDirectory
and clean it before every restart with -resetExtract
.
Thanks for that trick.
ReplyDeleteI got one problem: I wrote a little REST-servlet with JAX-RS, working fine when executed directly inside Eclipse with Tomcat7. Then I made a executable .jar-file according to your instructions but my servlet doesn't work. It's able to start and no errors are given but me REST-servlet isnt responding to any HTTP-Request anymore (neither a result nor an error page is shown). My servlet uses some external jars (like jersey, jaxb,...), I ensured that Maven copies these libs into the target folder. Any idea?
were you able to fix this? I am having the this issue and unable to fix it
DeleteRemember about registering the rest classes inside your Application class (the one with ApplicationPath). I noticed that using jersey inside standalone jar requires that in compare of using deployment on tomcat where registering just package is working
ReplyDeleteCan you please eloborate on how to register the rest class in the application class?
DeleteI have followed your instructions and get the error:
ReplyDeletejava.io.FileNotFoundException: C:\Users\Home\.extract\webapps\test.war (The system cannot find the file specified)
It happens only on Windows and on macOS in runs perfectly. Do you now how to make it run on Windows?
Thank you sir, it is a great article
ReplyDeleteAll information is available thanks....
ReplyDeleteSocial Media Marketing Faridabad
Website Design Services
This comment has been removed by a blog administrator.
ReplyDelete