tschulte / gradle-jnlp-plugin

Gradle plugin to generate jnlp files, sign jars etc. for being able to start an application with Java Webstart
Apache License 2.0
20 stars 7 forks source link

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

Open mauromol opened 7 years ago

mauromol commented 7 years ago

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.

tschulte commented 7 years ago

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.

mauromol commented 7 years ago

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?

tschulte commented 7 years ago

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.

tschulte commented 7 years ago

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.

mauromol commented 7 years ago

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 https://github.com/tschulte/gradle-jnlp-plugin/issues/45#issuecomment-320207408, 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.

tschulte commented 7 years ago

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.

tschulte commented 7 years ago

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.