From: rtrimana Date: Fri, 5 Jul 2019 19:01:56 +0000 (-0700) Subject: Moving recursive lookup for defineClass0 just in the native method itself; messing... X-Git-Url: http://plrg.eecs.uci.edu/git/?p=jpf-core.git;a=commitdiff_plain;h=182324e618ad879c926c3f5f39789f165270eb89 Moving recursive lookup for defineClass0 just in the native method itself; messing up with the ClassLoaderInfo could potentially harm the URLClassLoader class and other class-loading mechanisms in JPF. --- diff --git a/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java b/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java index 63c3c88..b328587 100644 --- a/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java +++ b/src/main/gov/nasa/jpf/vm/ClassLoaderInfo.java @@ -360,13 +360,7 @@ public class ClassLoaderInfo } } else { // no match found - // TODO: Fix for Groovy's model-checking - // TODO: May need to do a recursive lookup - if (parent != null) { - return parent.getResolvedClassInfo(typeName); - } else { - throw new ClassInfoException("class not found: " + typeName, this, "java.lang.ClassNotFoundException", typeName); - } + throw new ClassInfoException("class not found: " + typeName, this, "java.lang.ClassNotFoundException", typeName); } } @@ -591,11 +585,6 @@ public class ClassLoaderInfo } } } - // TODO: Fix for Groovy's model-checking - // TODO: May need to do a recursive lookup - if (parent != null) { - return parent.loadClass(typeName); - } // initiate the roundtrip & bail out pushloadClassFrame(typeName); diff --git a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java index 98a8dd4..25a1dcf 100644 --- a/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java +++ b/src/peers/gov/nasa/jpf/vm/JPF_java_lang_ClassLoader.java @@ -128,17 +128,19 @@ public class JPF_java_lang_ClassLoader extends NativePeer { return ci.getClassObjectRef(); } + // TODO: Fix for Groovy's model-checking + // TODO: Load the SystemClassLoader if this ClassLoader fails, but just get it if it is already defined! + // TODO: This is needed for sun.reflect.GroovyMagic and some other classes @MJI public int defineClass0__Ljava_lang_String_2_3BII__Ljava_lang_Class_2 (MJIEnv env, int objRef, int nameRef, int bufferRef, int offset, int length) { String cname = env.getStringObject(nameRef); ClassLoaderInfo cl = env.getClassLoaderInfo(objRef); - // determine whether that the corresponding class is already defined by this - // classloader, if so, this attempt is invalid, and loading throws a LinkageError + // determine whether that the corresponding class is already defined by this + // classloader, if so, just return the already defined class! if (cl.getDefinedClassInfo(cname) != null) { // attempt to define twice - env.throwException("java.lang.LinkageError"); - return MJIEnv.NULL; + return cl.getDefinedClassInfo(cname).getClassObjectRef(); } byte[] buffer = env.getByteArrayObject(bufferRef); @@ -154,13 +156,32 @@ public class JPF_java_lang_ClassLoader extends NativePeer { ci.registerClass(ti); return ci.getClassObjectRef(); - + + } catch (LoadOnJPFRequired rre) { + return searchThroughSystemClassLoader(env, objRef, nameRef, bufferRef, offset, length); + } catch (ClassInfoException cix){ + if (cix.getExceptionClass().equals("java.lang.ClassNotFoundException")) { + return searchThroughSystemClassLoader(env, objRef, nameRef, bufferRef, offset, length); + } env.throwException("java.lang.ClassFormatError"); return MJIEnv.NULL; + } } + private int searchThroughSystemClassLoader + (MJIEnv env, int objRef, int nameRef, int bufferRef, int offset, int length) { + + int sysObjRef = env.getSystemClassLoaderInfo().getClassLoaderObjectRef(); + if (objRef != sysObjRef) { + return defineClass0__Ljava_lang_String_2_3BII__Ljava_lang_Class_2 + (env, sysObjRef, nameRef, bufferRef, offset, length); + } + env.throwException("java.lang.ClassNotFoundException"); + return MJIEnv.NULL; + } + protected static boolean check(MJIEnv env, String cname, byte[] buffer, int offset, int length) { // throw SecurityExcpetion if the package prefix is java diff --git a/src/tests/gov/nasa/jpf/test/java/lang/ClassLoaderTest.java b/src/tests/gov/nasa/jpf/test/java/lang/ClassLoaderTest.java index 5e164fc..5899d2b 100644 --- a/src/tests/gov/nasa/jpf/test/java/lang/ClassLoaderTest.java +++ b/src/tests/gov/nasa/jpf/test/java/lang/ClassLoaderTest.java @@ -6,13 +6,13 @@ * The Java Pathfinder core (jpf-core) platform is licensed under the * Apache License, Version 2.0 (the "License"); you may not use this file except * in compliance with the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0. + * + * http://www.apache.org/licenses/LICENSE-2.0. * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and + * See the License for the specific language governing permissions and * limitations under the License. */ package gov.nasa.jpf.test.java.lang; @@ -30,7 +30,7 @@ import org.junit.Test; * test of java.lang.ClassLoader API */ public class ClassLoaderTest extends TestJPF { - + @Test public void testGetResource() { if(verifyNoPropertyViolation()) { @@ -128,7 +128,7 @@ public class ClassLoaderTest extends TestJPF { public void testFoundResources() throws IOException { if(verifyNoPropertyViolation()) { TestClassLoader classLoader = new TestClassLoader(); - Enumeration enm = classLoader.findResources("not_existing_resource"); + Enumeration enm = classLoader.findResources("not_existing_resource"); assertNotNull(enm); assertFalse(enm.hasMoreElements()); } @@ -168,7 +168,7 @@ public class ClassLoaderTest extends TestJPF { } class TestClassLoader extends ClassLoader { - + public TestClassLoader() { super(); } @@ -178,8 +178,8 @@ public class ClassLoaderTest extends TestJPF { } @Override - protected Enumeration findResources(String name) throws IOException { + protected Enumeration findResources(String name) throws IOException { return super.findResources(name); } } -} +} \ No newline at end of file