Java Doodle: crossdomain.xml Support

While we wait for the full JavaFX SDK to be released later this summer I'd like to show you some cool desktop Java things that you can do right now. This is the first in a series I'm going to call Java Doodles, highlighting the new features in JavaSE 6 update 10, now in beta. Join me over the coming weeks when we will explore more cool things you can do with desktop Java.

A photo applet

archive="http://projects.joshy.org/demos/PhotoStrip/webstart/PhotoStrip.jar" width="400" height="200" >

Above is a simple applet which loads the most recent photos from my Flickr stream. It's a very simple pure Java applet that's only 8k in size. This applet isn't interesting for what it does, but rather what for what it doesn't do. If you have JavaSE 6 update 10 then you won't see a security warning dialog, even though it's hosted on my personal server (not java.net) and it's connecting to Flickr.com. How this this possible?

The applet security model, known as the sandbox, only lets applets connect to the webserver they were loaded from. They cannot connect to anywhere else unless they are signed. Signing is great when you need access to more than what is allowed inside the sandbox, but it has two problems: the user will receive an ugly warning dialog about the applet, and the applet will have full access to the user's computer. Full access is overkill when all you want to do is talk to a webservice on another server. Surely there is some middle ground between the sandbox and full access? Well now there is.

crossdomain.xml support

If the server hosting a webservice has special xml file on it then the applet plugin will allow connections to that server. This special file is called a crossdomain.xml file and it must be present on the exact subdomain hosting the webservice. Here is the crossdomain.xml file for the Flickr server hosting the images:

<?xml version="1.0"?>
<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
<cross-domain-policy>
  <allow-access-from domain="*" />
</cross-domain-policy>

Because Flickr wants people to build apps which connect to their webservices they have put a crossdomain.xml file on all of their domains which host webservices. The crossdomain.xml mechanism was originally designed for Flash applications, but with JavaSE 6 update 10 now Java apps can take advantage of these services too!

Degrading gracefully

So what happens if you don't have update 10? In a plain applet the connection to static.flickr.com would throw a security access exception. The applet has to be signed for that to work, but we don't want the applet to be signed in the update 10 case. The key to degrading gracefully is to have two sets of jars, one signed and the other unsigned, and use the new JNLP support to specify the update 10 version, falling back to the classic applet classpath for older JVMs. Here's how it works. In my webpage I put this applet tag:

<div id="applet">
    <applet code="photostrip.Applet"
            archive="http://projects.joshy.org/demos/PhotoStrip/webstart/PhotoStrip.jar"
            width="400" height="200"
            >
        <param name="jnlp_href" value="http://projects.joshy.org/demos/PhotoStrip/photostrip.jnlp">
        <param name="flickruser" value="31706743@N00"/>
        <param name="size" value="100"/>
        <param name="cols" value="4"/>
        <param name="rows" value="2"/>
    </applet>
</div>

then in the photostrip.jnlp file I put this

<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="" href="">
    <information>
        <title>PhotoStrip</title>
        <vendor>Joshua Marinacci</vendor>
        <offline-allowed />
    </information>
    <resources>
        <j2se version="1.5+" href="http://java.sun.com/products/autodl/j2se" />
        <jar href="unsigned/PhotoStrip.jar" main="true" />
        <!-- Application Resources -->
    </resources>
  <applet-desc 
      name="PhotoStrip"
      main-class="photostrip.Applet"
      width="400"
      height="200">
  </applet-desc>
</jnlp>

The applet tag version uses the signed jar in the webstart directory. The JNLP version uses the unsigned jar in the unsigned directory. New JREs will use JNLP version without a warning dialog. Older JREs will use the applet tag version with the warning dialog. Using this simple method you can degrade gracefully in older JREs and browsers. In fact, you don't have to use this technique just for signing issues. The two jars could point to different versions of the app that turn on and off any of the other new JavaSE 6 update 10 features.

Going forward

With crossdomain.xml support in Java now all sorts of mashups become possible in applets without any jar signing at all. Here are a few other sites with crossdomain.xml supported webservices that you could connect to and do interesting things with.

For more information on crossdomain.xml support in JavaSE 6 update 10 see these references:

Source

Here is the source to the PhotoStrip application. You also need this bin directory which includes some extra Ant tasks for packaging.

Talk to me about it on Twitter

Posted May 28th, 2008

Tagged: java.net