I just do not get it!
How are we to be able to build and deploy WS Applications on different customer sites in the future?
We have a scenario where we launch a WS Client that communicates with our server. We need to pass (at least) parameters for communication details via the JNLP file,
Currently we trust on a homebrew JNLP servlet that injects different settings into the requested JNLP file.
So far this has been working just fine, but as of Java 7 it has been more and more difficult and from u45 stopped working entirely.
I read all about the new security "features" and have been fighting for hours and hours to follow all new guidelines...
Properties must have a "jnlp." prefix, check! (Just duplicate the properties on the client without the silly prefix)
Permissions manifest-attribute, check!
Codebase manifest-attribute, check!
Application-name manifest-attribute, check!
Trusted-Library manifest-attribute, check! (Hmm didn't work out that well did it)
OK less warnings about our own stuff, nice!
Manifest attributes in all the library jar files....who do I call?
Warnings, warnings, warnings....alright, never mind. I'll just tell my customers to ignore them.
Signed JNLP file, hmm... kinda hard for a dynamic one right?
Signed JNLP using APPLICATION_TEMLPLATE, well yeah, it must match the actual JNLP file exactly except for the code base...or where did I go wrong?
How did you guys think?
Even if I missed out on some details about the template pattern and it actually is possible to pass dynamic parameters via the JNLP file, I can't even come up with an idea how to set up a descent build environment, currently using Maven 2....with dependencies, yeah they might change! And I even change my own version number sometimes.
So I figure I need to generate the APPLICATION_TEMPLATE from a stub, based on dependencies from my main jar and at the SAME TIME put that very template back into the main jar and then sign it.
You can use wildcards (*) in the APPLICATION_TEMPLATE.JNLP for the codebase, arguments passed etc, most attributes, etc.
main requirement is that it matches the structure of the JNLP you generate at runtime.
See an example in this post: https://forums.oracle.com/thread/2594055
Still, you'd probably have to assign number of placeholder <jar> tags for the number of dependencies you have. Or generate this part of the file in your build.
Or in our case, we mash all dependencies into one uber-jar dependency. Then we have complete control over the MANIFEST attributes, etc.
BUT you cannot use wildcards for properties...that just seems absolutely crazy, as that is part of what makes our application's deployment "dynamic"...
<property name="jnlp.some.property" value="*"/>
That won't work, I have to include the exact same value in the property name as my jnlp which was dynamically created at install time...and of course I can't bundle my CA signer inside my installer and bundle the actual jnlp in the jar and sign it, that would just render my signing and jar/jnlp security useless.
So I guess 2 questions for me...
1) Will oracle make this useful?
2) If not, is there some other way to accomplish this, specifically our customers don't like warnings of any type...the other side of this is I do need to have installation specific properties passed to the VM (that I had to change to jnlp* format)
What you can do is to change the JNLP and use dynamic arguments instead of dynamic properties because <argument>*</argument> is allowed.
This way I´ve changed our app this morning and instead of System.getProperty in the code you must parse the command line args in the main method (check out commons-cli for parsing).
I think the intention of this change was to increase the security of "system properties" java uses. I guess most of the people out there using dynamically generated jnlp files used the property mechanism because it´s easier than parsing command line args (me too) :-)
I was really frustrated with the changes Oracle did but happy now that it´s working again changing a little bit the app.
Hope this helps.
Thank you all for your advice.
I actually implemented both things in this way...
We had a multi module Maven project with two major modules, the server-module and the swing-module.
I added a jnlp-module, that contains the two jnlp-templates I need, the APPLICATION_TEMPLATE.JNLP and the template I use for the dynamic stuff. I also put my dynamic jnlp servlet class in here as well.
Using the standard maven resources tag I modify both templates to inject the project version number as file name suffix on the two jars I now use.
(I replaced all properties by arguments, and then to avoid a lot of code changes I just put the lot of them into System properties in my main client method, first thing.)
Then I added this jnlp-module as a dependency in both the swing-module and the server-module.
In the swing module I use the maven-shade-plugin to create two uber jar files, complete with the correct meta tags, one containing my own stuff and one containing all external dependencies, both with the project version as name suffix.
In the server war module I copy the two uber jars to my jnlp/lib folder and sign them.
Happy to share more details.
Thanks chummer, that worked for me on properties and JNLP template (using them as arguments instead).....
Another question though with the jnlp only passing the "secure" properties to the client VM...
java.util.prefs.PreferencesFactory is not "secure"...but, it is my understanding that, if using your own custom PreferencesFactory (which our application does, and has for years), this property has to be passed in as a -D to the VM....but if the jnlp is still not passing it, is there anyway to do this in Webstart?
I've been fighting all day with these new "features" as well, even if we use our applications in intranet only. As I read through this thread I can see only workarounds / hacks to the real problems and not really future proofed solutions. To me two major problems remain open:
1) how to handle 3rd party jars - the fact is that we don't have / want to have control over 3rd party jars, so to put fix security declarations within the jar file itself is very poor solutions. This will mean, that if I'd use commons-lang in two different applications with different security settings I have to provide two "different versions" of this lib only because of the security declarations in the manifest?
2) how to handle dynamic jnlps - the template proposal is not so useful as it seems, because important parts are locked for changes. Moreover the specification states that what is locked is up to the vendor of the JWS client, ending that some applications may be broken on different vendor JVMs! I didn't find any list, what is black-listed in the Oracle's WS implementation yet.
Sorry to repeat the original question once again, but I think we need really answers to these questions to provide stable and most important future proofed solutions and not to be surprised on each JRE update with security popups and broken applications.
Any answers / clarifications will be much appreciated!