How can I pass arbitrary system properties whose values may change to a signed Java RIA (applet, webstart) via JNLP?

孤者浪人 提交于 2019-11-29 11:41:33

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+"/>
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!