1

I'm having trouble passing arguments to a Java application started using Java Web Start. My system is Ubuntu Linux 12.04.1 Precise, but the same also happens in Windows 7. Both use Oracle Java version 1.7.0_09.

Edit: I'm investigating if a Web Start application would suit our needs better than a normal applet. The problem with an applet is that it gets closed if the user navigates away from the page which is not what we want. (We're also interested in seeing if we can get around a certain security issue by using Web Start instead of an applet.) We'd like to start the application from the browser so that we could pass information about the authenticated user to the Java application. Requiring the user to login in the application seems like a bad solution (we might have to support things like OAuth).

I have a sample program CommandLineArgs.java:

public class CommandLineArgs {
    public static void main(String[] args)  {
        System.out.println(String.format("Got %d command line args:", args.length));
        for (String arg : args) {
            System.out.println(arg);
        }
    }
}

I packaged this into a jar:

javac CommandLineArgs.java
zip cmd.jar CommandLineArgs.class

Then I have a JNLP file called cmd.jnlp:

<?xml version="1.0" encoding="utf-8"?>

<!-- Empty codebase means use same directory. -->
<jnlp spec="1.0+" codebase="https://localhost:9876/">
    <information>
        <title>Command Line Args Printer</title>
        <vendor>No one</vendor>
        <homepage href="https://localhost:9876/"/>
        <description>Application that prints the command line arguments that it gets.</description>
    </information>
    <resources>
        <j2se version="1.6+" initial-heap-size="32m" max-heap-size="128m" />
        <property name="jnlp.versionEnabled" value="true"/>

        <jar href="cmd.jar" main="true"/>

    </resources>
    <application-desc main-class="CommandLineArgs">
        <!-- Here are sample arguments I'd like to pass to the program. -->
        <argument>arg1</argument>
        <argument>arg2</argument>
        <argument>arg3</argument>
    </application-desc>
</jnlp>

Here's a HTML page cmd.html I use for testing. The div element was originally created by using deployjava.js: deployJava.launchWebStartApplication('https://localhost:9876/cmd.jnlp')

<!DOCTYPE html>

<html>
<head>
    <title>Java web start command line arguments test</title>

    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
</head>
<body>

<div id="div1" style="position: relative; left: -10000px; margin: 0px auto; " class="dynamicDiv">
    <embed type="application/x-java-applet;jpi-version=1.7.0_09" width="0" height="0" launchjnlp="https://localhost:9876/cmd.jnlp" docbase="https://localhost:9876/">
</div>

</body>
</html>

The fastest way I could get a https server running was to use the openssl tool commonly found in Linuxes. When running the server like this, the current directory should contain cmd.html, cmd.jar and cmd.jnlp .

sudo cp /etc/ssl/private/ssl-cert-snakeoil.key .
sudo chmod 666 ssl-cert-snakeoil.key
openssl req -batch -new -x509 -key ssl-cert-snakeoil.key -out ssl-cert-snakeoil.key.crt
openssl s_server -cert ssl-cert-snakeoil.key.crt -key ssl-cert-snakeoil.key -accept 9876 -WWW

Now if I surf to https://localhost:9876/cmd.html I can run the application. The Java console opens and it prints this. Notice that there are 0 command line arguments.

   JNLP Ref (absolute): https://localhost:9876/cmd.jnlp
    Match: beginTraversal
Match: digest selected JREDesc: JREDesc[version 1.6+, heap=33554432-134217728, args=null, href=null, sel=false, null, null], JREInfo: JREInfo for index 0:
    platform is: 1.7
    product is: 1.7.0_09
    location is: http://java.sun.com/products/autodl/j2se
    path is: /opt/jre1.7.0_09/bin/java
    args is: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8001
    native platform is: Linux, amd64 [ x86_64, 64bit ]
    JavaFX runtime is: JavaFX 2.2.3 found at /opt/jre1.7.0_09/
    enabled is: true
    registered is: true
    system is: true

    Match: ignoring maxHeap: 134217728
    Match: selecting InitHeap: 33554432
    Match: digesting vmargs: null
    Match: digested vmargs: [JVMParameters: isSecure: true, args: ]
    Match: JVM args after accumulation: [JVMParameters: isSecure: true, args: ]
    Match: digest LaunchDesc: null
    Match: digest properties: []
    Match: JVM args: [JVMParameters: isSecure: true, args: ]
    Match: endTraversal ..
    Match: JVM args final: -Xms32m
    Match: Running JREInfo Version    match: 1.7.0.09 == 1.7.0.09
     Match: Running JVM args match: have:<-Xms32m     satisfy want:<-Xms32m>
Got 0 command line args:

On the other hand, if I run javaws from the command line (javaws cmd.jnlp), I get this in the java console. Now there are 3 command line arguments.

    Match: beginTraversal
