JNLP does not auto updating JAR file - java

I am working in a such environment, where we have to update client jar in every 2 months maximum. So, as a solution I am suggesting to use JNLP by using this approach we do not have to worry that every user is using the latest release or not. As, There are more then 100 clients per department.
But the problem is JNLP isn't upgrade the new jar file in the following is the my.jnlp file
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0+" codebase="http://192.168.1.26:8080/" href="Test.jnlp">
<information>
<title>HC</title>
<vendor>DRL</vendor>
<homepage href="http://192.168.1.26:8080/" />
<description>DRL</description>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="1.6+" />
<jar href="JnlpTest.jar" download="eager" />
</resources>
<application-desc
name="HC-DRL"
main-class="com.drl.simap.client.module.ui.Splash" />
</jnlp>
My working environment:
Tomcat-6.0 server and following tutorial
here

If you download the jnlp spec and look at chapter 6, there is a whole section about caching: "6 Downloading and Caching of Resources"
You can try to add a version number to your jar file and then use the jnlp jar version attribute.
If you currently don't do that, the spec states the following:
An entry downloaded using the basic download protocol must be located
in the cache based on the URL. The time stamp obtained from the HTTP
GET request in the Last-Modified header field of the reply should be
stored along with the downloaded resource. The time stamp is used to
determine if the copy on the server is newer.
The JNLP Client cannot assume that the HTTP GET request will return
the same JAR file for each request. The JNLP Client must periodically
check the Web server to see if an updated version is available. This
check is recommended to be performed before an application is
launched, but the exact algorithm used by a JNLP Client depends on the
particular implementation. For example, if a JNLP Client is offline,
the check is not required to be performed.
The above caching rules also apply to extension descriptors downloaded
using the extension download protocol where the version attribute is
not specified.

Related

How to use variables in JNLP arguments

Having the following sample jnlp:
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="$$codebase" href="$$name">
<information>
<title>Some Example</title>
<vendor>Some Sample Vendor</vendor>
<homepage href="http://www.somesamplevendorhomepage.com"/>
<description>Some Sample Description</description>
<icon kind="splash" href="link_to_some_splash.jpg"/>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<update check="always" policy="always"/>
<application-desc main-class="com.some.sample.Main">
<argument>--URL=SAMPLE_DB_NAME=http://localhost:<db_port>/webapplication/creds/auth</argument>
<argument>--UserTimeout=350</argument>
</application-desc>
<resources>
<j2se version="1.7+" />
<jar href="com.some.sample_1.0.0.jar"/>
.
.
.
</resources>
</jnlp>
(please ignore formatting or other inconsistencies - the only part that matters is the argument part)
Having the variable db_port within the argument tag, is there a way to pass a value to this variable when executing the jnlp with javaws?
For example: javaws /path/to/sample.jnlp 31022
EDIT:
JNLP downloads the JARs to the cache folder located (on Windows) under AppData\LocalLow\Sun\Java\Deployment\cache.
Is there a way to use the download JARs (my app has multiple JAR files) in order to have a way to execute the app providing the argument directly to the downloaded JAR?
For example:
jar -jar app.jar --URL=SAMPLE_DB_NAME=http://localhost:<db_port>/webapplication/creds/auth
PS: I understand that the files that are stored in the cache folder have a computed generated name and they are without the .jar extension.
However from the Java Control Panel GUI or from CMD/PS with "javaws -viewer" I was able to determine the file used as jnlp and launch it. I was wondering if there is a way to use some of the JARs to launch the app or maybe create a "parent" one in order to be able to pass arguments to it.
The documentation seems to be intentionally lacking on this topic, but the documentation suggests the preferred method to pass command line parameters to the javaws executable is through ‑userConfig flag.
e.g.
javaws /path/to/sample.jnlp -userConfig port 31022
The documentation doesn't provide examples for this. I even searched GitHub for javaws userConfig and only got a handful of results, so this seems to be a very rarely used feature.
Since your question specifically asks about a <port> variable contained within another variable, that is not something directly supported. You would instead need to find a way to wildcard or paramaterize the <port> using an additional variable and some search/replace inside the main class, assuming you have access to the source. If you don't have access to the source, you will be stuck writing the JNLP by hand, which can have additional work required if it's a signed file.

