Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8076264

[macosx] Launching app on MacOSX requires enclosing class

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3
    • 9
    • None
    • client-libs
    • b65
    • x86
    • os_x

    Backports

      Description

        If you create a jar file on Mac that contains a nested static main class but not its enclosing class file, attempting to execute it via "java -jar" will fail, but on Linux it will succeed. The two behaviors should be identical (WORA). Since Linux can successfully execute without the enclosing class, Mac should probably be fixed to be identical.

        Here's one way to create such a jar file:

        Apply this patch, then run the test via jtreg

        diff --git a/test/java/util/zip/EntryCount64k.java b/test/java/util/zip/EntryCount64k.java
        --- a/test/java/util/zip/EntryCount64k.java
        +++ b/test/java/util/zip/EntryCount64k.java
        @@ -56,13 +56,12 @@
         
             static final String MAIN_CLASS = "EntryCount64k$Main";
             static final String THIS_CLASS = "EntryCount64k";
        - static final String[] SPECIAL_CLASSES = { MAIN_CLASS, THIS_CLASS };
        - // static final String[] SPECIAL_CLASSES = { MAIN_CLASS };
        + // static final String[] SPECIAL_CLASSES = { MAIN_CLASS, THIS_CLASS };
        + static final String[] SPECIAL_CLASSES = { MAIN_CLASS };
             static final int SPECIAL_COUNT = 1 + SPECIAL_CLASSES.length;
         
             public static void main(String[] args) throws Throwable {
        - for (int i = (1 << 16) - 3; i < (1 << 16) + 2; i++)
        - test(i);
        +test(3);
             }
         
             static void test(int entryCount) throws Throwable {
        @@ -109,13 +108,13 @@
                 checkCanRead(zipFile, entryCount);
                 if (shouldUseZip64 != usesZip64)
                     throw new Error(details);
        - zipFile.delete();
        + // zipFile.delete();
             }
         
             static boolean usesZip64(File zipFile) throws Exception {
                 RandomAccessFile raf = new RandomAccessFile(zipFile, "r");
                 byte[] buf = new byte[4096];
        - raf.seek(raf.length() - buf.length);
        + raf.seek(Math.max(0, raf.length() - buf.length));
                 raf.read(buf);
                 for (int i = 0; i < buf.length - 4; i++) {
                     // Look for ZIP64 End Header Signature


        The test will fail with

         stderr: [Error: A JNI error has occurred, please check your installation and try again
        Exception in thread "main" java.lang.NoClassDefFoundError: EntryCount64k
        at java.lang.Class.getDeclaringClass0(Native Method)
        at java.lang.Class.getDeclaringClass(Class.java:1281)
        at java.lang.Class.getEnclosingClass(Class.java:1323)
        at java.lang.Class.getCanonicalName(Class.java:1438)
        Caused by: java.lang.ClassNotFoundException: EntryCount64k
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:262)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
        ... 4 more
        ]

        The resulting jar file looks like:

        $ jar tvf test/JTwork/scratch/EntryCount64k-tmp.zip
            53 Mon Mar 30 10:42:12 PDT 2015 META-INF/MANIFEST.MF
           477 Mon Mar 30 10:42:12 PDT 2015 EntryCount64k$Main.class
             0 Mon Mar 30 10:42:12 PDT 2015 2

        Executing it on Mac gives:

        $ java -jar test/JTwork/scratch/EntryCount64k-tmp.zip
        Error: A JNI error has occurred, please check your installation and try again
        Exception in thread "main" java.lang.NoClassDefFoundError: EntryCount64k
        at java.lang.Class.getDeclaringClass0(Native Method)
        at java.lang.Class.getDeclaringClass(Class.java:1235)
        at java.lang.Class.getEnclosingClass(Class.java:1277)
        at java.lang.Class.getCanonicalName(Class.java:1392)
        Caused by: java.lang.ClassNotFoundException: EntryCount64k
        at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
        ... 4 more


        If you copy the jar file to Linux, it succeeds:

         $ java -jar /tmp/EntryCount64k-tmp.zip
        Main

        Attachments

          Issue Links

            Activity

              People

                serb Sergey Bylokhov
                martin Martin Buchholz
                Votes:
                0 Vote for this issue
                Watchers:
                8 Start watching this issue

                Dates

                  Created:
                  Updated:
                  Resolved: