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();
}
}
}
}
|
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.
|