Skip to content

ClassInfoException when running tests - Java 10 #94

@gayanW

Description

@gayanW

Tests executes through JPF fails with ClassInfoException when running under Java 9/10.

Example: Running gov.nasa.jpf.test.basic.HarnessTest

[junit] gov.nasa.jpf.vm.ClassInfoException: class not found: java.io.Serializable
[junit]     at gov.nasa.jpf.vm.ClassLoaderInfo.getResolvedClassInfo(ClassLoaderInfo.java:363)
[junit]     at gov.nasa.jpf.vm.SystemClassLoaderInfo.getResolvedClassInfo(SystemClassLoaderInfo.java:147)
[junit]     at gov.nasa.jpf.vm.SystemClassLoaderInfo.loadClass(SystemClassLoaderInfo.java:182)
[junit]     at gov.nasa.jpf.vm.ClassInfo.resolveReferencedClass(ClassInfo.java:2414)
[junit]     at gov.nasa.jpf.vm.ClassInfo.loadInterfaces(ClassInfo.java:2366)
[junit]     at gov.nasa.jpf.vm.ClassInfo.resolveClass(ClassInfo.java:2383)
[junit]     at gov.nasa.jpf.vm.ClassInfo.resolveAndLink(ClassInfo.java:548)
[junit]     at gov.nasa.jpf.jvm.JVMClassInfo.<init>(JVMClassInfo.java:624)
[junit]     at gov.nasa.jpf.jvm.JVMClassFileContainer$JVMClassFileMatch.createClassInfo(JVMClassFileContainer.java:58)
[junit]     at gov.nasa.jpf.jvm.JVMClassFileContainer$JVMClassFileMatch.createClassInfo(JVMClassFileContainer.java:33)
[junit]     at gov.nasa.jpf.vm.ClassLoaderInfo.getResolvedClassInfo(ClassLoaderInfo.java:353)
[junit]     at gov.nasa.jpf.vm.SystemClassLoaderInfo.getResolvedClassInfo(SystemClassLoaderInfo.java:147)
[junit]     at gov.nasa.jpf.vm.VM.getStartupSystemClassInfos(VM.java:445)
[junit]     at gov.nasa.jpf.vm.VM.initializeMainThread(VM.java:564)
[junit]     at gov.nasa.jpf.vm.SingleProcessVM.initialize(SingleProcessVM.java:130)
[junit]     at gov.nasa.jpf.JPF.run(JPF.java:611)
[junit]     at gov.nasa.jpf.util.test.TestJPF.createAndRunJPF(TestJPF.java:675)
[junit]     at gov.nasa.jpf.util.test.TestJPF.unhandledException(TestJPF.java:849)
[junit]     at gov.nasa.jpf.util.test.TestJPF.verifyUnhandledException(TestJPF.java:903)
[junit]     at gov.nasa.jpf.test.basic.HarnessTest.verifyNullPointerException(HarnessTest.java:54)

ClassInfoException is thrown in here:

/**
* obtain ClassInfo object for given class name
*
* if the requested class or any of its superclasses and interfaces
* is not found this method will throw a ClassInfoException. Loading
* of respective superclasses and interfaces happens recursively from here.
*
* Returned ClassInfo objects are not registered yet, i.e. still have to
* be added to the ClassLoaderInfo's statics, and don't have associated java.lang.Class
* objects until registerClass(ti) is called.
*
* Before any field or method access, the class also has to be initialized,
* which can include overlayed execution of &lt;clinit&gt; declaredMethods, which is done
* by calling initializeClass(ti,insn)
*
* this is for loading classes from the file system
*/
public ClassInfo getResolvedClassInfo (String className) throws ClassInfoException {
String typeName = Types.getClassNameFromTypeName( className);
ClassInfo ci = resolvedClasses.get( typeName);
if (ci == null) {
if (ClassInfo.isBuiltinClass( typeName)){
ci = loadSystemClass( typeName);
} else {
ClassFileMatch match = getMatch( typeName);
if (match != null){
String url = match.getClassURL();
ci = loadedClasses.get( url); // have we loaded the class from this source before
if (ci != null){
if (ci.getClassLoaderInfo() != this){ // might have been loaded by another classloader
ci = ci.cloneFor(this);
}
} else {
try {
log.info("loading class ", typeName, " from ", url);
ci = match.createClassInfo(this);
} catch (ClassParseException cpx){
throw new ClassInfoException( "error parsing class", this, "java.lang.NoClassDefFoundError", typeName, cpx);
}
loadedClasses.put( url, ci);
}
} else { // no match found
throw new ClassInfoException("class not found: " + typeName, this, "java.lang.ClassNotFoundException", typeName);
}
}
setAttributes(ci);
resolvedClasses.put(typeName, ci);
}
return ci;
}

Possible causes

As stated in the JDK 9 Release Notes the system property sun.boot.class.path has been removed. This makes JPF to fail resolve standard Java classes.

// finally, we load from the standard Java libraries
v = System.getProperty("sun.boot.class.path");
if (v != null) {
buf.append(v);
}

References
http://www.oracle.com/technetwork/java/javase/9-relnote-issues-3704069.html
https://stackoverflow.com/q/50451536/3647002


Implementation for the class URL generation would also need to be updated.

@Override
public String getClassURL (String typeName){
return getURL() + typeName.replace('.', '/') + ".class";
}

In the earlier versions path to standard class would be like:

jar:file:/path/to/jjre/lib/rt.jar!/java/lang/Object.class

With the module system:

jrt:/java.base/java/lang/Object.class

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions