Export maven war artifact as runnable jetty package
Today I will show you a way to export a <packaging>war</packaging> artifact as a runnable windows application.
The ingredients are:
- maven war artifact (i.e. our web application)
- embedded Jetty
A minimal web application’s pom looks like this:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>de.ahoehma</groupId> <artifactId>dummy-webapp</artifactId> <version>1.0.0-SNAPSHOT</version> <packaging>war</packaging> </project>
Now we add some components to the artifact …
1. add the following profile to the pom.xml:
<profiles> <profile> <id>jetty-offline</id> <build> <plugins> <plugin> <artifactId>maven-assembly-plugin</artifactId> <version>2.2-beta-5</version> <configuration> <finalName>offline-dummy-webapp-${project.version}</finalName> <attach>false</attach> <descriptors> <descriptor>src/assembly/jetty-offline.xml</descriptor> </descriptors> </configuration> <executions> <execution> <id>make-assembly</id> <phase>package</phase> <goals> <goal>single</goal> </goals> </execution> </executions> </plugin> </plugins> </build> <dependencies> <!-- logging ... --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.15</version> <scope>runtime</scope> </dependency> <!-- embedded jetty --> <dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty</artifactId> <version>${jetty.version}</version> </dependency> <dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>start</artifactId> <version>${jetty.version}</version> </dependency> <dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jetty-util</artifactId> <version>${jetty.version}</version> </dependency> <dependency> <groupId>org.mortbay.jetty</groupId> <artifactId>jsp-2.1-jetty</artifactId> <version>${jetty.version}</version> </dependency> </dependencies> <properties> <jetty.version>6.1.23</jetty.version> </properties> </profile> </profiles>
2. the assembly descriptor for src/assembly/jetty-offline is here:
<?xml version="1.0" encoding="UTF-8"?> <assembly xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.1 http://maven.apache.org/xsd/assembly-1.1.1.xsd"> <formats> <format>dir</format> </formats> <dependencySets> <dependencySet> <!-- unpack the webapp as root application --> <scope>runtime</scope> <unpack>true</unpack> <outputDirectory>webapps/root/</outputDirectory> <includes> <include>de.ahoehma:dummy-webapp:war</include> </includes> </dependencySet> <dependencySet> <unpack>false</unpack> <outputDirectory>lib</outputDirectory> <useTransitiveFiltering>true</useTransitiveFiltering> <useStrictFiltering>true</useStrictFiltering> <includes> <include>org.mortbay.jetty:jetty</include> <include>org.mortbay.jetty:jetty-util</include> <include>org.mortbay.jetty:start</include> <include>org.mortbay.jetty:jsp-2.1-jetty</include> <include>commons-logging:commons-logging</include> <include>log4j:log4j</include> </includes> </dependencySet> </dependencySets> <fileSets> <fileSet> <directory>src/jetty/bin</directory> <outputDirectory>bin/</outputDirectory> <filtered>false</filtered> </fileSet> <fileSet> <directory>src/jetty/resources</directory> <outputDirectory>etc/</outputDirectory> <filtered>false</filtered> </fileSet> </fileSets> </assembly>
See maven-assembly-plugin for more options …
3. src/jetty/bin contains a windows batch file:
@echo off @set JVM_OPTS=-XX:MaxPermSize=256m -XX:PermSize=128m -Xms128m -Xmx512m (cd .. && java %JVM_OPTS% -jar lib/start-6.1.23.jar)
4. and at least the src/jetty/resources contains the file jetty.xml:
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd"> <Configure id="Server" class="org.mortbay.jetty.Server"> <Set name="ThreadPool"> <New class="org.mortbay.thread.BoundedThreadPool"> <Set name="minThreads">10</Set> <Set name="maxThreads">250</Set> <Set name="lowThreads">25</Set> </New> </Set> <Call name="addConnector"> <Arg> <New class="org.mortbay.jetty.nio.SelectChannelConnector"> <Set name="host"><SystemProperty name="jetty.host" default="localhost"/></Set> <Set name="port"><SystemProperty name="jetty.port" default="1976"/></Set> <Set name="maxIdleTime">30000</Set> <Set name="Acceptors">2</Set> <Set name="statsOn">false</Set> <Set name="confidentialPort">8442</Set> <Set name="lowResourcesConnections">5000</Set> <Set name="lowResourcesMaxIdleTime">5000</Set> </New> </Arg> </Call> <Set name="handler"> <New id="Handlers" class="org.mortbay.jetty.handler.HandlerCollection"> <Set name="handlers"> <Array type="org.mortbay.jetty.Handler"> <Item> <New id="Contexts" class="org.mortbay.jetty.handler.ContextHandlerCollection"/> </Item> <Item> <New id="DefaultHandler" class="org.mortbay.jetty.handler.DefaultHandler"/> </Item> </Array> </Set> </New> </Set> <Call name="addLifeCycle"> <Arg> <New class="org.mortbay.jetty.deployer.ContextDeployer"> <Set name="contexts"><Ref id="Contexts"/></Set> <Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set> <Set name="scanInterval">1</Set> </New> </Arg> </Call> <Call name="addLifeCycle"> <Arg> <New class="org.mortbay.jetty.deployer.WebAppDeployer"> <Set name="contexts"><Ref id="Contexts"/></Set> <Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set> <Set name="parentLoaderPriority">false</Set> <Set name="extract">true</Set> <Set name="allowDuplicates">false</Set> </New> </Arg> </Call> <Set name="stopAtShutdown">true</Set> <Set name="sendServerVersion">true</Set> <Set name="sendDateHeader">true</Set> <Set name="gracefulShutdown">1000</Set> </Configure>
Now we are able to build a „offline version“ of our web application:
mvn package -Pjetty-offline
The result will be a directory target\distribution\offline-dummy-webapp-1.0.0-SNAPSHOT with the structure:
bin/ jetty_run.bar etc/ jetty.xml lib/ log4j-1.2.15.jar commons-logging-1.1.1.jar servlet-api-2.5-20081211.jar start-6.1.23.jar jetty-6.1.23.jar jetty-util-6.1.23.jar ant-1.6.5.jar core-3.1.1.jar ecj-3.5.1.jar jsp-2.1-jetty-6.1.23.jar jsp-2.1-glassfish-2.1.v20091210.jar jsp-api-2.1-glassfish-2.1.v20091210.jar webapps/ root/ index.html css/ images/ META-INF/ pages/ WEB-INF/ ...
To run the web application start the jetty_run.bat (i.e. open the dir with the explorer and double click the bat-file).
That’s it 😀
This article was the first part if the tutorial … in the second part I will show you how to build a windows exe package with a runnable web application inside …
JoWiSoftware.de 13:30 am Sonntag, 13. Februar 2011 Permalink | Zum Antworten anmelden
Creating runnable wars with Maven (and Jetty)…
Hudson is a really great tool if you work with source code in a team with more than two persons. One thing in hudson always fascinated me: the fact, that Hudson is runnable just by typing java -jar hudson.war I do not know if it really has practical re…
tplee923 19:54 am Donnerstag, 16. Juni 2011 Permalink | Zum Antworten anmelden
When I use your code, and execute the bat file, why I get the error:
java.lang.ClassNotFoundException: org.mortbay.xml.XmlConfiguration
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at org.mortbay.start.Main.invokeMain(Main.java:179)
at org.mortbay.start.Main.start(Main.java:534)
at org.mortbay.start.Main.start(Main.java:441)
at org.mortbay.start.Main.main(Main.java:119)
Andreas Höhmann 23:30 am Donnerstag, 16. Juni 2011 Permalink | Zum Antworten anmelden
Hmm … what version of jetty do you use?
Creating runnable wars with Maven (and Jetty) – JoWiSoftware 9:30 am Sonntag, 30. August 2020 Permalink | Zum Antworten anmelden
[…] already are a few blog posts which gave interesting hints. I decided to take an easy way: using overlays in the […]