United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6460510 Applet throws OutOfMemory/ClassNotFound exception with cache enabled
JDK-6460510 : Applet throws OutOfMemory/ClassNotFound exception with cache enabled

Details
Type:
Bug
Submit Date:
2006-08-16
Status:
Closed
Updated Date:
2010-04-04
Project Name:
JDK
Resolved Date:
2006-09-28
Component:
deploy
OS:
windows_xp
Sub-Component:
plugin
CPU:
x86
Priority:
P2
Resolution:
Fixed
Affected Versions:
6
Fixed Versions:

Related Reports

Sub Tasks

Description
Applet throws ClassNotFound exception with cache enabled

builds reproducible - b38 onwards
The bug is not reproducible on b37

OS tested - Win XP Pro, Win XP Home
browsers tested - IE6.0, MZ 1.7.x

Steps to reproduce

1) Install jre1.6.0 b37 or later

2) Delete the folder "java" 
C:\Documents and Settings\{User}\Application data\Sun

3) Open Java Control Panel, and enable "Show java console" and "Show Applet Lifecycle Exceptions"

4) Make sure the cache is enabled
General -> Settings ->Temporary Files Settings
"Keep temporary files on my computer" should be checked

4) Open the browser and launch the following applet
http://sqeweb/deployment1/deployment_tiger_exec_ws/deployment/src/plugin/phonehome/applethtml/GrayBoxTest-19.html

5) Only three of the six frames are loaded and ClassNotFound exceptions are thrown in the java console. Please see the attachment for the exceptions thrown

6) Now open the Java Control Panel and disable cache
General -> Settings ->Temporary Files Settings
"Keep temporary files on my computer" should be unchecked

7) Load the above applet again, and the applet loads fine and no exceptions are thrown.

expected behavior - no exceptions should be thrown with cache enabled.

                                    

Comments
EVALUATION

we run into OutOfMemory exception when this occurs:


java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOf(Unknown Source)
	at java.io.ByteArrayOutputStream.write(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)
	at java.io.FilterInputStream.read(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)
	at sun.plugin.net.protocol.jar.CachedJarURLConnection.getJarFile(Unknown Source)
	at sun.misc.URLClassPath$JarLoader.getJarFile(Unknown Source)
	at sun.misc.URLClassPath$JarLoader.access$600(Unknown Source)
	at sun.misc.URLClassPath$JarLoader$1.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.misc.URLClassPath$JarLoader.ensureOpen(Unknown Source)
	at sun.misc.URLClassPath$JarLoader.<init>(Unknown Source)
	at sun.misc.URLClassPath$3.run(Unknown Source)
	at java.security.AccessController.doPrivileged(Native Method)
	at sun.misc.URLClassPath.getLoader(Unknown Source)
	at sun.misc.URLClassPath.getLoader(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 java.lang.ClassLoader.loadClass(Unknown Source)
basic: Exception: java.lang.OutOfMemoryError: Java heap space

Need to investigate the cause of it.
                                     
2006-08-16
WORK AROUND

set -Xmx192m, the applet will run
                                     
2006-08-17
EVALUATION

the problem is for 6.0 plugin, we depend on the java.net.ResponseCache for resource downloading.

i created a same standalone java testcase, with ResponseCache, which downloads the 2 jar files (40mb and 20mb) as in the plugin applet test, and it will run into outOfMemory exception too.

Need to contact the networking team and see if we are using the ResponseCache for downloading correctly.

Standalone testcase source code below:

import java.net.*;
import java.io.*;
import java.util.*;
import javax.swing.*;

class test extends ResponseCache {
    private static int BUF_SIZE = 8192;
public CacheResponse get(URI uri,
                                  String rqstMethod,
                                  Map<String,List<String>> rqstHeaders)
    throws IOException {
    return null;
}

public CacheRequest put(URI uri,
                                 URLConnection conn)
    throws IOException {
     URL url = uri.toURL();
      return new CacheRequest(url, conn);
   
}

class ByteArrayOutputStream extends java.io.ByteArrayOutputStream {
    
    private URL _url;
    private URLConnection _conn;
    
    ByteArrayOutputStream(URL url, URLConnection conn) {
        _url = url;
        _conn = conn;
    }   
 
    
    public void close() throws IOException {   
     
     
        
        ByteArrayInputStream bais = new ByteArrayInputStream(toByteArray());
         byte[] buf = new byte[BUF_SIZE];
	 int read = 0;
	 File nestedJar = File.createTempFile("jar_cache", null);
	 BufferedInputStream nestedIn = new BufferedInputStream(bais);
	 BufferedOutputStream nestedOut = new BufferedOutputStream(new FileOutputStream(nestedJar));
	 read = 0;
	 
	 while ((read = nestedIn.read(buf)) != -1)
	     nestedOut.write(buf, 0, read);
	 
	 nestedOut.close();
	 nestedOut = null;
	 
     
        super.close();
    }
}

class CacheRequest extends java.net.CacheRequest {
    
    private URL _url;
    private URLConnection _conn;
    private boolean _downloading = false;
    
    CacheRequest(URL url, URLConnection conn) {
        _url = url;
        _conn = conn;
    }
    
    public void abort() {

    }
    
    public OutputStream getBody() throws IOException {
        return new ByteArrayOutputStream(_url, _conn);
    }
}

    public static void main(String[] args) {
	//JFrame jf = new JFrame("dummy");
	//jf.show();
	test t = new test();
	ResponseCache.setDefault(t);
	try {
	    System.out.println("download test22.jar");
	    downloadURL(new URL("http://sqeweb.sfbay.sun.com/deployment1/deployment_tiger_exec_ws/deployment/src/plugin/phonehome/classes/Test22.jar"));
	    System.out.println("download test31.jar");
	    downloadURL(new URL("http://sqeweb.sfbay.sun.com/deployment1/deployment_tiger_exec_ws/deployment/src/plugin/phonehome/classes/Test31.jar"));
	} catch (Exception e) {
	    e.printStackTrace();
	}
    }

    public static void downloadURL(URL url) throws IOException {
	 InputStream is = null;
	 URLConnection conn =  url.openConnection();
	 try {
	     // this calls into CacheHandler.get
	     byte[] buf = new byte[BUF_SIZE];
	     is = new BufferedInputStream(conn.getInputStream());
	     while (is.read(buf) != -1) {
	     }
	     
	 } finally {
	     if (is != null) {
		 // this calls into CacheHandler.put
		 is.close();
	     }
	 }
    }
}
                                     
2006-08-17
SUGGESTED FIX

http://web-east.east/deployment/www/webrevs/ngthomas/6460510/webrev/
                                     
2006-08-17
EVALUATION

The cause of the OutOfMemory exception is due to the way we use the ResponseCache.  We create a ByteArrayOutputStream and use a byte[] to hold the jar contents in memory, and after everything is downloaded in memory, we then write it out to cache.

This will cause OutOfMemory exception easily, since all the jar contents is stored in memory first, before we write it out to file system.

We should instead use a FileOutputStream for the CacheRespose, so we will write out the file as the download proceeds, instead of storing everything into the memory first.
                                     
2006-08-17



Hardware and Software, Engineered to Work Together