I am looking for source code for a complete application that uses the Webstart Maven Plugin.
Any ideas?
I am looking for source code for a complete application that uses the Webstart Maven Plugin.
Any ideas?
I tried the webstart plugin in a prrof of concept involving an embedded tomcat server. The plugin is bound to the package phase and takes a longtime to execute, I would recommend to invoke it manually from the command line. It generates a zip file in the target directory containing the jnlp file and all dependencies. This file can then be extraced and put on a webserver. The url in the pom should point to this path on the server. When started, the app runs a tomcat server on localhost port 8080 with a simple servlet that just returns the requested path as a string.
Let me know if this works for you.
Here is the pom of the project, the plugin configuration was mostly copied from the documentation here
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>net.jhorstmann</groupId>
<artifactId>EmbeddedTomcatWebstart</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>EmbeddedTomcatWebstart</name>
<url>http://localhost/jnlp/</url>
<organization>
<name>Organisation</name>
</organization>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<tomcat.version>7.0.6</tomcat.version>
</properties>
<repositories>
<repository>
<id>jboss</id>
<url>http://repository.jboss.org/nexus/content/groups/public/</url>
</repository>
<repository>
<id>sonatype</id>
<url>http://oss.sonatype.org/content/repositories/releases/</url>
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.5</source>
<target>1.5</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<archive>
<manifest>
<mainClass>net.jhorstmann.embeddedtomcat7.App</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo.webstart</groupId>
<artifactId>webstart-maven-plugin</artifactId>
<executions>
<execution>
<!-- bind to phase, I prefer to call it manualls -->
<phase>package</phase>
<goals>
<goal>jnlp-inline</goal> <!-- use jnlp, jnlp-inline or jnlp-single as appropriate -->
</goals>
</execution>
</executions>
<configuration>
<!--outputDirectory></outputDirectory--> <!-- not required?? -->
<!-- Set to true to exclude all transitive dependencies. Default is false. -->
<excludeTransitive>false</excludeTransitive>
<!-- The path where the libraries are stored within the jnlp structure. not required. by default the libraries are within the working directory -->
<libPath>lib</libPath>
<outputJarVersions>true</outputJarVersions>
<!-- [optional] transitive dependencies filter - if omitted, all transitive dependencies are included -->
<dependencies>
<!-- Note that only groupId and artifactId must be specified here. because of a limitation of the Include/ExcludesArtifactFilter -->
<!--
<includes>
<include>commons-logging:commons-logging</include>
<include>commons-cli:commons-cli</include>
</includes>
-->
<!--
<excludes>
<exclude></exclude>
<excludes>
-->
</dependencies>
<!--
<resourcesDirectory>${project.basedir}/src/main/jnlp/resources</resourcesDirectory>
-->
<!-- default value -->
<!-- JNLP generation -->
<jnlp>
<!-- default values -->
<!--inputTemplateResourcePath>${project.basedir}</inputTemplateResourcePath-->
<!--inputTemplate>src/main/jnlp/template.vm</inputTemplate--> <!-- relative to inputTemplateResourcePath -->
<outputFile>app.jnlp</outputFile> <!-- defaults to launch.jnlp -->
<!-- used to automatically identify the jar containing the main class. -->
<!-- this is perhaps going to change -->
<mainClass>net.jhorstmann.embeddedtomcat7.App</mainClass>
</jnlp>
<!-- SIGNING -->
<!-- defining this will automatically sign the jar and its dependencies, if necessary -->
<sign>
<keystore>${basedir}/keystore</keystore>
<keypass>password</keypass> <!-- we need to override passwords easily from the command line. ${keypass} -->
<storepass>password</storepass> <!-- ${storepass} -->
<!--storetype>fillme</storetype-->
<alias>EmbeddedTomcatWebstart</alias>
<!--validity>fillme</validity-->
<!-- only required for generating the keystore -->
<dnameCn>EmbeddedTomcatWebstart</dnameCn>
<dnameOu>Organisation Unit</dnameOu>
<dnameO>Organisation</dnameO>
<dnameL>Location</dnameL>
<dnameSt>State</dnameSt>
<dnameC>Country</dnameC>
<verify>true</verify> <!-- verify that the signing operation succeeded -->
<!-- KEYSTORE MANAGEMENT -->
<keystoreConfig>
<delete>true</delete> <!-- delete the keystore -->
<gen>true</gen> <!-- optional shortcut to generate the store. -->
</keystoreConfig>
</sign>
<!-- BUILDING PROCESS -->
<pack200>true</pack200>
<gzip>true</gzip> <!-- default force when pack200 false, true when pack200 selected ?? -->
<!-- causes a version attribute to be output in each jar resource element, optional, default is false -->
<outputJarVersions>false</outputJarVersions>
<!--install>false</install--> <!-- not yet supported -->
<verbose>true</verbose>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-catalina</artifactId>
<version>${tomcat.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-coyote</artifactId>
<version>${tomcat.version}</version>
</dependency>
</dependencies>
</project>
Here is a custom template for the jnlp file placed at src/main/jnlp/template.vm
, I can't remember why I needed that exactly:
<?xml version="1.0" encoding="utf-8"?>
<jnlp
spec="$jnlpspec"
codebase="$project.Url"
href="$outputFile">
<information>
<title>$project.Name</title>
<vendor>$project.Organization.Name</vendor>
<homepage href="$project.Url"/>
<description>$project.Description</description>
#if($offlineAllowed)
<offline-allowed/>
#end
</information>
#if($allPermissions)
<security>
<all-permissions/>
</security>
#end
<resources>
<j2se version="$j2seVersion"/>
$dependencies
</resources>
<application-desc main-class="$mainClass"/>
</jnlp>
This is the main class at src/main/java/net/jhorstmann/embeddedtomcat7/App.java
package net.jhorstmann.embeddedtomcat7;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.servlet.ServletException;
import org.apache.catalina.Context;
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Wrapper;
import org.apache.catalina.startup.Tomcat;
public class App {
public static void main(String[] args) throws LifecycleException, ServletException, IOException {
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
File webappDir = new File(tmpDir, "embeddedtomcat7");
webappDir.mkdir();
final Tomcat tomcat = new Tomcat();
tomcat.setPort(8080);
tomcat.setBaseDir(tmpDir.getAbsolutePath());
tomcat.getConnector().setURIEncoding("UTF-8");
String contextPath = "/";
Context context = tomcat.addContext(contextPath, webappDir.getAbsolutePath());
Wrapper wrapper = tomcat.addServlet(contextPath, "Test", new TestServlet());
//Wrapper wrapper = tomcat.addServlet(contextPath, "Async", new AsyncServlet());
//wrapper.setAsyncSupported(true);
wrapper.addMapping("/*");
tomcat.start();
tomcat.getServer().await();
}
}
And finally a servlet at src/main/java/net/jhorstmann/embeddedtomcat7/TestServlet.java
package net.jhorstmann.embeddedtomcat7;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class TestServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html; charset=utf-8");
PrintWriter writer = resp.getWriter();
writer.println("<h1>" + req.getPathInfo() + "</h1>");
writer.close();
}
}
A few notes on this plugin (it's documentation is horrible):
It won't use the template.vm file unless you specify it, like
<templateFilename>roll-gen-template.vm</templateFilename>
For creating a war:
If you want to use the JnlpDownloadServlet (the standard one java provides) to serve up the files instead of the above code (and have the plugin generate a working version.xml file for it to use, etc.), basically you need to create a new project of type war and target the jnlp-download-servlet goal
(it doesn't seem to support creating a war with classes from the current pom project) then, instead of a single <jnlp>
section, you'll have the <jnlpFiles>
section instead, which can list multiple jar dependencies. You may need to modify your web.xml file as well.
http://www.mojohaus.org/webstart/webstart-maven-plugin/jnlp-mojos-overview.html has an example pom for
If you have additional comments feel free to edit this, it is a community wiki.