在浏览器中运行时,Java Web Start不会将参数传递给应用程序

时间:2012-10-18 13:18:28

标签: java java-web-start java-ws

我在使用Java Web Start开始向Java应用程序传递参数时遇到问题。我的系统是Ubuntu Linux 12.04.1 Precise,但在Windows 7中也是如此。两者都使用Oracle Java版本1.7.0_09。

编辑:我正在调查Web Start应用程序是否比普通applet更适合我们的需求。 applet的问题在于,如果用户离开页面而不是我们想要的东西,它会被关闭。 (我们也有兴趣看看我们是否可以通过使用Web Start而不是applet解决某个安全问题。)我们想从浏览器启动应用程序,以便我们可以传递有关经过身份验证的Java应用程序用户。要求用户登录应用程序似乎是一个糟糕的解决方案(我们可能需要支持OAuth之类的东西)。

我有一个示例程序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);
        }
    }
}

我将它打包成一个罐子:

javac CommandLineArgs.java
zip cmd.jar CommandLineArgs.class

然后我有一个名为cmd.jnlp的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>

这是我用于测试的HTML页面cmd.html。 div元素最初是使用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>

运行https服务器的最快方法是使用Linux中常见的openssl工具。像这样运行服务器时,当前目录应该包含cmd.html,cmd.jar和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

现在,如果我浏览https://localhost:9876/cmd.html我可以运行该应用程序。 Java控制台打开并打印出来。请注意,有0个命令行参数。

   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:

另一方面,如果我从命令行(javaws cmd.jnlp)运行javaws,我会在java控制台中得到它。现在有3个命令行参数。

    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

我做错了吗?为什么在浏览器中运行时参数不会传递给我的程序?

我发现帖子Java WS application ignoring arguments sporadically似乎描述了同样的问题。 posdef的解决方案是从jnlp文件中的jnlp元素中删除href属性,但我没有该属性。

3 个答案:

答案 0 :(得分:1)

application-desc适用于WebStart应用程序,使用applet-desc作为小程序。

答案 1 :(得分:1)

  

我们也有兴趣看看我们是否可以通过使用Web Start而不是applet解决某个安全问题。

应用于基于JWS的应用程序的安全环境。总是非常类似于应用于applet的。一些细微差别是System.exit(n)总是限制在applet(甚至是受信任的applet)中,并且JWS在沙盒和受信任之间提供了中等级别的安全性。

在Oracle收购插件之前,Sun竭尽全力整合两种形式的插件。

所以对这个问题的简短回答是'不'。如果您可以在JWS应用程序中执行此操作,则应该可以在小程序中执行此操作。

答案 2 :(得分:0)

根据Oracle文档

“属性元素定义了一个可通过System.getProperty和System.setProperties方法使用的系统属性。它有两个必需的属性:name和value。”

然后给出了这个例子:

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

要检索Java类中的值:

System.getProperty("key");