Java WebStart速度慢,从无效文件夹中请求库

时间:2011-04-24 13:38:09

标签: java classloader jnlp java-web-start

问题和疑问:Java webstarted app在基础文件夹中查找其类而不是./lib。

正如Java Web Start applications ask repeatedly for un-existing files中的类似问题所示,我已将关闭 jar签名,以排除安全问题,问题仍然存在。

下面找到关于这个简单的java程序网络内容的简洁示例:

public static void main(String[] args) {
    // TODO code application logic here
    System.out.println("Hello World! Initializing the class from the jar residing in lib/ folder. Expecting heavy network traffic...");

    //This class resides in lib/SampleJavaLibrary.jar
    //Initializing it just to excercise the class loader problem
    CDummyClass sDummy = new CDummyClass();

    System.out.println("Done");

}

在网络上(通过wireshark),人们可以观察到对基础文件夹中的jar的重复请求,在一些调用中,我计算了多达10次重试,由web服务器回复404.最终,loadClass成功,但仅在10之后或更多对不存在的罐子的要求。将其与给定程序中正在访问的类的数量相乘,最终会导致初始化非常慢。 在这个简单的例子中,这个简单的类只有“2次”重试。

这一切都开始正常,罐子装满了,一切都很好而且很好:

6   0.020921    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/launch.jnlp HTTP/1.1
8   0.028092    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 200 OK  (application/x-java-jnlp-file)
10  0.514038    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/lib/SampleJavaLibrary.jar HTTP/1.1 
11  0.520688    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 200 OK  (application/java-archive)
12  0.618640    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/WebStartSample.jar HTTP/1.1 
14  0.652541    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 200 OK  (application/java-archive)

这是故障开始的地方,在图书馆班级电话:

16  0.943801    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/SampleJavaLibrary.jar HTTP/1.1 
18  0.991748    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 404 Not Found  (text/html)
22  0.997281    192.168.1.35    192.168.1.130   HTTP    GET /mnt/vbox/workspace/WebStartSample/distC/SampleJavaLibrary.jar HTTP/1.1 
24  1.004799    192.168.1.130   192.168.1.35    HTTP    HTTP/1.1 404 Not Found  (text/html)

最终,在上面重试之后,正在找到并初始化类(!),很可能是在已经存在的jar中,它是在应用程序启动时加载的。

为什么jnlp类加载器会查看基本文件夹,以及为什么这么多次重试都超出了我的范围。我确实尝试在调试器下运行,但是找不到类加载器的源代码而无法自己解决。

FWIW这里是我的jnlp文件,是的,我确实尝试了更新标签的所有变体,懒惰,渴望,没有变化

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<jnlp codebase="http://mydebian.mydomain/mnt/vbox/workspace/WebStartSample/distC"    href="launch.jnlp" spec="1.0+">
    <information>
        <title>WebStartSample</title>
        <vendor>user</vendor>
        <homepage href=""/>
        <description>WebStartSample</description>
        <description kind="short">WebStartSample</description>

    </information>
<update check="always"/>

    <resources>
<j2se version="1.5+"/>
<jar href="WebStartSample.jar" main="true"/>


    <jar href="lib/SampleJavaLibrary.jar"/>
</resources>
    <application-desc main-class="webstartsample.Main">

    </application-desc>
</jnlp>

我怀疑JNLPClassLoader()有问题,这是webstart中使用的特定加载器。

此致

罗伯特

3 个答案:

答案 0 :(得分:2)

建议:

  1. 使用JaNeLA验证JNLP。这似乎对我有用,但JaNeLA是更好的判断。
  2. 为每个Jar包含package元素。 Resources section of the JNLP File Syntax中提到了此元素(也在页面顶部的表格中展开)。将页面中的链接追溯到(仅可下载)API规范,以获取package元素的更多详细信息。另外,API规范。是JWS上最好的资源。我希望甲骨文能让它可以浏览网页。
  3. 索引Jar文件。
  4. 继续问这么好(经过深思熟虑,研究得很好,提出的很好)的问题。 :)

答案 1 :(得分:2)

感谢大家的建议。正是安德鲁暗示要“指出罐子”,这指向了正确的方向......

即,jars(我选择的当前IDE,Netbeans)索引。但是,主jar中的META-INF / INDEX.LIST包含对其他jar的引用,就好像它们位于主jar的当前文件夹中一样。

JarIndex-Version: 1.0

WebStartSample.jar
webstartsample

SampleJavaLibrary.jar
newpackage

这导致了jnlpClassLoader(),使用主索引,并在codebase url中查找jar,而它们实际上位于./lib url子文件夹下。

这是正确的索引(手动重新创建)的样子:

JarIndex-Version: 1.0

WebStartSample.jar
webstartsample

lib/SampleJavaLibrary.jar
newpackage

为了使问题变得更糟,这样的webstarted应用程序不会失败,他们只会首先在错误的位置查找类/ jar,然后最终找到它们,可能已经加载了bu jnlp loader,如原始问题所述。

简而言之,这与IS的Netbeans构建和打包程序有关。

我的立即修复是禁用jar索引,这导致了正确和最小的网络流量,并大大改善了应用程序初始化。

要在Netbeans中执行此操作,请转到工具 - &gt;选项 - &gt;杂项 - &gt; Ant-&gt;属性并添加jar.index=false

正确的解决方法是让Netbeans正确地对jar进行索引,但这是另一个问题。

再次感谢大家的建议。

PS。

  • janela util在我的jnlp
  • 中没有发现重大错误
  • 包含元素包括不做任何更改
  • mydebian指的是我的服务器,客户端是win7,包含所有最新和最好的java运行时和jdks,包括netbeans 6.9(也测试了7.0,产生了相同的问题索引)

答案 2 :(得分:0)

“mydebian.mydomain”主机名暗示您在Debian上运行,其中OpenJDK是默认的Java实现。

Sun Java WebStart实现是不是 OpenJDK的一部分,因此使用了替代实现。由于Java WebStart没有正式的TCK,因此需要手动找到OpenJDK实现中的细微差别甚至错误(因为没有官方的TCK)。

我建议尝试使用Sun JVM(例如在Windows上)并查看行为是否发生变化。