Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8168448 | 9 | Ioi Lam | P3 | Resolved | Fixed | b146 |
For the case where a class has an initialization error, the class is already linked so this code is wrong in link_class_impl:
// check for error state. This is checking for the wrong state.
// If initialization_error, then this class *was* linked.
if (this_k->is_in_error_state()) {
ResourceMark rm(THREAD);
THROW_MSG_(vmSymbols::java_lang_NoClassDefFoundError(),
this_k->external_name(), false);
}
There is nothing in the spec that says to throw NCDFE for link time exceptions. This also prevents linking interfaces that extend interfaces that have had initialization errors, which is also legal in the spec. In the JLS 12.4.2 step 7, implies that initialization errors in interfaces do not affect other interfaces. Linking interfaces should not be dependent on initialization state either (there's nothing in the spec about this).
Here's a test program that demonstrates this.
--- begin source ---
class Test {
static Object someMethod() { throw new RuntimeException("initialization_error"); }
static boolean out(String s) { System.out.println(s); return true; }
// K interface with a default method has an initialization error
interface K {
static final Object CONST = someMethod();
default int method() { return 2; }
}
// Iunlinked is not linked when K gets an initialization error. Linking Iunlinked should not
// get NoClassDefFoundError because it does not depend on the initialization state of K for
// linking. There's bug now where it does, filed separately.
interface Iunlinked extends K {
boolean v = out("Iunlinked");
}
static class C implements K {}
public static void main(java.lang.String[] unused) {
try {
C c = new C();
} catch (ExceptionInInitializerError e) {
System.out.println("this is expected");
}
boolean b = Iunlinked.v; // should not fail!
}
}
--- end source ---
I tested the jvm with removing the code above and everything passes, except CDS uses initialization_error state for some purpose that I can't unwind right now. See linked bug for more.
Suggested fix is to create a state < linked and use this in the CDS code. You can't use initialization_error.
- backported by
-
JDK-8168448 NoClassDefFoundError should not be thrown if class is in_error_state at link time
-
- Resolved
-
- relates to
-
JDK-8163969 Cyclic interface initialization causes JVM crash
-
- Resolved
-