JDK-8187436 : -Xbootclasspath/a causes sanity check assertion with exploded build
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 10
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2017-09-11
  • Updated: 2019-05-22
  • Resolved: 2017-09-26
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 10
10 b31Fixed
Related Reports
Relates :  
Relates :  
Description
Consider the following test:

package p;

public class Test {
    public static void main(String[] args) throws Exception {
        Package p = Test.class.getPackage();
    }
}

mkdir bootclasses
javac -d bootclasses Test.java
java -Xbootclasspath/a:bootclasses p.Test

With an exploded build then this trips up on an assert in classLoader.hpp:

#  Internal Error (hotspot/src/share/vm/classfile/classLoader.hpp:403), pid=49574, tid=5123
#  assert(n >= 0 && n < _num_entries) failed: sanity

Assertion was added as part of JDK-8072061.
Comments
The handling of the (boot) classpath entries is kind of complicated with CDS (because we are appending the app classpath to the boot classpath during dump time), but that shouldn't be necessary because we have already switched to using the Java loaders during dump time. I think the proper fix is to clean up CDS, as well as other use of classpath_entry. For example, this special case: if (n == 0) { assert(has_jrt_entry(), "No class path entry at 0 for exploded module builds"); return ClassLoader::_jrt_entry; } else { ClassLoader::_jrt_entry should be the head of the list, so we shouldn't need to have this special case. Not sure how urgent JDK-8187436 is. We can put in an urgent fix like the one Harold proposed, but we should do the proper clean up afterwards.
13-09-2017

If _num_entries is for CDS only then should be only compiled in with if INCLUDE_CDS? As it stands it does get incremented with exploded builds, it is just out by one.
13-09-2017

It looks like _num_entries is only used by CDS, which is not supported with exploded builds. So, it probably does not matter what is done to _num_entries for the exploded build. Perhaps change the assert to: - assert(n >= 0 && n < _num_entries, "sanity"); + assert(n >= 0, "sanity"); + assert(!has_jrt_entry() || n < _num_entries, "sanity");
13-09-2017

The alternative is to bump _num_entries when in an exploded build.
13-09-2017

Perhaps just the assert needs to change: diff --git a/src/share/vm/classfile/classLoader.hpp b/src/share/vm/classfile/classLoader.hpp --- a/src/share/vm/classfile/classLoader.hpp +++ b/src/share/vm/classfile/classLoader.hpp @@ -403,7 +403,8 @@ static int compute_Object_vtable(); static ClassPathEntry* classpath_entry(int n) { - assert(n >= 0 && n < _num_entries, "sanity"); + assert(n >= 0, "sanity"); + assert(n < _num_entries || (n == _num_entries && !has_jrt_entry()), "sanity"); if (n == 0) { assert(has_jrt_entry(), "No class path entry at 0 for exploded module builds"); return ClassLoader::_jrt_entry; Note that AppCDS does not work with exploded builds.
12-09-2017