JDK-6373059 : OutOfMemoryError on ZipFile.open
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Affected Version: 5.0
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: linux
  • CPU: x86
  • Submitted: 2006-01-17
  • Updated: 2011-03-02
  • Resolved: 2006-04-29
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 JDK 6
5.0u8Fixed 6 b83Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java version "1.5.0_05"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_05-b05)
Java HotSpot(TM) 64-Bit Server VM (build 1.5.0_05-b05, mixed mode)


ADDITIONAL OS VERSION INFORMATION :
Linux dev17.pub.qa.atl.jboss.com 2.6.9-22.0.1.ELsmp #1 SMP Tue Oct 18 18:39:02 EDT 2005 x86_64 x86_64 x86_64 GNU/Linux


A DESCRIPTION OF THE PROBLEM :
When starting an out-of-the-box JBoss 4.0.2/4.0.3SP1 we get random OutOfMemoryError Error very early on startup, about 30% of the time.

This is not really due to JBoss code, we have a minimal testcase that can be used to reproduce the problem.

This happens only on the 64bit version of jdk5 on Linux. It works fine on older jdk versions, or the 32 bit versions. It works fine also using the 64bit JRockit on Linux.

The issue was discussed here: http://www.jboss.com/index.html?module=bb&op=viewtopic&t=74994&postdays=0&postorder=asc&start=0

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
  To run the testcase use:

java TestOOM jboss-4.0.2/server/all/lib/ test.xml

Basically point it to a directory with a lot of jar files (e.g. the server/all/lib directory of jboss that contains 45 jars) plus any non-jar, non-empty file (e.g. test.xml)

In this example we use those paths to contract a URL[] passed to  a URLClassLoader, then try to load a non-existing class. Most of the times this tests will produce an OOM Error, at the point when the non-jar file is openned

ACTUAL -
java TestOOM jboss-4.0.2/server/all/lib/ test.xml
#0 file:/home/dimitris/jboss-4.0.2/server/all/lib/activation.jar
#1 file:/home/dimitris/jboss-4.0.2/server/all/lib/autonumber-plugin.jar
#2 file:/home/dimitris/jboss-4.0.2/server/all/lib/avalon-framework.jar
#3 file:/home/dimitris/jboss-4.0.2/server/all/lib/bcel.jar
#4 file:/home/dimitris/jboss-4.0.2/server/all/lib/bindingservice-plugin.jar
#5 file:/home/dimitris/jboss-4.0.2/server/all/lib/bsh-1.3.0.jar
#6 file:/home/dimitris/jboss-4.0.2/server/all/lib/bsh-deployer.jar
#7 file:/home/dimitris/jboss-4.0.2/server/all/lib/commons-httpclient.jar
#8 file:/home/dimitris/jboss-4.0.2/server/all/lib/commons-logging.jar
#9 file:/home/dimitris/jboss-4.0.2/server/all/lib/hsqldb-plugin.jar
#10 file:/home/dimitris/jboss-4.0.2/server/all/lib/hsqldb.jar
#11 file:/home/dimitris/jboss-4.0.2/server/all/lib/jacorb.jar
#12 file:/home/dimitris/jboss-4.0.2/server/all/lib/javax.servlet.jar
#13 file:/home/dimitris/jboss-4.0.2/server/all/lib/javax.servlet.jsp.jar
#14 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-cache.jar
#15 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-common-jdbc-wrapper.jar
#16 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-iiop.jar
#17 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-j2ee.jar
#18 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-jaxrpc.jar
#19 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-jca.jar
#20 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-jsr77.jar
#21 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-management.jar
#22 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-monitoring.jar
#23 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-remoting.jar
#24 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-saaj.jar
#25 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss-transaction.jar
#26 file:/home/dimitris/jboss-4.0.2/server/all/lib/jboss.jar
#27 file:/home/dimitris/jboss-4.0.2/server/all/lib/jbossha.jar
#28 file:/home/dimitris/jboss-4.0.2/server/all/lib/jbossmq.jar
#29 file:/home/dimitris/jboss-4.0.2/server/all/lib/jbosssx.jar
#30 file:/home/dimitris/jboss-4.0.2/server/all/lib/jgroups.jar
#31 file:/home/dimitris/jboss-4.0.2/server/all/lib/jmx-adaptor-plugin.jar
#32 file:/home/dimitris/jboss-4.0.2/server/all/lib/jnpserver.jar
#33 file:/home/dimitris/jboss-4.0.2/server/all/lib/jpl-pattern.jar
#34 file:/home/dimitris/jboss-4.0.2/server/all/lib/jpl-util.jar
#35 file:/home/dimitris/jboss-4.0.2/server/all/lib/license.html
#36 file:/home/dimitris/jboss-4.0.2/server/all/lib/log4j.jar
#37 file:/home/dimitris/jboss-4.0.2/server/all/lib/mail-plugin.jar
#38 file:/home/dimitris/jboss-4.0.2/server/all/lib/mail.jar
#39 file:/home/dimitris/jboss-4.0.2/server/all/lib/properties-plugin.jar
#40 file:/home/dimitris/jboss-4.0.2/server/all/lib/scheduler-plugin-example.jar
#41 file:/home/dimitris/jboss-4.0.2/server/all/lib/scheduler-plugin.jar
#42 file:/home/dimitris/jboss-4.0.2/server/all/lib/scout.jar
#43 file:/home/dimitris/jboss-4.0.2/server/all/lib/snmp-support.jar
#44 file:/home/dimitris/jboss-4.0.2/server/all/lib/webcallbackhandler.jar
#45 file:/home/dimitris/test.xml
java.lang.OutOfMemoryError
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:203)
        at java.util.jar.JarFile.<init>(JarFile.java:132)
        at java.util.jar.JarFile.<init>(JarFile.java:70)
        at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:579)
        at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:546)
        at sun.misc.URLClassPath$3.run(URLClassPath.java:324)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.misc.URLClassPath.getLoader(URLClassPath.java:313)
        at sun.misc.URLClassPath.getLoader(URLClassPath.java:290)
        at sun.misc.URLClassPath.findResource(URLClassPath.java:141)
        at java.net.URLClassLoader$2.run(URLClassLoader.java:362)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findResource(URLClassLoader.java:359)
        at TestOOM.main(TestOOM.java:49)


