Bug 34856

Summary: MacOSX 10.4 and Java 5 jnilibs causes ZipException when Tomcat loads non-jars
Product: Tomcat 5 Reporter: Niels Castle Andersen <castle>
Component: JasperAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED INVALID    
Severity: normal CC: petr.jiricka, pratik.solanki, sherold, zikmund
Priority: P2    
Version: 5.0.30   
Target Milestone: ---   
Hardware: Macintosh   
OS: Mac OS X 10.4   
URL: http://www.burnthacker.com/archives/000218.html

Description Niels Castle Andersen 2005-05-11 10:04:35 UTC
Tiger includes all the jnilib JNI extensions in the classpath of the JVM.

When you compile a JSP using Jasper on Tomcat 5, what you get in your tomcat logs looks like:

error: error reading /System/Library/Java/Extensions/libJ3D.jnilib; 
java.util.zip.ZipException: error in opening zip file

Jasper attempts to read the jnilib as a jar since it's in the classpath, and that doesn't work.
Comment 1 Pratik Solanki 2005-06-14 19:07:24 UTC
The issue is two-fold.

Jasper/Tomcat seems to be adding all the files found under /System/Library/Java/Extensions to the 
classpath. The log file has 

classpath= ....../System/Library/Java/Extensions/libJ3DAudio.jnilib:/System/Library/Java/Extensions/
libJ3DUtils.jnilib:...

This is wrong. It should not be adding jnilib files to the classpath

The second issue is that the javac compiler is expected to ignore such invalid files in the classpath. 1.4 
did that. 1.5 is throwing an exception. This seems to be a regression in javac. AFAICT, this should be 
happening on all platforms and not just on MacOSX. Can anyone confirm or deny this? Does Tomcat/
Jasper work fine on Linux/Windows/Solaris with 1.5?

A few comments on the original bug report.

(In reply to comment #0)
> Tiger includes all the jnilib JNI extensions in the classpath of the JVM.

No. Jasper/Tomcat does that.

> Jasper attempts to read the jnilib as a jar since it's in the classpath, and that doesn't work.

No. javac 1.5 on Tiger attempts to read the jnilib as a jar. This is a bug in javac.
Comment 2 Remy Maucherat 2005-06-16 11:26:28 UTC
*** Bug 35266 has been marked as a duplicate of this bug. ***
Comment 3 Mike B 2005-07-11 21:27:55 UTC
To work around this bug in OS X 10.4, rename or move the offending *.jnilib files.
Comment 4 Pratik Solanki 2005-07-15 19:51:05 UTC
Bug filed with Sun

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6295519
Comment 5 Yoav Shapira 2005-09-01 20:39:10 UTC
Are you suggesting we change Jasper to only add files ending in .jar to the
classpath?
Comment 6 Niels Castle Andersen 2005-09-01 22:20:37 UTC
(In reply to comment #5)
> Are you suggesting we change Jasper to only add files ending in .jar to the classpath?

I bet adding only files ending in jar would break a lot of stuff.

Is it possible to catch the exceptions thrown when opening broken files from the classpath and simply log 
an error message?

Not a purist solution but it would allow Jasper to continue to function in most cases.
Comment 7 Pratik Solanki 2005-09-07 04:11:25 UTC
> (In reply to comment #5)
> Are you suggesting we change Jasper to only add files ending in .jar to the
classpath?

Yes. .jar and .zip

(In reply to comment #6)
> I bet adding only files ending in jar would break a lot of stuff.

Why would it break stuff? Are class files ever found in a non-.zip/.jar file?
The only situation I can think of is if someone has a zip file named a.foo, i.e.
the file is a zip file, but the extension is not .zip.

If you did have such a situation on Windows/Solaris/Linux, you would already
have seen failures there (with 1.5). If the only platform we're concerned about
is the Mac then I would say it's safe to add just .zip and .jar.

Alternatively, you could go in the opposite direction and exclude all
.jnilib/.dylib files (as a hack). That may work depending on what the user has
lying the directory.

More fundamentally, why do we explicitly add all the files found in
/System/Library/Java/Extensions directory to the classpath? The JVM on MacOS
will automatically pick up those jars so yet another option may be to just
ignore that directory while creating the huge classpath.

Thinking on these lines some more... it strikes me that
/System/Library/Java/Extensions is part of the java.ext.dir system property. Any
jar/zip file found in java.ext.dir will be automatically picked up by the VM
during compilation/execution. What this means is that you can generalize your
solution by not adding any of the files in the directories specified by
java.ext.dir to the classpath. See
<http://developer.apple.com/releasenotes/Java/Java131MOSX10.1RN/index.html#JavaExtensions>
(old 1.3.1 release notes but I'm sure the text is still valid for 1.5)

----
Java extension locations

Java can be extended by adding custom jar, zip, and class files, as well as
native JNI libraries, in the location specified by the java.ext.dir property. In
Mac OS X 10.0, this property pointed to
/System/Library/Frameworks/JavaVM.framework/Versions/1.3/Home/lib/ext, and many
third party applications placed their extensions there. There are two problems
with this scheme: installing files in the System domain requires administrative
privileges; and the extensions are tied to a specific version of the JDK.

In Mac OS X 10.1, java.ext.dir has been changed to contain a list of
directories, and several additional locations for saving extensions have been
added. This new scheme makes it possible to override extensions, and provides
distinct locations for third party extensions, Apple extensions, and Sun JDK
extensions. By default, Java searches for extensions, in order, in the following
directories:

   1. User’s home directory (~/Library/Java/Extensions/)
   2. Local domain (/Library/Java/Extensions/)
   3. Network domain (/Network/Library/Java/Extensions/)
   4. System domain (/System/Library/Java/Extensions/)
   5. $JAVA_HOME
(/System/Library/Frameworks/JavaVM.framework/Versions/Current/Home/lib/ext/)

In general, third party developers should install extensions in the Local
domain. Apple extensions, such as QTJava.zip, are installed in the System
domain, and Sun JDK extensions are installed in $JAVA_HOME.
-----

> Is it possible to catch the exceptions thrown when opening broken files from
the classpath and simply log 
> an error message?

Not sure if it would work but it might be worth a shot.
Comment 8 Pratik Solanki 2005-09-07 04:14:28 UTC
btw, this is a Mac OS X 10.4 only bug (since there's no J2SE5.0 on 10.3).
Someone needs to add 10.4 to the list of OSes.
Comment 9 Pratik Solanki 2005-10-05 07:16:32 UTC
J2SE 5.0 Release 3 Developer Preview 2 is out which has a fix for this bug. If
someone is an ADC member, could they download (from http://connect.apple.com)
and test this release to see if this bug is fixed.
Comment 10 Pratik Solanki 2005-10-31 03:53:56 UTC
J2SE 5.0 DP4 is available at http://connect.apple.com and has a fix for this
bug. It would be really good if someone (need to be an ADC member) could verify
this bug so we know it's fixed.
Comment 11 Mark Thomas 2006-09-24 16:26:19 UTC
Closing this as INVALID since it is not a Tomcat issue.