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

NoClassDefFoundError after failed new StreamEncoder(out, lock, Charset.defaultCh

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Won't Fix
    • Icon: P4 P4
    • 8-pool
    • 6, 6u14
    • core-libs

        FULL PRODUCT VERSION :
        java version "1.6.0_03"
        Java(TM) SE Runtime Environment (build 1.6.0_03-b05)
        Java HotSpot(TM) Client VM (build 1.6.0_03-b05, mixed mode)


        ADDITIONAL OS VERSION INFORMATION :
        Windows XP SR-2

        EXTRA RELEVANT SYSTEM CONFIGURATION :
        - default platform is JDK 6u11
        - Run with NetBeans 6.5 using JDK 6u11
        - configure platform JDK 6u03 for execution of user code
        - add sources in C:\Programme\Java\jdk1.6.0_03\src\j2se\src\share\classes from jdk-6u3-fcs-src-b05-jrl-24_sep_2007.jar to platform library
        - CompileOnSave enabled


        A DESCRIPTION OF THE PROBLEM :
        See following soure snippet from sun.nio.cs.StreamEncoder:
        (https://java-nio-charset-enhanced.dev.java.net/source/browse/java-nio-charset-enhanced/trunk/src/sun/nio/cs/StreamEncoder.java?rev=568&view=markup)

            public static StreamEncoder forOutputStreamWriter(OutputStream out,
                    Object lock, String charsetName) throws UnsupportedEncodingException {
                try {
                    return new StreamEncoder(out, lock, (charsetName == null) ?
                            Charset.defaultCharset() : Charset.forName(charsetName));
        } catch (IllegalCharsetNameException icne) {
                    throw new UnsupportedEncodingException (icne.getCharsetName());
                }
            }

        Running this code results in UnsatisfiedLinkError during startup of the VM, because via setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); in System.initializeSystemClass() sun.nio.cs.StreamEncoder.forOutputStreamWriter(...) is invoked, which tries to load system default charset by Charset.defaultCharset().
        Charset.defaultCharset() in my project is running into code, which needs to open jar-file. The UnsatisfiedLinkError is thrown, because zip library is not loaded at this time (loadLibrary("zip"); will be invoked after setOut0(new PrintStream(new BufferedOutputStream(fdOut, 128), true)); in System.initializeSystemClass()).

        So I tried to catch this UnsatisfiedLinkError, and open new StreamEncoder by STARTUP_CHARSET, which doesn't need to load data from jar file:

                try {
                    return new StreamEncoder(out, lock, (charsetName == null) ?
                            Charset.defaultCharset() : Charset.forName(charsetName));
        } catch (IllegalCharsetNameException icne) {
                    throw new UnsupportedEncodingException (icne.getCharsetName());
        } catch (Error er) { // doesn't work, file bug report
        // if (sun.misc.VM.isBooted())
        // throw er;
                    return new StreamEncoder(out, lock, STARTUP_CHARSET);
                }

        Running this code results in NoClassDefFoundError (see Error Message(e) section) although opening jar file isn't needed for STARTUP_CHARSET, checking sun.misc.VM.isBooted() doesn't help.
        IMO this is a bug, because opening new StreamDecoder via STARTUP_CHARSET before trying it via Charset.defaultCharset() works without problems (see following source snippet).

                try {
                    return (sun.misc.VM.isBooted() && (STARTUP_CHARSET = null) == null) // STARTUP_CHARSET is no more needed after VM is booted
                        ? new StreamEncoder(out, lock, (charsetName == null) ?
                            Charset.defaultCharset() : Charset.forName(charsetName))
                        // workaround to avoid startup endless loop:
                        : new StreamEncoder(out, lock, STARTUP_CHARSET);
        } catch (IllegalCharsetNameException icne) {
                    throw new UnsupportedEncodingException (icne.getCharsetName());
                }

        Failed opening new StreamEncoder via Charset.defaultCharset() seems to set system to bad unusable state, because new StreamEncoder(out, lock, STARTUP_CHARSET) in catch block (see 2nd source snippet) doesn't work anymore, which will work if invoked at first (see 3rd source snippet).


        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        - checkout sources from (use trunk, revision 568):
        https://java-nio-charset-enhanced.dev.java.net/source/browse/java-nio-charset-enhanced/?diff_format=s&rev=568
        - Clean&Build project
        - Run test sun\nio\cs\CharsetsTest.java


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        new StreamEncoder(out, lock, STARTUP_CHARSET) in catch block should run, too, if new StreamEncoder(out, lock, Charset.defaultCharset()) failed before.
        ACTUAL -
        java.lang.NoClassDefFoundError

        ERROR MESSAGES/STACK TRACES THAT OCCUR :
        java.lang.NoClassDefFoundError: Could not initialize class java.util.jar.JarFile
                at sun.misc.URLClassPath$JarLoader.getJarFile(URLClassPath.java:643)
                at sun.misc.URLClassPath$JarLoader.access$600(URLClassPath.java:538)
                at sun.misc.URLClassPath$JarLoader$1.run(URLClassPath.java:605)
                at java.security.AccessController.doPrivileged(Native Method)
                at sun.misc.URLClassPath$JarLoader.ensureOpen(URLClassPath.java:597)
                at sun.misc.URLClassPath$JarLoader.<init>(URLClassPath.java:581)
                at sun.misc.URLClassPath$3.run(URLClassPath.java:331)
                at java.security.AccessController.doPrivileged(Native Method)
                at sun.misc.URLClassPath.getLoader(URLClassPath.java:320)
                at sun.misc.URLClassPath.getLoader(URLClassPath.java:297)
                at sun.misc.URLClassPath.getResource(URLClassPath.java:167)
                at java.net.URLClassLoader$1.run(URLClassLoader.java:192)
                at java.security.AccessController.doPrivileged(Native Method)
                at java.net.URLClassLoader.findClass(URLClassLoader.java:188)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
                at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:276)
                at java.lang.ClassLoader.loadClass(ClassLoader.java:251)
                at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)
        Exception in thread "main"
        Test sun.nio.cs.CharsetsTest FAILED (crashed)
        test:
        BUILD SUCCESSFUL (total time: 0 seconds)


        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------
        https://java-nio-charset-enhanced.dev.java.net/source/browse/java-nio-charset-enhanced/trunk/src/sun/nio/cs/StreamEncoder.java?rev=568&view=markup
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
                try {
                    return (sun.misc.VM.isBooted() && (STARTUP_CHARSET = null) == null) // STARTUP_CHARSET is no more needed after VM is booted
                        ? new StreamEncoder(out, lock, (charsetName == null) ?
                            Charset.defaultCharset() : Charset.forName(charsetName))
                        // workaround to avoid startup endless loop:
                        : new StreamEncoder(out, lock, STARTUP_CHARSET);
        } catch (IllegalCharsetNameException icne) {
                    throw new UnsupportedEncodingException (icne.getCharsetName());
                }

              sherman Xueming Shen
              ndcosta Nelson Dcosta (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: