On both counts, your application will need to add some trivial code to be executed at start-up, in order to work around these two issues.
Wildcards Not Allowed in Property Values
The JNLP specification says:
It is expected that a JNLP Client will blacklist (or restrict) certain jnlp elements and argument values such as "java-vm-args" or property "name" and "value" to maintain security. The exact list is up to the individual JNLP Client implementations.
In fact, the Oracle implementation (at least in 7u45) does blacklist the value
attribute of the <property/>
element -- it cannot be wildcarded. I've been unable to locate any reasoning behind this decision, but there it is.
The webstart work-around allows arbitrary property names as well as values; the applet work-around requires that the names of the properties be known at code-signing time.
Work-around: Webstart
In your JNLP file, include a number of wildcard arguments:
<application-desc main-class="com.example.YourMainClass">
<argument>*</argument>
<argument>*</argument>
</application-desc>
In your application's main
method, parse these arguments and copy them in to system properties using System.setProperty()
, skipping over arguments that still have the literal value "*"
. I recommend simply splitting each argument on the first occurrence of "="
. (If your application already takes regular arguments as well, you'll have to get a bit more creative.)
Work-around: Applet
In your JNLP file, include parameters defining the system properties that need to be set:
<applet-desc main-class="com.example.YourMainClassApplet">
<param name="SYS_PROPERTY_PARAMETERS" value="prop1,prop2"/>
<param name="prop1" value="*"/>
<param name="prop2" value="*"/>
</applet-desc>
In your Applet.init()
method, get the value of the SYS_PROPERTY_PARAMETERS
parameter, and iterate over it to get the value of each parameter. If it is not the literal "*"
, copy it to a system property using System.setProperty()
.
"Insecure Operation" dialog
This is a bug in the Oracle plugin that is triggered by the use of LiveConnect (Java <-> JavaScript interaction).
Work-around: "secure" property prefixes
Prefix all system properties set via <property/>
elements in the JNLP with "jnlp."
:
<property name="jnlp.my-prop" value="fixed-value"/>
Then in your application's main()
or Applet.init()
method, iterate over a copy of System.getProperties()
and, if the property name starts with "jnlp."
, copy its value into a property of the same name with that prefix stripped off. (Iterating over the copy is necessary to avoid a ConcurrentModificationException
.)
Gotcha: JNLP template validator considers order of XML attributes
Finally, if your process of filling in the values for the properties could cause attributes of other elements in the JNLP document to be reordered, this may cause the JNLP template validation to fail. (Parsing the JNLP with a DOM parser, filling in the wildcards, and streaming it back out using StreamResult
is one way this could happen.) For example, I had these two multi-attribute elements, and the order of the elements had to match:
<jnlp codebase="*" spec="1.0+">
<j2se java-vm-args="-Xms256M -Xmx512M -XX:MaxPermSize=256m" version="1.6+"/>