Webstart Security is Impossible. Trying to use with glassfhish 4

The end goal is to provide application client downloads using Java webstart from Glassfish 4.
I've been trying to get this working for 3 days, researching every method I can find and no matter what I try, webstart is blocked.
Exception list. Doesn't work.
Adding the certificate as a trusted certificate. Doesn't work.
Sandbox which doesn't need any permissions. Doesn't work.
Updating Java. Doesn't work.
I can't seem to find the deployment rule sets option but this sounds like something that needs full windows server integration etc.
There is no medium option in the Java console security settings as I am using java 8.0.31.
Simple test app that has nothing but static main void which prints a message to command line. Cannot get it to work...
It is starting to drive me crazy that it is impossible to develop anything using webstart, the only options I can see are purchasing a certificate for local development or totally dropping webstart...
How I added the certifacte to my machine - the certificate is shown in my Java console.
Here is the simple scenario I cannot get working:
package com.cbprogramming;
import javafx.application.Application;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
System.out.println("Test");
}
public static void main(String[] args) {
launch(args);
}
}
I then used IntelliJ Idea to create a JavaFX application that packages it including the webstart jar file, JNLP file and html web page including custom manifest fields for permissions: sandbox and codebase.
The JNLP file, I also tried with the security and permissions tags, both all-permissions and sandbox.
<?xml version="1.0" encoding="utf-8"?>
<jnlp spec="1.0" xmlns:jfx="http://javafx.com" href="WebstartTest.jnlp">
<information>
<title>Webstart Test</title>
<vendor>Testing</vendor>
<description>A Java Webstart testing app</description>
<offline-allowed/>
</information>
<resources>
<jfx:javafx-runtime version="8.0+" href="http://javadl.sun.com/webapps/download/GetFile/javafx-latest/windows-i586/javafx2.jnlp"/>
</resources>
<resources>
<j2se version="1.6+" href="http://java.sun.com/products/autodl/j2se"/>
<jar href="WebstartTest.jar" size="1190" download="eager" />
</resources>
<security>
<all-permissions/>
</security>
<applet-desc width="600" height="400" main-class="com.javafx.main.NoJavaFXFallback" name="WebstartTest" >
<param name="requiredFXVersion" value="8.0+"/>
</applet-desc>
<jfx:javafx-desc width="600" height="400" main-class="com.test.Main" name="WebstartTest" />
<update check="background"/>
</jnlp>
And the manifest file:
Manifest-Version: 1.0
permissions: sandbox
codebase: file:///d:/test/
JavaFX-Version: 8.0
Class-Path:
Created-By: JavaFX Packager
Main-Class: com.test.Main
Name: com/test/Main.class
SHA-256-Digest: 8BK5m/ojirCK/QEx8Oe+9z/L6P8JXin0CMDK4R2mkAI=
I have added the jnlp, jar and html files to the exceptions list, I've tried both with file:// and file:///, I've also tried adding the glassfhish URL to the exception list, http and https...
I am developing on a Win 8.1 pro machine using Jdk 8.0.31.
Every forum I have read users are saying any one of these options fix their problem. What am I doing so wrong?!? Is 8.0.31 broken? Or is webstart just not worth using?
Here is what I found incase others find it useful.
It looks like Glassfish 4.1 has a webstart bug when using Java 7 update 25 or later (currently 8.0.31). The workaround is to use an older version of Java.
I never could get the java console exceptions list to work.
Adding the certificate as trusted let webstart work from a local file/html file but it still didn't work through glassfish.
The tags needed to be removed from jnlp files now that they are in the jar manifest file or the application was blocked, these tags are added automaticlly by glassfish and intellij JavaFX packager.
Another thought is to setup a local certificate authority and add it as trusted through the java console - this way it isn't a self signed certificate.
Also, to get a glassfish application client debugging in IntelliJ:
Create a batch file: start "name" cmd /c "<installdir>\glassfish\bin\appclient.bat -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=5005 -client <dir>\TEMPSClient.jar"
Create a remote debugging configuration and set it to run the created script using the external tool in the before launch section.
This uses the default ports etc. for remote debugging, and will run the application jar in the glassfish client container before attaching the debugger to it. To get console output, redirect stdout and stderr to a log file and attach the log file to your remote debug configuration.
I first tried using the embedded ACC but couldn't get that working (copy/paste from docs has functions that don't even exist...). It would be great if someone knows of a good tutorial for using the embedded ACC.

