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

[macosx] Launching app on MacOSX requires enclosing class

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: None
    • Fix Version/s: 9
    • Component/s: client-libs
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b65
    • CPU:
      x86
    • OS:
      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

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

                  Dates

                  • Created:
                    Updated:
                    Resolved: