I am posting the simplest possible example I could get working. It is a grossly over-simplified example designed to focus purely on getting the Swing/Webstart/Maven combination working.
For example:
The Swing client is the simplest possible Swing app you could possibly create (it just displays ‘Hello World’), since the focus is on the Swing/Webstart/Maven setup, not complex Swing coding
There are very few dependencies on other projects, to keep the poms simple. Obviously real apps are likely to be much more complicated
The example uses just 2 maven modules (client and web) when in reality, a real enterprise project would likely have many more (e.g. client, web, service, persist). The web module in this example could act as your entry point to those other modules.
Anyway, hopefully those simplifications keep the example easy to follow.
Basic overview
The example uses a simple 2 module (client and web) maven project, with the jnlp defined in the client module. You then need to build and deploy the artifacts (a zip containing the built jnlp bundle for the client module and a war for the web module) to a maven repository. The final piece of the puzzle is then downloading the client zip and web war to your app server of choice (e.g. tomcat).
Note that the Maven project structure I am using here is (loosely) based on the maven multi module example from the maven docs. The dir structure is just the standard maven directory layout. We wont be using the test and resources folders for this simple example, but they are included as a placeholder.
1. Setup maven folder structure
I don’t know of a maven archetype for creating a multi-module project, so we need to do it manually. Create the following directory structure:
package com.shaunabram.swingwebstartmaven;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class HelloWorldSwing {
public static void main(String[] args) {
JFrame frame = new JFrame("HelloWorldSwing");
final JLabel label = new JLabel("Hello World");
frame.getContentPane().add(label);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
3. Create web.xml
Next, we create the simplest possible web.xml i.e. an empty one. For this example, we just need the webapp to serve our jnlp file (and associated jars). In a real application, the web module would be the interface your your server. For example, you might use Spring Remoting and HTTP invokers to allow your Swing client to communicate with a service layer via your web module.
JnlpDownladServlet
Note that our example does not use the JnlpDownloadServlet, purely to keep the example as simple as possible. You however, may want to configure our webapp’s web.xml to use the JnlpDownladServlet as it adds some extra benefits such as allowing you to use $$codebase instead of having to maintain hardcoded project URLs (e.g. the template.vm file in the next section would benefit from its use as it contains a hardcoded url). See some background info on the JnlpDownloadServlet here, and notes on how to configure your webapp to use JnlpDownloadServlet here.
Your web.xml should look something like below.
This file will be located here:
Note the use of the hardcoded URL for the codebase. You may need to change this for your local environment. For more options how the codebase is used, see here. Also, as noted above, utilising the JnlpDownloadServlet would allow use to remove the hardcoded URL and use $$codebase instead.
5. Create our maven poms
5.1 Parent project pom
Next, we define the pom for our parent project, SwingWebstartMaven.
This file will be located here:
This pom is the most important part of this example as it is where we specify the details for the jnlp file generation. See here for JNLP File generation details.
4.0.0com.shaunabram.swingwebstartmavenSwingWebstartMaven1.0SwingWebstartMaven-ClientjarSwingWebstartMaven Clientorg.codehaus.mojo.webstartwebstart-maven-plugin1.0-beta-2packagepackagejnlp-inlinelaunch.jnlpcom.shaunabram.swingwebstartmaven.HelloWorldSwinglibSwingWebstartMavenExample-KeyStoreYourPasswordYourPasswordSwingWebstartMavenExample3650Your NameOrganizational UnitOrganizationCity or LocalityState or ProvinceUStruetruetruefalsetruefalsetrue
5.3 Webapp module pom
Next, we define the pom for our webapp module.
This file will be located here:
4.0.0com.shaunabram.swingwebstartmavenSwingWebstartMaven1.0SwingWebstartMaven-WebwarSwingWebstartMaven Web
6. Build, deploy and run
Build
To build, simply do:
mvn clean install
Deploy
Deploying is a slightly trickier matter…
Web module
For the web module, you can simply build and ensure the generated war is placed in your tomcat webapps dir, by whichever mechanism suits you best.
For example,
1) Manually copy the war from the target dir to your tomcat dir (although if doing is manually like this, you may want to remove any version number i.e. it should be named SwingWebstartMaven-Webapp.war rather than SwingWebstartMaven-Webapp-1.0.war).
2) Add the following to the build/pluginManagement/plugins section of your parent pom (SwingWebstartMaven\SwingWebstartMaven\pom.xml)
3) Write a script on your server than will pull the generated war from your maven repository (e.g. using wget to download from Nexus) and place it in your tomcat dir.
Client module
For the client module however, deploying it is a slightly trickier matter.
My preferred approach is to to utilise the script approach mentioned in step 3) above to also pull down the client zip (e.g. SwingWebstartMaven\SwingWebstartMaven-Client\target\SwingWebstartMaven-Client-1.0.zip), and extract the contents into the tomcat webapps dir (I like to put it in a webstart folder e.g. tomcat\webapps\SwingWebstartMaven-Web\webstart).
For example, the script could, among other things,
Stop tomcat
Determine the latest version of the project available in the maven repository
Pull down the web module’s war tomcat/webapps
Start tomcat (so the war will be extracted and deployed)
Pull down the client module’s zip
Unzip to (for example) tomcat/webapps/SwingWebstartMaven-Web/webstart
These are all just suggestions for deployment of course – how you do it is up to you. But my point is that I found extracting the client module’s generated zip file (containing the jnlp bundle) to be the easiest way to deploy a JNLP project to an app server to make it easily accessible for users.
Run
Whatever build and deployment method you choose, you should now be able to access your Webstart enabled Swing app from a URL like this:
Could you maybe attach a screenshot of your final directory structure and all of the files near the end of the post? Some parts of this guide are a little confusing. For example, the text-based directory diagram appears to show that SwingWebstartMaven-Webapp is located within SwingWebstartMaven-Client, which I’m guessing it’s not; and the guide says to put template.vm inside SwingWebstartMaven-Webapp/src, even though that directory structure doesn’t exist in the original diagram. Otherwise, this has been really, really helpful!
Hey Heet,
Thanks for the pointers. I updated the directory diagram – it now reflects the zipped project I linked to at the start of the post. I’m afraid it’s been a long time since I worked on this though, so I don’t have a final version to post…
Thanks for this guide, helped me a lot!
Thanks Jörg, glad you found it useful…
Shaun
Great guide. Thanks for it.
Unfortunately I encountered a problem when running downloaded example. After deploying my web browser opens address http://localhost:8080/SwingWebstartMaven-Web/ successfully, but http://localhost:8080/SwingWebstartMaven-Web/webstart/launch.jnlp gives 404 error. What should I check? Thanks in advance
Hi Martin,
Sorry for the delay in responding – your comment got blocked by the spam filter. Are you still having problems?
Shaun
Shaun,
Could you maybe attach a screenshot of your final directory structure and all of the files near the end of the post? Some parts of this guide are a little confusing. For example, the text-based directory diagram appears to show that SwingWebstartMaven-Webapp is located within SwingWebstartMaven-Client, which I’m guessing it’s not; and the guide says to put template.vm inside SwingWebstartMaven-Webapp/src, even though that directory structure doesn’t exist in the original diagram. Otherwise, this has been really, really helpful!
Heet
Hey Heet,
Thanks for the pointers. I updated the directory diagram – it now reflects the zipped project I linked to at the start of the post. I’m afraid it’s been a long time since I worked on this though, so I don’t have a final version to post…
Shaun