ERROR MESSAGES/STACK TRACES THAT OCCUR :
java.lang.OutOfMemoryError
        at java.util.zip.ZipFile.open(Native Method)
        at java.util.zip.ZipFile.<init>(ZipFile.java:203)
        at java.util.jar.JarFile.<init>(JarFile.java:132)
        at java.util.jar.JarFile.<init>(JarFile.java:70)
        at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:579)
        at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:546)
        at sun.misc.URLClassPath$3.run(URLClassPath.java:324)
        at java.security.AccessController.doPrivileged(Native Method)
        at sun.misc.URLClassPath.getLoader(URLClassPath.java:313)
        at sun.misc.URLClassPath.getLoader(URLClassPath.java:290)
        at sun.misc.URLClassPath.findResource(URLClassPath.java:141)
        at java.net.URLClassLoader$2.run(URLClassLoader.java:362)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findResource(URLClassLoader.java:359)
        at TestOOM.main(TestOOM.java:49)


REPRODUCIBILITY :
This bug can be reproduced often.

---------- BEGIN SOURCE ----------
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Properties;

public class TestOOM
{
   public static void main(String[] args)
   {
      ArrayList urls = new ArrayList();
      try
      {
         for (int i = 0; i < args.length; i++)
         {
            File file = new File(args[i]);
            if (file.isDirectory())
            {
               File[] files = file.listFiles();
               for (int j = 0; j < files.length; j++)
               {
                  urls.add(files[j].toURL());
               }
            }
            else
            {
               urls.add(file.toURL());
            }
         }
      }
      catch (MalformedURLException ignore)
      {
      }

      URL[] cp = (URL[])urls.toArray(new URL[urls.size()]);
      for (int i = 0; i < cp.length; i++)
      {
         System.out.println("#" + i + " " + cp[i]);
      }


      URLClassLoader ucl = new URLClassLoader(cp);
      try
      {
         ucl.findResource("foo.bar.Class");
      }
      catch (Throwable t)
      {
         // got it!
         t.printStackTrace();
         System.exit(1);
      }
   }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
There is not really workaround for this, other than avoiding open non zip files with ZipFile, but this not always under our control.

This is a really annoying bug.

Comments
EVALUATION Early in JVM startup, while parsing a class file, a call to malloc returns a valid memory address, but errno is set to ENOMEM. At this time, since the return value is valid, errno is not checked. This could be very possible a C library fault, as the same code runs well in kernel 2.4. This error status remains unchanged, and is eventually checked when readCEN returns NULL from reading non-zip file. errno was set to ENOMEM before this call, and as readCEN does nothing to change it, and since the return from readCEN indicates an error, errno is checked, and so an incorrect OOM is thrown. Setting errno to "0" before any operation on memory in Zip_Open_Generic can "fix" this problem.
18-04-2006

WORK AROUND Instead of adding all files in a directory to the URL[] that is given to URLClassLoader, use a java.io.FilenameFilter to add only .jar and .zip files to the URL[].
14-03-2006

WORK AROUND set LD_ASSUME_KERNEL=2.4.1
11-02-2006