With Java 7 Update 45, the System Properties no Longer Set from JNLP Tag "Property"

We run the application from the attached JNLP. On the Java console, we have output the system properties with D. The properties from our JNLP files are not set any more. This is the first Java version that we get this sort of problems with. Everything was working fine up to and including 7 Update 40.
We have all the jars signed but there are no security attributes in their manifests.
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://10.0.10.230/webstart/app" href="desktop.jnlp">
<information>
<title>MyApp Desktop</title>
<vendor>MyApp GmbH</vendor>
<homepage href="http://www.myres-edv.de"/>
<description>MyApp Desktop</description>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="1.5+" initial-heap-size="512M" max-heap-size="1024M" javaws-vm-args="-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8200"/>
<property name="org.omg.CORBA.ORBInitialHost" value="10.0.10.230"/>
<property name="org.omg.CORBA.ORBServerHost" value="10.0.10.230" />
<property name="sun.net.spi.nameservice.provider.1" value="dns,sun" />
<property name="MyApp.baktswritedos" value="true"/>
<property name="MyApp.nocomm" value="true"/>
<property name="MyApp.la.erfassungdos" value="true"/>
<property name="com.sun.corba.ee.transport.ORBTCPConnectTimeouts" value="500:30000:40:30000" />
<property name="deployment.trace.level" value="all" />
<jar href="myresjar/ejb/myres/myres_ejb_client.jar" main="true" download="eager"/>
<jar href="myresjar/ejb/myres/myres_ejb.jar" download="eager"/>
<extension name="jars" href="commonejbjars.jnlp"/>
<extension name="jars" href="jr.jnlp"/>
<extension name="jars" href="commonjars.jnlp"/>
<extension name="jars" href="commonjh.jnlp"/>
<nativelib href="myresjar/ejb/myres/myres_dll.jar"/>
</resources>
<resources os="Windows">
<nativelib href="myresjar/myres/native-dlls.jar" download="eager"/>
</resources>
<application-desc main-class="de.myapp.gui.desktop.mainframe.DesktopMainFrame">
<argument>-serverIP=10.0.0.230</argument>
<argument>-initNewDayAction=true</argument>
</application-desc>
</jnlp>
We experienced the same Problem with Java 7 Update 45 (1.7.0_45). The JNLP Spec gave a hint for a work-around:
Properties set in the jnlp file will normally be set by Java Web Start after the VM is started but before the application is invoked. Some properties are considered "secure" properties and can be passed as -Dkey=value arguments on the java invocation command line.
The following properties, as well as properties beginning with either "javaws." or "jnlp.", are considered "secure" and will be passed to the VM in this way:
...
While "insecure" properties stopped working, we realized that "secure" properties would still be set correctly.
Maybe the mechanism that sets properties after the VM is started but before the application is invoked, got broken with this Java update, or maybe this was an intentional but undocumented change.
The work-around now depends on the type of system properties:
For system properties that affect Java behavior or libraries, we changed our code to call System.setProperty() at the application start instead of setting them in the JNLP.
For properties that we use to configure the application from the JNLP file, we added the jnlp. prefix so that they are passed correctly again.
<property name="myconfig" value="DE" />
to
<property name="jnlp.myconfig" value="DE" />
Edit: According to OpenJDK Bug JDK-8023821, the change was intentional:
Starting from 7u45 launch descriptor (JNLP file) need to be signed in order to set insecure system properties. So it is expected behaviour in 7u45...
(from a comment)
Instructions for signing a JNLP.
We got bit badly by this same issue. We ended up going the route of including the JNLP file in the signed jar, but that presented some tricky build issues for us, because we had previously built one set of JARS and used multiple JNLP files to support different environments (QA, Production, Demo, etc), passing the environment details through to the app via a system property. We did try to make use of a JNLP template file as discussed here, http://docs.oracle.com/javase/7/docs/technotes/guides/jweb/security/signedJNLP.html, but we kept getting errors related to verifying the JNLP file and gave up due to time constraints. It's possible we were just doing something wrong, but the error messages did not make it at all clear what part of the JNLP file didn't match the template. Additionally, there is this somewhat unhelpful note in the link above that says: "Elements or attributes that may compromise security will be locked out from this feature." I could find no documented examples of such elements or attributes.
Had the same problem and solved it by signing the jnlp file. Your main jar should contain a copy of the jnlp file renamed as APPLICATION.JNLP and placed under JNLP-INF folder.(the name of the folder and jnlp file must be uppercase)
I set as:
<jnlp>
...
<application-desc main-class="Main">
<argument>param1=value1</argument>
</application-desc>
</jnlp>
Ps. Just be aware that passing values using tag you are passing application parameters and not JVM parameter. Your application should catch this parameter in your method main(String args[])
Just spent 2 days trying to fix this problem, trying to sign jars and other files...and then I found the solution which seems to be very simple and is working fine:
I *put a jndi.properties-file with the following content in my JRE-home-director*y (jre7/lib):
java.naming.factory.initial=org.jnp.interfaces.NamingContextFactory
java.naming.factory.url.pkgs=org.jboss.naming:org.jnp.interfaces
java.naming.provider.url=jnp://localhost:1099
I had this problem when updating from Java 1.6 to Java 1.7(51)...

