tschulte/gradle-jnlp-plugin

Provide some basic documentation of jnlp-war plugins and your JnlpDownloadServlet

mauromol opened this issue · 7 comments

Thanks for the great jnlp plugin!

By making a search on https://plugins.gradle.org/, I discovered you also provide a jnlp-war plugin. Looking at the source code, I think I understand it's meant to provide support for multiple versions of JNLP files and JARDiff patches and also adds your own version of JnlpDownloadServlet to the project runtime dependencies.

I could not find any example on how to use the whole thing in the examples directory (forgive me if I'm wrong). Also, it's not evident to me what your JnlpDownloadServlet offers compared to the one provided by the standard JDK sample package.

Please see my comment in #45.

The JnlpDownloadServlet is a complete rewrite of the functionality (without using the code) of the sample provided in the JDK.

I used a newer servlet spec (3.1.0) which made some things easier. And I moved some aspects to the gradle plugin to make the servlet more lightweight.

  • Jardiffs are created by gradle (they are generated by the sample jnlp-servlet at runtime, making the servlet more complex)
  • pack200 support is handled by gradle, only the pack200 file is contained in the war, and only that is delivered. No check if pack200 is supported by the client. I don't think there exists any webstart client that can not handle pack200.
  • more I don't remember at the moment

Very interesting, also because the standard JnlpDownloadServlet is not available through Maven and, if you use the provided binaries, there are no debug information.

I also experienced problems with the standard JnlpDownloadServlet if you disable the "versioning" feature (i.e.: use plain JAR names in the jar elements href attributes with no version attribute): downloading of JARs with static URLs simply fails with a 404 error. Does your servlet also fixes this?

The standard JnlpDownloadServlet was made available by the maven webstart plugin: http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.mojo%22%20AND%20a%3A%22webstart-jnlp-servlet%22

My Servlet tries to locate the requested resource. If a version-id parameter is given (that's what the webstart client does), it will use that (e.g. http://localhost/ria/lib/ria.jar?version-id=1.0.0 results in lib/ria__V1.0.0.jar). But you can also directly request that version (e.g. http://localhost/ria/lib/ria__V1.0.0.jar).

When using useVersions = false, the jnlp will not create version attributes in the jnlp file. Intead it will directly use __V1.0.0.jar in the href attribute.

But since the jar is stored as __V1.0.0.jar in the war file, you cannot request it without any version information (either by using ?version-id=1.0.0 or by requesting __V1.0.0.jar).

When you have started version 1.0.0 of your ria, and then upgrade to version 1.1.0, the webstart client will request http://localhost/ria/lib/ria.jar?version-id=1.1.0&current-version-id=1.0.0. In that case the JnlpServlet will simply check, if a file lib/ria__V1.0.0__V1.1.0.diff.jar.pack.gz is available, if that is not available, it will check if lib/ria__V1.0.0__V1.1.0.diff.jar is available, if that is not available, it will check if lib/ria__V1.1.0.jar.pack.gz is available, if that is not available, it will check if lib/ria__V1.1.0.jar is available. If none of that files is available, it will send a HTTP 404.

The jnlp-war plugin will add the __V1.0.0__v1.1.0.jar.pack.gz or __V1.0.0__V1.1.0.jar file if configured accordingly.

When you have a clean java webstart cache, the webstart client will only request http://localhost/ria/lib/ria.jar?version-id=1.1.0, and the servlet will skip the first two checks for the diff-files.

Oh, I forgot. My servlet will always deliver the .pack.gz if the jar file is not in the war. I.e. When the war contains only the .pack.gz files (usePack200 = true, which is the default), you cannot request the jar file directly. If you request http://localhost/ria/lib/ria.jar?version-id=1.1.0 or http://localhost/ria/lib/ria__V1.1.0.jar, the servlet will always deliver the pack.gz file and set the http header accordingly. This is because the servlet is designed to be used by the webstart client only, and all webstart clients IMO support pack200 and so I did not implement a check for the corresponding http request header to simplify the servlet.

The standard JnlpDownloadServlet was made available by the maven webstart plugin: http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.codehaus.mojo%22%20AND%20a%3A%22webstart-jnlp-servlet%22

I saw that artifact but I was not sure about the versioning policy. Also, I'm using the default JnlpDownloadServlet taken from Java 8 samples, although I didn't check whether there is any difference from the one in the Java 7 samples.

But you can also directly request that version (e.g. http://localhost/ria/lib/ria__V1.0.0.jar).

So, this seems to be an improvement over the default JnlpDownloadServlet, since as I wrote in #45 (comment), that one seems to produce 404 errors when direct requests for http://localhost/ria/lib/ria__V1.0.0.jar are made...

When using useVersions = false, the jnlp will not create version attributes in the jnlp file. Intead it will directly use __V1.0.0.jar in the href attribute.
But since the jar is stored as __V1.0.0.jar in the war file, you cannot request it without any version information (either by using ?version-id=1.0.0 or by requesting __V1.0.0.jar).

This is clear. The problem is that, in my experience, the latter technique (requesting __V1.0.0.jar directly) does not seem to work with the default JnlpDownloadServlet. I could not debug it thoroughly because of the lack of debug information, though.

I remember having had multiple issues with the JnlpDownloadServlet. And the code of the JnlpDownloadServlet is rather complex. That was the main reason to start from scratch. E.g. the JnlpDownloadServlet allows either using file name convention (__V1.0.0.jar) or alternatively a versions.xml file. I went with just the file name convention to make things simpler.

Just found a text I posted on the maven webstart mailing list: http://mojo.10943.n7.nabble.com/Webstart-JnlpDownloadServlet-Jardiff-and-Pack200-td47548.html

I apparently wrote that text before implementing my own Servlet. Replacement of $$name etc. ended up in a Servlet Filter.