Match: digest selected JREDesc: JREDesc[version 1.6+, heap=33554432-134217728, args=null, href=null, sel=false, null, null], JREInfo: JREInfo for index 0:
    platform is: 1.7
    product is: 1.7.0_09
    location is: http://java.sun.com/products/autodl/j2se
    path is: /opt/jre1.7.0_09/bin/java
    args is: -agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8001
    native platform is: Linux, amd64 [ x86_64, 64bit ]
    JavaFX runtime is: JavaFX 2.2.3 found at /opt/jre1.7.0_09/
    enabled is: true
    registered is: true
    system is: true

    Match: ignoring maxHeap: 134217728
    Match: selecting InitHeap: 33554432
    Match: digesting vmargs: null
    Match: digested vmargs: [JVMParameters: isSecure: true, args: ]
    Match: JVM args after accumulation: [JVMParameters: isSecure: true, args: ]
    Match: digest LaunchDesc: null
    Match: digest properties: []
    Match: JVM args: [JVMParameters: isSecure: true, args: ]
    Match: endTraversal ..
    Match: JVM args final: -Xms32m
    Match: Running JREInfo Version    match: 1.7.0.09 == 1.7.0.09
     Match: Running JVM args match: have:<-Djnlp.versionEnabled=true -Xms32m     satisfy want:<-Xms32m>
Got 3 command line args:
arg1
arg2
arg3

Am I doing something wrong? Why don't the arguments get passed to my program when running in the browser?

I found the post Java WS application ignoring arguments sporadically that seems to describe the same problem. The solution for posdef was to remove the href attribute from the jnlp element in the jnlp file but I don't have that attribute.

Community
  • 1
  • 1
stereolegged
  • 83
  • 3
  • 7
  • How is this code running in a browser if it is not an applet? If it is an applet, it would generally expect to receive params rather than command line args. – Andrew Thompson Oct 19 '12 at 04:41
  • Thanks for your reply. I updated the question and explained what we're trying to achieve. We already have an applet but I believe we'd like to turn it into an application that runs separate from the browser window/tab. – stereolegged Oct 19 '12 at 09:50
  • Actually i managed to re-create a very similiar problem as stated here. Using a quite minimal test.jnlp + deployJava.launchWebStartApplication('test.jnlp') the arguments doesnt get passed to main. If i launch the same downloaded java-file from local disc it works perfectly. Did you happen to find a solution for this problem? – Aksel Willgert Nov 06 '12 at 19:16
  • I didn't find a solution, I just gave up and moved on to other things. – stereolegged Feb 08 '13 at 10:26

3 Answers3

1

application-desc is for WebStart applications, use applet-desc for applets.

Dmitri
  • 8,999
  • 5
  • 36
  • 43
  • Thanks for your reply. I updated the question and explained what we're trying to achieve. We already have a full-blown applet but it's not actually running on the page but in a separate window. We'd like the Java application to stay open even if the user navigates away from the page, and I'm under the impression that you can't do that with an applet. Of course, if my assumption is mistaken then I'd appreciate your input. – stereolegged Oct 19 '12 at 09:49
  • Yep, sounds like you want a WebStart app and not an applet (there are very few circumstances where you would actually want to use an applet). – Dmitri Oct 19 '12 at 19:42
1

We're also interested in seeing if we can get around a certain security issue by using Web Start instead of an applet.

The security environment applied to JWS based apps. was always very similar to that applied to applets. Some minor differences were that System.exit(n) was always restricted in applets (even trusted ones) and that JWS offered an intermediate level of security between sand-boxed and trusted.

Sun went to great effort to integrate the two forms of the plug-in before Oracle bought them.

So the short answer to that ..question is, 'no'. If you can do it in a JWS app., you should be able to do it in an applet.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • 1
    The problem we have would be worth its own question, actually. Briefly, someone runs our applet behind a proxy. Our applet experiences some momentary freezes, and when we attached a debugger to Java we found out that when a new anonymous class is created, the classloader checks if it's ok, someone in Java makes a network request to find out something (don't know what) and everything freezes while Java is trying to resolve a hostname. My best guess it's unable to resolve the hostname because it would have to use the proxy and it doesn't. I was wondering if we could avoid this permission check. – stereolegged Oct 19 '12 at 10:55
  • Here's the full question regarding the security issue: http://stackoverflow.com/questions/13025957/java-applet-behind-proxy-experiences-temporary-freezes-when-instantiating-new-cl – stereolegged Oct 23 '12 at 08:06
0

Per the Oracle docs

"The property element defines a system property that will be available through the System.getProperty and System.setProperties methods. It has two required attributes: name and value."

Then this example is given:

<property name="key" value="overwritten"/> 

To retrieve the value inside a Java class:

System.getProperty("key");

AssHat_
  • 353
  • 2
  • 13
  • I realize this isn't the same as passing "String[] args" to main, however with javaws you have limited options. You could always make a bootstrapper if you need it to be the regular "String[] args". i.e. Make another main class that handles pulling the System Properties and then launches the "real" application, passing the values as an array. – AssHat_ Oct 27 '12 at 06:50