JDK-4740901 : Problem with Cipher.getInstance and cached Applet JAR file
  • Type: Bug
  • Component: deploy
  • Sub-Component: plugin
  • Affected Version: 1.4.0,1.4.1
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: windows_nt,windows_2000
  • CPU: x86
  • Submitted: 2002-09-03
  • Updated: 2002-10-15
  • Resolved: 2002-10-15
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
1.4.2 mantisFixed
Description

Name: gm110360			Date: 09/03/2002


FULL PRODUCT VERSION :
java version "1.4.0_01"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03)
Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode)



FULL OPERATING SYSTEM VERSION : Microsoft Windows 2000
[Version 5.00.2195] Service Pack 3


A DESCRIPTION OF THE PROBLEM :
When I call Cipher.getInstance() in the 1.4 java plugin
(with cache enabled), I can no longer create any new
classes from the jar file containing the class which uses
the Cipher.getInstance.  Example: Encryptor.class and
Login.class are contained in the same jar file.  The
following code fails.

try{
    javax.crypto.Cipher cipher =
javax.crypto.Cipher.getInstance("PBEWithMD5AndDES");
}catch(Exception e){}

LoginDialog dlg = new LoginDialog(); //Failure occurs here





STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. call Cipher.getInstance within a Java applet running
under Java Plugin 1.4
2. call new on an object that is within the same jar file
as the object that called Cipher.getInstance

EXPECTED VERSUS ACTUAL BEHAVIOR :
The applet throws a "java.lang.IllegalStateException: zip
file closed" exception and the applet is unable to create
new instances of objects within the jar file.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalStateException: zip file closed

	at java.util.zip.ZipFile.getEntry(ZipFile.java:143)

	at java.util.jar.JarFile.getEntry(JarFile.java:183)

	at sun.plugin.cache.CachedJarFile.getEntry(CachedJarFile.java:75)

	at java.util.jar.JarFile.getJarEntry(JarFile.java:170)

	at sun.misc.URLClassPath$JarLoader.getResource(URLClassPath.java:577)

	at sun.misc.URLClassPath.getResource(URLClassPath.java:135)

	at java.net.URLClassLoader$1.run(URLClassLoader.java:190)

	at java.security.AccessController.doPrivileged(Native Method)

	at java.net.URLClassLoader.findClass(URLClassLoader.java:186)

	at sun.applet.AppletClassLoader.findClass(AppletClassLoader.java:132)

	at sun.plugin.security.PluginClassLoader.findClass
(PluginClassLoader.java:189)

	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)

	at sun.applet.AppletClassLoader.loadClass(AppletClassLoader.java:112)

	at java.lang.ClassLoader.loadClass(ClassLoader.java:262)

	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:322)

	at com.avaya.ipagent.adminclient.LoginDialog.jbInit(LoginDialog.java:63)

	at com.avaya.ipagent.adminclient.LoginDialog.<init>(LoginDialog.java:36)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
************TestApplet.java********************
import java.awt.*;
import javax.swing.*;

public class TestApplet extends JApplet
{

  public void init()
  {
    Container contentPane = getContentPane();
    JLabel label = new JLabel("Not a Hello, World applet",
SwingConstants.CENTER);
    contentPane.add(label);

    try{
      javax.crypto.Cipher cipher = javax.crypto.Cipher.getInstance
("PBEWithMD5AndDES");
    }catch(Exception e){}

    System.out.println("Cipher.getInstance() called, now trying to create new
LoginDialog()");

    Login login = new Login();

    System.out.println("new LoginDialog() created");
  }
}
******************************************************************

*****************Login.java*************************************
public class Login
{