Managing constantly-changing JNLP dependencies?

We use JNLP to deploy our Swing application to all of our users. With JNLP, you have to reference specific names/versions of any JAR dependencies, such as widget-lib-1.4.7.jar.
We have just introduced a new project that will compile as a reusable JAR, but that will be changing rapidly (every few days or so), and so the version number will change frequently. Our Swing app will depend on this new project once its completed.
Unless we change our setup, we'll have to update the JNLP and republish it every time we publish a new version of this new dependency, which, like I said, will be very frequent.
Is there any way to call Ivy from inside a JNLP, or some way of telling the JNLP to include the contents of a directory (and then have a separate process that always makes sure the latest version of the JAR is in that directory), or something we can do so that we don't have to constantly change the JNLP?
Thanks in advance!
If your JNLP is updated frequently (or needs any other per-user parameters, like upload keys), don't use a static file. Instead, create a template JNLP file with JSP, Velocity, Freemarker, or a similar template engine and fill in the JNLP's fields dynamically, such as from a database.
I'm not sure if this addresses your need, but you could use a second .jnlp for your frequently changing library. Your main application's .jnlp would refer to that .jnlp with an <extension> element.
Your main application's .jnlp would contain this:
<resources>
<j2se version="1.7+"/>
<jar href="MyApp.jar" main="true"/>
<extension name="WidgetLib" href="WidgetLib.jnlp"/>
</resources>
And WidgetLib.jnlp would look something like this:
<?xml version="1.0" encoding="UTF-8"?>
<jnlp href="WidgetLib.jnlp"
version="1.4.7"
codebase="http://www.company.com/myapp/">
<information>
<title>Widget Library</title>
<vendor>My Company</vendor>
<description>Latest version of Widget Library</description>
<offline-allowed/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<jar href="widget-lib-1.4.7.jar"/>
</resources>
<component-desc/>
</jnlp>

JNLP File Association: How do I open the file which was double-clicked on?

