One of the weird things I ran into when I first started trying to get JRubyFX to work with JavaFX‘s packaging tools, was that the packager would create these WebStart files and no matter what I tried, I couldn’t seem to get them working. Usually there was no error message, or something very cryptic.
I knew people had gotten JRuby apps working with WebStart before, so I didn’t think it would be impossible to accomplish, but ultimately went with a strategy of just removing the WebStart files after they were generated, as part of JRubyFX’s build task.
But I was persistent. What I ultimately hit upon was this article from March 2008, which mentioned that because JRuby uses reflection internally, the .jar had to be signed, and the .jnlp needed a setting requesting a higher level of security.
The next problem I ran into was that the webstart files created by the javafx packager make sure that there is a copy of the JavaFX library available for the application to use. JRubyFX apps need that library too, of course, but when I tried just signing the jar and then adding the extra lines about security to the packager’s .jnlp file, it still didn’t work. Instead, I got a new error telling me that the main-class could not be cast to javafx.application.Application.
This made sense, and so after some abortive attempts at launching the JRubyFX app from a small JavaFX app, I figured out which part of the .jnlp file ensured that the JavaFX libraries were available, and which part was trying to launch the app as if it was a JavaFX application. Finally, I wrote my own .jnlp file, based on other working WebStart JRuby apps, plus the code to get the JavaFX library, and PRESTO! One working JRubyFX WebStart app.
Let’s write a small sample JRubyFX app, build it into a jar, and then create the WebStart files to launch it.
First create a new project directory, change into it, and create a src dir inside:
mkdir HelloWebStartÂ
cd HelloWebStartÂ
mkdir src
Now create a new file inside the src directory, hello.rb, and open it in your favorite editor:
From the main HelloWebStart directory, build an executable jar using the jrubyfx-jarify tool:
jrubyfx-jarify src --main src/hello.rb hello.jar
Now we are going to sign our jar, using java’s tools for this purpose, you can read more about that both in this article and the Java tutorial on generating keys:
keytool -genkey -keystore myKeystore -alias myself
This will prompt you with a number of questions, just be sure to remember the passwords you give it. Next we self-certify:
keytool -selfcert -alias myself -keystore myKeystore
This will ask you for that password, so I hope you remember what it was!
Next we sign our jar, again you’ll be prompted for your password:
jarsigner -keystore myKeystore hello.jar myself
If you execute the jar with java -jar hello.jar you should see:
Now we need to create the jnlp file, which is what will launch the app. In the main HelloWebStart directory, where your jar file is, create the file hello.jnlp.
You can read all about WebStart and jnlp on Oracle’s WebStart Deployment Tutorials page, but let’s go over some of this.
The jnlp file is XML, so normal XML syntax rules apply. In the jnlp tag we have a few attributes. First, we set up the “jfx” namespace. Next we leave codebase as an empty string, because we are running this from our own computer, but if we were hosting this on the internet, codebase would be a url indicating the directory that held the jnlp file. For example, if you download the WebStart JNLP file from the JRuby Homepage’s Try Jruby example, and open it with your text editor, you’ll see their jnlp tag looks like:
<jnlp codebase="http://jruby.org/tryjruby" href="irb.jnlp" spec="1.0+">
The codebase, combined with the href, provides the full url to the jnlp file, which in that case is http://jruby.org/tryjruby/irb.jnlp.
The information tag and its elements is important, so don’t leave it completely blank, as Java uses that information in the dialogs it displays to the user. “offline-allowed” instructs java to allow the program to run, once its been downloaded, even if the user doesn’t have an internet connection. That’s because with WebStart it’s even possible for us to allow the user to create a desktop shortcut and run our application whenever they want.
Next comes a very important part. The security tag, and its enclosed all-permissions is what tells Java to expect a signed jar, and to request the additional security permissions we need in order for JRuby to do its internal reflection thing.
There are two resources tags. The first uses that “jfx” namespace we created earlier to ensure the user has an available and up-to-date copy of the JavaFX library. This is also very important. The second checks for the Java Run Time, and then downloads our executable jar. Normally, if we had this on a server, the href attribute inside the jar tag would be a url pointing to our jar. To look at the Try JRuby example again, their jnlp uses this tag:
<jar eager="true" href="http://jruby.org.s3.amazonaws.com/tryjruby/jruby-complete-signed.jar" main="true"/>
In this case, since we are running this on our own machine, we need an absolute path to the jar file’s location. On my Ubuntu 12.04 machine, with the jar in the location I have it in, /home/eric/projects/jrubyfx_projects/test/HelloWebStart/hello.jar works. Similar is likely to work on OSX, though I cannot be sure. On Windows, you will need to experiment a bit and find what works.
Finally, application-desc tells java which file inside the jar is the class to launch the application. As long as we are using the jrubyfx-jarify tool, it should always be “org.jruby.JarBootstrapMain”.
If you got all this correct, and you double click on hello.jnlp you should see a java splash screen followed by a dialog like this:
This is requesting those permissions we’ve discussed. It’s unfortunate, but there is just no way at present to get around this. If you check the box, the disabled “Run” button will become enabled, and your app should start up.
If double-clicking the file did nothing, or just reopened the file in your text editor, you can execute it to test it from the command line with:
javaws hello.jnlp
Now, we want to see WebStart working from a web page, of course, so let’s set up a very simple web page that will let us download the jnlp file and run our app that way. Create hello.html and open it up.
This is just an extremely simply web page with a little javascript to create a launch button that points to our jnlp file. It should also be completely possible to have the webstart app open up inside the browser, using a combination of javascript and java, but that is far beyond the scope of this tutorial. Make sure that hello.html, hello.jnlp and hello.jar are all in the same directory and double-click on hello.html to open it in your browser. If you did everything correctly, you should see the following:
Clicking on either the link, or the launch button, should download the jnlp file which you can run. After verifying the security dialog again, your app should begin to run!
I can’t wait to hear your success stories in the comments below, along with any suggestions or criticism. I hope this was helpful, and keep building cool stuff.

Recent Comments