  public Login()
  {
  }
}
******************************************************************

********************TestApplet.html******************************
<APPLET CODE="TestApplet.class" WIDTH=300 HEIGHT=300>
    <PARAM NAME = CODE VALUE = "TestApplet.class" >
    <PARAM NAME = CODEBASE VALUE = "." >
    <PARAM NAME = ARCHIVE VALUE = "TestApplet.jar" >
</APPLET>
******************************************************************
---------- END SOURCE ----------

CUSTOMER WORKAROUND :
There are two workarounds that I know of, however neither
is a very good solution.

1. Turn the Java 1.4 plugin cache off.

2. Place the class file that calls Cipher.getInstance into
its own jar file and only create one instance of that
class.  Then place the rest of the class files into another
jar file, that way you can create as many instances as
needed. Example: <PARAM NAME = ARCHIVE VALUE
= "TestApplet.jar", "Encrypt.jar" > where Encrypt.jar will
contain the class that calls Cipher.getInstance.
(Review ID: 163558) 
======================================================================

Name: gm110360			Date: 09/03/2002


FULL PRODUCT VERSION :
Java plug-in 1.4.0

A DESCRIPTION OF THE PROBLEM :
When using Cipher.getInstance within an Applet the jar file
containing this code becomes closed and can no longer be
accessed. This results in an
exception: "IllegalStateException: Zip file closed".
This is only the case when caching is enabled within the
Plug-in.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1.Ensure that Cache is enabled.
2.Create a couple of classes and an Applet all within the
same jar. Call one class with Cipher.getInstance then try
to access the other class for the first time error should
occur.
3.

EXPECTED VERSUS ACTUAL BEHAVIOR :
Should not close jar.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.IllegalStateException: zip file closed

	at java.util.zip.ZipFile.getEntry(Unknown Source)

	at java.util.jar.JarFile.getEntry(Unknown Source)

	at sun.plugin.cache.CachedJarFile.getEntry(Unknown Source)

	at java.util.jar.JarFile.getJarEntry(Unknown Source)

	at sun.misc.URLClassPath$JarLoader.getResource(Unknown Source)

	at sun.misc.URLClassPath.getResource(Unknown Source)

	at java.net.URLClassLoader$1.run(Unknown Source)

	at java.security.AccessController.doPrivileged(Native Method)

	at java.net.URLClassLoader.findClass(Unknown Source)

	at sun.applet.AppletClassLoader.findClass(Unknown Source)

	at sun.plugin.security.PluginClassLoader.findClass(Unknown Source)

	at java.lang.ClassLoader.loadClass(Unknown Source)

	at sun.applet.AppletClassLoader.loadClass(Unknown Source)

	at java.lang.ClassLoader.loadClass(Unknown Source)

	at java.lang.ClassLoader.loadClassInternal(Unknown Source)


REPRODUCIBILITY :
This bug can be reproduced always.

CUSTOMER WORKAROUND :
Disable caching or move code into multiple jars.
(Review ID: 159363)
======================================================================

Comments
CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: mantis FIXED IN: mantis INTEGRATED IN: mantis mantis-b04
14-06-2004

EVALUATION javax.crypto.SunJCE_d.finalize closes the cached jar file and therefore IllegalStateException is thrown if the cached jar is used later. This bug looks similar to #4326919. Re-assigning to security team for further evaluation ###@###.### 2002-09-05 According to my investigation, this is due to an implementation issue in sun.plugin.net.protocol.jar.CachedJarURLConnection class. Here are more details: Before JCE retrieves user's jar file, it calls URLConnection.setUseCaches(false) to indicate that it wants its own copy of this JarFile object instead of the cached version. However, unlike class sun.net.www.protocol.jar.JarURLConnection which honors this setting, class sun.plugin.net.protocol.jar.CachedJarURLConnection always returns the cached copy. According to the javadoc of java.net.URLConnection.setUseCaches(boolean): ================== Some protocols do caching of documents. Occasionally, it is important to be able to "tunnel through" and ignore the caches (e.g., the "reload" button in a browser). If the UseCaches flag on a connection is true, the connection is allowed to use whatever caches it can. If false, caches are to be ignored. The default value comes from DefaultUseCaches, which defaults to true. ================== It seems that plugin's implementation of java.net.JarURLConnection does not conforms to the specification of URLConnection.setUseCaches(boolean). Will discuss with plugin team about their JarURLConnection implementation. ###@###.### 2002-09-05 Discussed with Deva who confirmed my observation of Plugin's JarURLConnection implementation. Re-assign the bug back to plugin team. ###@###.### 2002-09-06
05-09-2002