Problems with Java web start when upgrading to j7u45
As you can guess from the title, the post will be dedicated to the security update released by Java, which will probably break / break the launch of the web start application. All are not indifferent - I ask for a cat.
Our company has adopted the practice of updating Java on all servers as soon as new versions are released. Actually, this is what we did this time. But something went wrong, the web start client stopped running and the application, without declaring war, just started to close.
Rolling up her sleeves, I had to figure out what caused this behavior.
By launching the client locally, previously unknown warnings appeared that the manifest files were missing properties: Permissions, Application-Name, Codebase. After reading a little about them, as a test, it was decided to add them to the fool in all manifests, approximately in the following form:
Not too beautiful, it got rid of warnings, but did not solve the problem.
Further, during long debugs (thank you Eclipse RCP for a happy childhood), it was noticed that the system parameters were somehow transferred incorrectly, which led to the next post on stackoverflow: stackoverflow.com/questions/19400725/with-java-update- 7-45-the-system-properties-no-more-set-from-jnlp-tag-property .
Summarizing it, we can say that now you can’t just take it and transfer it to the JNLP file.
3 solutions were found:
1) Sign the JNLP file - docs.oracle.com/javase/7/docs/technotes/guides/jweb/signedJNLP.html#signedJnlp - in short - just put jnlp in the signed dzharik in the JNLP-INF folder with named APPLICATION.JNLP and there will be happiness.
The main problem with this method was that we have different JNLPs for each client and, generally speaking, are generated on the fly.
2) Create a signed JNLP file template - blogs.oracle.com/thejavatutorials/entry/signing_jar_files_with_a
Initially, I settled on this method, nothing complicated: the same as in the previous paragraph, only the file name APPLICATION_TEMPLATE.JNLP and those places that can change replace with '*'.
But everything turned out not so rosy, nothing worked. I had to shamanize a bit and get into the inside of the web start to see how the template and the jnlp file are compared. As a result, the following code was discovered in com.sun.javaws.jnl.XMLFormat:
It checks something like this: when comparing a template with a file, it looks to see if the current tag is in the black list, if so, it does not skip such a jnlp file. In the current implementation, you cannot add templates to the java-vm-args property of java or j2se tags, and you cannot pass parameters containing a template to the value.
And again a failure, many properties for each client are unique and are transmitted just through the parameters in the form:
And we can’t just write in the template:
Only the last option (at that time) remains:
3) According to bugs.openjdk.java.net/browse/JDK-8023821 , properties can be transferred by adding the prefix 'jnlp' to them, they will be successfully transferred to system properties and further in our code it will be possible to shift them to their place. Since no other alternative was found, the code found here was added at the very beginning of the application launch :
Our company has adopted the practice of updating Java on all servers as soon as new versions are released. Actually, this is what we did this time. But something went wrong, the web start client stopped running and the application, without declaring war, just started to close.
Rolling up her sleeves, I had to figure out what caused this behavior.
By launching the client locally, previously unknown warnings appeared that the manifest files were missing properties: Permissions, Application-Name, Codebase. After reading a little about them, as a test, it was decided to add them to the fool in all manifests, approximately in the following form:
Permissions: all-permissions
Application-Name: AppName
Codebase: *
Not too beautiful, it got rid of warnings, but did not solve the problem.
Further, during long debugs (thank you Eclipse RCP for a happy childhood), it was noticed that the system parameters were somehow transferred incorrectly, which led to the next post on stackoverflow: stackoverflow.com/questions/19400725/with-java-update- 7-45-the-system-properties-no-more-set-from-jnlp-tag-property .
Summarizing it, we can say that now you can’t just take it and transfer it to the JNLP file.
3 solutions were found:
1) Sign the JNLP file - docs.oracle.com/javase/7/docs/technotes/guides/jweb/signedJNLP.html#signedJnlp - in short - just put jnlp in the signed dzharik in the JNLP-INF folder with named APPLICATION.JNLP and there will be happiness.
The main problem with this method was that we have different JNLPs for each client and, generally speaking, are generated on the fly.
2) Create a signed JNLP file template - blogs.oracle.com/thejavatutorials/entry/signing_jar_files_with_a
Initially, I settled on this method, nothing complicated: the same as in the previous paragraph, only the file name APPLICATION_TEMPLATE.JNLP and those places that can change replace with '*'.
But everything turned out not so rosy, nothing worked. I had to shamanize a bit and get into the inside of the web start to see how the template and the jnlp file are compared. As a result, the following code was discovered in com.sun.javaws.jnl.XMLFormat:
public static boolean isBlacklisted(XMLNode paramXMLNode)
{
if (paramXMLNode == null) {
return false;
}
if (paramXMLNode.getName() != null)
{
XMLAttribute localXMLAttribute;
String str;
if ((paramXMLNode.getName().equals("java")) || (paramXMLNode.getName().equals("j2se"))) {
for (localXMLAttribute = paramXMLNode.getAttributes(); localXMLAttribute != null; localXMLAttribute = localXMLAttribute.getNext()) {
if (localXMLAttribute.getName().equals("java-vm-args"))
{
str = localXMLAttribute.getValue();
if ((str != null) && (str.indexOf("*") >= 0))
{
Trace.println("Blacklisted - a = " + localXMLAttribute, TraceLevel.SECURITY);
return true;
}
}
}
} else if (paramXMLNode.getName().equals("property")) {
for (localXMLAttribute = paramXMLNode.getAttributes(); localXMLAttribute != null; localXMLAttribute = localXMLAttribute.getNext())
{
str = localXMLAttribute.getValue();
if ((str != null) && (str.indexOf("*") >= 0))
{
Trace.println("Blacklisted - a = " + localXMLAttribute, TraceLevel.SECURITY);
return true;
}
}
}
}
if (isBlacklisted(paramXMLNode.getNested())) {
return true;
}
return isBlacklisted(paramXMLNode.getNext());
}
It checks something like this: when comparing a template with a file, it looks to see if the current tag is in the black list, if so, it does not skip such a jnlp file. In the current implementation, you cannot add templates to the java-vm-args property of java or j2se tags, and you cannot pass parameters containing a template to the value.
And again a failure, many properties for each client are unique and are transmitted just through the parameters in the form:
And we can’t just write in the template:
Only the last option (at that time) remains:
3) According to bugs.openjdk.java.net/browse/JDK-8023821 , properties can be transferred by adding the prefix 'jnlp' to them, they will be successfully transferred to system properties and further in our code it will be possible to shift them to their place. Since no other alternative was found, the code found here was added at the very beginning of the application launch :
private static void initializeSystemProperiesFromJnlp() {
//Hack for not signing JNLP file
Properties properties = System.getProperties();
// copy properties to avoid ConcurrentModificationException
Properties copiedProperties = new Properties();
copiedProperties.putAll(properties);
Set