I've got the following JNLP:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE jnlp PUBLIC "-//Sun Microsystems, Inc//DTD JNLP Descriptor 6.0.10//EN" "http://java.sun.com/dtd/JNLP-6.0.10.dtd">
<jnlp spec="6.0.10" version="1.63" codebase="http://foo.example.com/msi" href="Foo.jnlp">
<information>
<title>Foo</title>
<vendor> Foo Systems, Inc.</vendor>
<homepage href="http://Foo.com"/>
<description>Foo Viewer/Editor Application</description>
<icon href="splash.gif" width="425" height="102" kind="splash"/>
<icon href="Foo.gif" width="64" height="64"/>
<offline-allowed/>
<shortcut>
<desktop/>
<menu submenu="Foo Systems, Inc."/>
</shortcut>
<association mime-type="application-x/wlog" extensions="wlog"/>
<association mime-type="application-x/mplot" extensions="mplot"/>
</information>
<security>
<all-permissions/>
</security>
<resources>
<j2se version="1.6+" initial-heap-size="32m" max-heap-size="255m"/>
<jar href="jars_deployment/TimingFramework-1.0.jar"/>
<jar href="jars_deployment/iText-2.1.5.jar"/>
<jar href="jars_deployment/jai_codec.jar"/>
<jar href="Foo.jar"/>
<jar href="jars_deployment/TimingFramework-1.0.jar"/>
<jar href="jars_deployment/iText-2.1.5.jar"/>
<jar href="jars_deployment/jai_codec.jar"/>
<jar href="jars_deployment/jsch-20090402.jar"/>
<property name="apple.laf.useScreenMenuBar" value="true"/>
<property name="apple.awt.graphics.UseQuartz" value="false"/>
<property name="com.apple.mrj.application.apple.menu.about.name" value="Foo"/>
<property name="java.util.logging.config.file" value="/Users/Shared/logging.properties"/>
</resources>
<application-desc main-class="com.prosc.msi.editor.ui.test.Sandbox"/>
</jnlp>
Most everything is working. When I double-click a .wlog file, it opens up my application. However, it doesn't open the correct file. I read somewhere that JNLP was supposed to pass parameters to the main method indicating which file caused the app to be launched, but this is not happening (on OS X 10.6). I get an empty array to my application's main method.
Probably unrelated, my splash screen doesn't work :(
Any pointers on getting this working?
In a bundled application on Mac OS X, you can implement com.apple.eawt.ApplicationListener, as shown in the Mac OS X Reference Library example, OSXAdapter:
The sample also supports document handing from the Finder by implementing the handleOpenFile() method and registering for supported file types in its Info.plist file.
Addendum: com.apple.eawt.ApplicationListener is deprecated; instead consider com.apple.eawt.Application, which provides getApplication().setOpenFileHandler().
About the splash window
I think the app is just missing the right path to your images.
In this case, like you mention the codebase:
<jnlp spec="6.0.10" version="1.63" codebase="http://foo.example.com/msi" href="Foo.jnlp"> and like you said in the image:
<icon href="splash.gif" width="425" height="102" kind="splash"/>
then, your images have to be in http://foo.example.com/msi/splash.gif
You might want be sure images are in that place.... is what I'm thinking could be the cause.
About the file association.
I'm working right now in the same, and it was seeming to be working while adding a Service from the JNLP API SingleInstanceService. This service is used to register the application like a singleton instance. So, any time your application is lauched, it could retreive the parameters which were used to call you app. In this case, you can use it to see the name of the file that was double clicked on.
http://download.oracle.com/javase/6/docs/technotes/guides/javaws/developersguide/examples.html#SingleInstanceService
In page above you can find an example and a breaf explanation about that service.
The problem that I found with that, is that I could not see the file name the first time that you run the app.
I mean, this service should register the app the first time, and after this time, you will be seeing the parameters used to launch the app. So, with this service if you opened the first time your app through a double click on your associated file, you will miss the parameters, until the next double click on it. Your app now will not open another instance again, just will pass the parameters to the instantiated application.
So, I found another solution for this.
http://www.knowledgesutra.com/discuss/tpclso-implement-single-instance-application-java.om
The boy in the page above, used a jar file from inside the Java installation to see the VM instance running that was invoked to see the parameters of the launch of your app. It has the code and the jar used to do that in this same page.
Now I'm able to see the line that was calling the app, like this:
com.sun.javaws.Main -open C:\\JNLP example\\applet-cartoon\\drawingPack\\drawing_monitor\\ejemplo.ply C:\Users\IsraelAltamira\AppData\Local\Temp\javaws23
where ejemplo.ply is the file extension that I used in the jnlp descriptor.
And well, Im working in OS X 10.6.4 now, and it seems to work, but at this moment the web start is not doing me the file association, and is not doing the shortcuts to the installed app... but maybe this last solution works for both systems (at least it work from my fake hyperlink, like the line above to open the file).

Categories

Resources