简体   繁体   English

如果jar文件>特定大小,Applet无法在Windows 7上加载Java 1.7

[英]Applet fails to load with Java 1.7 on Windows 7 if jar file is >a certain size

We have a fairly complex signed applet that's been working fine for us since we developed it a couple of years ago. 我们有一个相当复杂的签名小程序,自从我们几年前开发它以来一直很好用。 It runs fine with Java 1.5 and 1.6 on all OS/browser configurations we care about. 在我们关心的所有操作系统/浏览器配置中,它可以在Java 1.5和1.6上运行良好。

It does not work with Java 1.7 in any browser on Windows 7 or Vista. 它在Windows 7或Vista上的任何浏览器中都不适用于Java 1.7。 We've seen it work on Windows XP. 我们已经看到它适用于Windows XP。 This applet is running in sites that are served by Apache connecting to Tomcat 6 using mod_proxy. 此applet在Apache使用mod_proxy连接到Tomcat 6的站点中运行。

That's all for background information, as I have reduced the problem down to a very simple, unsigned applet: 这些都是背景信息,因为我将问题简化为一个非常简单的未签名小程序:

package myapplet;
import java.applet.Applet;
import java.awt.Color;
import java.awt.Graphics;

public class MyApplet extends Applet {
    private static final long    serialVersionUID    = 1L;

    public void paint(Graphics g) {
        g.drawRect(0, 0, 250, 100);
        g.setColor(Color.blue);
        g.drawString("Look at me, I'm a Java Applet!", 10, 50);
    }
}

If this applet class is put into a jar file with another file that takes the total (compressed) size of the jar file over about 18KB then the applet doesn't load when served by Tomcat 6 (or Apache 2.2) running locally. 如果将这个applet类放入一个jar文件中,另一个文件将jar文件的总(压缩)大小超过大约18KB,那么当由本地运行的Tomcat 6(或Apache 2.2)提供服务时,applet不会加载。

I played around by adding a text file to the jar file and changing the size of the text file. 我通过向jar文件添加文本文件并更改文本文件的大小来玩。 I got it to the point where it would go from working to not working by adding one character to the text file. 我通过在文本文件中添加一个字符来实现它从工作到不工作的程度。

Looking at the console log with trace on it is hanging at the point where it is trying to download the jar file. 查看带有跟踪的控制台日志,它正在尝试下载jar文件。 Here's the thread that I think is hanging: 这是我认为悬挂的主题:

