JDK6 Web start Cache location

8 October 2007, by: development

For a web start deployment of an application it is sometimes
necessary to be able to get the location of the cached and downloaded
jar files which come with the web start deployed application.

I needed to be able to specify some files to the external javac class path
to compile some dynamically generated jasper reports on the client side.

There are a lot of forum topics about this, but no copy-paste solution.
So even with a "year behind" policy on the java jvm I had to fix
this by myself :P 

The jdk6 broke this because they updated the JNLPClassLoader in jdk6
to extend the URLClassLoader which is hooked to the java cache api.
This is all nicely explained at:

http://java.sun.com/developer/community/askxprt/2006/jl0410.html

But now the URL to the jar files returned from the  JNLPClassLoader are URLs
pointing to the external http location.
In jdk5 these were pointing to the cached version on the  filesystem.

To get the cached version of the files in jdk6 we use a JarURLConnection to get
the jar file from the URL, The jar file returned is cache entry of the already
downloaded file, but its name is not preserved by the cache.
It is something like "~/.java/deployment/cache/6.0/55/65eff4b7-3af949f2"
So we copy it to an temp file which has an jar suffix and we are good to go
to include it in a class path.

I hope this will help some other wondering developers which are still in
need for a workaround, below is the full code version;

 /**

 * Fix jasper compling class path.

 * This is needed for webstart, because then the jvm classpath doesn’t contrain the client libs.

 * @throws Exception

 */

private void setJasperBuildPath() throws Exception {

String reportBuildPath = “”;

 // All jars have an manifest

   Enumeration<URL> e2 = Thread.currentThread().getContextClassLoader().getResources(“META-INF/MANIFEST.MF”);

   while(e2.hasMoreElements()) {

 URL u = e2.nextElement();

 String urlString = u.toExternalForm();

 

 // only do needed libs

 if (!(urlString.indexOf(“jasper”)>0 | urlString.indexOf(“itext”)>0 | urlString.indexOf(“showplanner-1″)>0)) {

  continue;

 }

 

 // index of .jar because the resource is behind it; “foo.jar!META-INF/MANIFEST.MF”

 int jarIndex = urlString.lastIndexOf(“.jar”);

 

 // skip non jar code

 if (jarIndex<1) {

  continue;

 }

 

 String jarLocation = null;

 if (urlString.startsWith(“jar:file:”)) {

  // jdk5 webstart cache AND development

  jarLocation = urlString.substring(4,jarIndex+4);    

 } else {

  // jdk6, uses java caching api in urlclassloader which is extended by the jndiclassloader in jdk6

  // we should get the same file from the cache, we copy because of classpath needs .jar suffix

  JarFile cachedFile = ((JarURLConnection)u.openConnection()).getJarFile();

  File tempFile = File.createTempFile(“cached-”, “.jar”);

  tempFile.deleteOnExit();

  copyFile(new File(cachedFile.getName()),tempFile);

  jarLocation = “file:”+tempFile.getAbsolutePath();

 }

 reportBuildPath+=jarLocation+File.pathSeparator;

 logger.info(“Adding to report compile path: “+jarLocation+” made from: “+urlString);

}

   System.setProperty(“jasper.reports.compile.class.path”,reportBuildPath);

   logger.finer(“Set japser com: “+reportBuildPath);

}

private void copyFile(File in, File out) throws Exception {

   FileChannel sourceChannel = new FileInputStream(in).getChannel();

   FileChannel destinationChannel = new FileOutputStream(out).getChannel();

   sourceChannel.transferTo(0, sourceChannel.size(), destinationChannel);

   sourceChannel.close();

   destinationChannel.close();

}

 

 Willem Cazander

 M4N.NL

3 Comments on “JDK6 Web start Cache location”

  1. Anon says:

    You don’t have to compile your JasperReports reports every time , you can load the compiled reports instead, take a look at the API

  2. Willem says:

    I know, we used the ant task in the past.
    But this time i needed dynamic reports so there are build with the ‘Design’ objects in the JasperReports api.

  3. dayna says:

    I shop quite a lot so I am going to get a rewards credit card. I hope to save some money with rebates. I just want to make sure that there aren’t any hidden pitfalls in the terms and conditions. I would really appreciate your help with that. I’m looking at the deals at

    low transfer card rates

Type your comment below:

best counter