"thread applet-com.bright.assetbank.clientsideedit.myapplet.MyApplet-1" prio=4 tid=0x048d8c00 nid=0x19b8 runnable [0x0700d000]
    java.lang.Thread.State: RUNNABLE
    at java.net.SocketInputStream.socketRead0(Native Method)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.net.SocketInputStream.read(Unknown Source)
    at java.io.BufferedInputStream.read1(Unknown Source)
    at java.io.BufferedInputStream.read(Unknown Source)
    - locked <0x29fd75b0> (a java.io.BufferedInputStream)
    at sun.net.www.MeteredStream.read(Unknown Source)
    - locked <0x29fd75d0> (a sun.net.www.http.KeepAliveStream)
    at java.io.FilterInputStream.read(Unknown Source)
    at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
    at java.io.BufferedInputStream.read1(Unknown Source)
    at java.io.BufferedInputStream.read(Unknown Source)
    - locked <0x29fd7630> (a java.io.BufferedInputStream)
    at java.io.FilterInputStream.read(Unknown Source)
    at sun.plugin.PluginURLJarFileCallBack.downloadJAR(Unknown Source)
    at sun.plugin.PluginURLJarFileCallBack.access$000(Unknown Source)
    at sun.plugin.PluginURLJarFileCallBack$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin.PluginURLJarFileCallBack.retrieve(Unknown Source)
    at sun.net.www.protocol.jar.URLJarFile.retrieve(Unknown Source)
    at sun.net.www.protocol.jar.URLJarFile.getJarFile(Unknown Source)
    at sun.net.www.protocol.jar.JarFileFactory.get(Unknown Source)
    at sun.net.www.protocol.jar.JarURLConnection.connect(Unknown Source)
    at sun.plugin.net.protocol.jar.CachedJarURLConnection.connect(Unknown Source)
    at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFileInternal(Unknown Source)
    - locked <0x29f2a938> (a sun.plugin.net.protocol.jar.CachedJarURLConnection)
    at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFile(Unknown Source)
    - locked <0x29f2a938> (a sun.plugin.net.protocol.jar.CachedJarURLConnection)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.getJarFile(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.access$1000(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.ensureOpen(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$JarLoader.<init>(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
    at com.sun.deploy.security.DeployURLClassPath.getLoader(Unknown Source)
    - locked <0x29dc7e98> (a com.sun.deploy.security.DeployURLClassPath)
    at com.sun.deploy.security.DeployURLClassPath.getResource(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at sun.plugin2.applet.Plugin2ClassLoader.findClassHelper(Unknown Source)
    at sun.plugin2.applet.Applet2ClassLoader.findClass(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
    - locked <0x29dc7ed8> (a sun.plugin2.applet.Applet2ClassLoader)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass0(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
    - locked <0x29dc7f78> (a sun.plugin2.applet.Applet2ClassLoader)
    at sun.plugin2.applet.Plugin2ClassLoader.loadClass(Unknown Source)
    - locked <0x29dc7f78> (a sun.plugin2.applet.Applet2ClassLoader)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.plugin2.applet.Plugin2ClassLoader.loadCode(Unknown Source)
    at sun.plugin2.applet.Plugin2Manager.initAppletAdapter(Unknown Source)
    at sun.plugin2.applet.Plugin2Manager$AppletExecutionRunnable.run(Unknown Source)
    at java.lang.Thread.run(Unknown Source)

Here are the last 4 lines in the Java console: 以下是Java控制台中的最后4行:

network: Cache entry not found [url: http://localhost/editor.jar, version: null]
network: Connecting http://localhost/editor.jar with proxy=DIRECT
network: Connecting http://localhost:80/ with proxy=DIRECT
network: Connecting http://localhost/editor.jar with cookie "csrftoken=523154b2e73a76b6f2088464bd4df4f7"

Some additional information: 一些其他信息:

  • On Windows Vista running Java 7 in a browser our main applet (served by Apache->mod_proxy->tomcat) loads if I uncheck "Enable blacklist revocation check". 在浏览器中运行Java 7的Windows Vista上,如果取消选中“启用黑名单吊销检查”,则会加载我们的主applet(由Apache-> mod_proxy-> tomcat提供)。 It doesn't load if this is checked. 如果选中此选项,则不会加载。 Unchecking this has no effect (ie doesn't make it work) on Windows 7. 在Windows 7上取消选中此功能无效(即无法正常工作)。
  • I tried hosting my test applet in Tomcat (locally), Apache (locally) and Apache (on a remote server I access via the Internet). 我尝试在Tomcat(本地),Apache(本地)和Apache(在我通过Internet访问的远程服务器上)托管我的测试applet。 For each one there was a size of jar file above which the applet would not load - however, this size varied between the web servers . 对于每一个都有一个jar文件大小,applet不会加载到该文件大小 - 但是,这个大小在Web服务器之间变化 For example, on the the remote server the jar file could be much larger - it had to be over ~1MB before it wouldn't load. 例如,在远程服务器上,jar文件可能要大得多 - 在不加载之前必须超过1MB。

Has anyone else seen this behaviour when trying to load an applet with Java 7 running in a browser on Windows 7 or Vista? 尝试加载在Windows 7或Vista上的浏览器中运行Java 7的applet时,有没有其他人看到这种行为? Is there a solution? 有解决方案吗?

Step-by-step instructions for how to reproduce this problem: 有关如何重现此问题的分步说明:

  • Copy the code above into a file called MyApplet.java located in a directory called myapplet 将上面的代码复制到名为Myapplet的名为MyApplet.java的文件中
  • Compile the code, ie javac MyApplet.java 编译代码,即javac MyApplet.java
  • Create a jar file: cd to the parent directory of myapplet and type jar -cvf editor.jar myapplet 创建一个jar文件:cd到myapplet的父目录,然后输入jar -cvf editor.jar myapplet
  • Create a simple HTML page to show the applet. 创建一个简单的HTML页面来显示applet。

For example: 例如:

<html>  
    <body>
        <applet code="myapplet.MyApplet" name="MyApplet" width="300" height="300" archive= "editor.jar" ></applet>
    </body>
</html>
  • Put this HTML file and the jar file into the same directory and serve from a web server eg Apache or Tomcat. 将此HTML文件和jar文件放在同一目录中,并从Web服务器(例如Apache或Tomcat)提供服务。
  • Visit this HTML page in Chrome or IE on a Windows 7 OS. 在Windows 7操作系统上访问Chrome或IE中的此HTML页面。 The applet will load fine! 小程序将加载正常!
  • Repeat the above steps, but this time put a small file eg an image (eg <2KB) into the myapplet directory (next to MyApplet.class) before you create the jar file. 重复上述步骤,但这次在创建jar文件之前将一个小文件(例如<2KB)放入myapplet目录(MyApplet.class旁边)。 This should also work. 这也应该有效。
  • Repeat, but this time put a large image (eg >100KB) into the myapplet directory (next to MyApplet.class) before you create the jar file. 重复,但这次在创建jar文件之前将一个大图像(例如> 100KB)放入myapplet目录(MyApplet.class旁边)。 The jar file will now be quite big. jar文件现在会很大。 This won't work, ie the applet won't load. 这不起作用,即applet不会加载。 If it does, and you are using Windows 7, then please let me know. 如果是,并且您使用的是Windows 7,请告诉我。 While testing, don't forget that applets are cached so press the x key in the java console to refresh the classloader cache and f5 to refresh the browser. 在测试时,不要忘记applet已缓存,因此请在java控制台中按x键刷新类加载器缓存,然后按f5刷新浏览器。

The workaround for bug 7183450 in the Java bug database fixes this issue, which is to add Java错误数据库中的错误7183450的解决方法修复了此问题,即添加

-Djava.net.preferIPv4Stack=true 

to the JVM arguments. 到JVM参数。

For example, to get my test applet running (see the example in my question above): 例如,要让我的测试applet运行(请参阅上面的问题中的示例):

<html>  
    <body>
        <applet code="myapplet.MyApplet" name="MyApplet" width="300" height="300" archive= "editor.jar" >
        <param name="java_arguments" value="-Djava.net.preferIPv4Stack=true">
    </applet>
    </body>
</html>

This is probably because the remote servers hosting our applet currently don't let IPv6 comms through their firewalls. 这可能是因为托管我们applet的远程服务器目前不允许IPv6通过其防火墙进行通信。

Interestingly, some of our Windows 7 machines still didn't work even with this workaround when running Java 1.7_05 but then did work (with this workaround) when upgraded to Java 1.7_06 (which is now available). 有趣的是,在运行Java 1.7_05时,我们的某些Windows 7计算机仍然无法使用此解决方法,但在升级到Java 1.7_06(现在可用)时确实可以工作(使用此解决方法)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM