| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * 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 |
| * |
| * 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 |
| * limitations under the License. |
| */ |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.lang.reflect.Method; |
| |
| public class Main { |
| public static void main(String[] args) { |
| System.loadLibrary(args[0]); |
| |
| testGetFieldId(TestClass.class, "intField", ""); |
| testGetFieldId(TestClass.class, "intField", "I"); |
| testGetFieldId(TestClass.class, "intField", "int"); |
| testGetFieldId(TestClass.class, "intField", "Lint;"); |
| testGetFieldId(TestClass.class, "stringField", "I"); |
| testGetFieldId(TestClass.class, "stringField", "Ljava/lang/String;"); |
| testGetFieldId(TestClass.class, "stringField", "java/lang/String"); |
| testGetFieldId(TestClass.class, "stringField", "Ljava.lang.String;"); |
| testGetFieldId(TestClass.class, "stringField", "java.lang.String"); |
| |
| try { |
| Method get = Main.class.getDeclaredMethod("getFieldId", |
| Class.class, |
| String.class, |
| String.class); |
| MyClassLoader loader = new MyClassLoader(Main.class.getClassLoader()); |
| Class<?> otherMain = Class.forName("Main", true, loader); |
| Method m = otherMain.getDeclaredMethod("testClassLoading", Method.class); |
| m.invoke(null, get); |
| } catch (Throwable t) { |
| t.printStackTrace(System.out); |
| } |
| } |
| |
| public static void testClassLoading(Method get) throws Exception { |
| System.out.println("Test that MyClassLoader.loadClass(\"Bad.Class\") shall not be called."); |
| String[] bad_class_names = { "Bad/Class", "Bad.Class", "LBad.Class;" }; |
| for (String signature : bad_class_names) { |
| try { |
| get.invoke(null, TestClass.class, "bogus", signature); |
| System.out.println("FAIL!"); |
| } catch (InvocationTargetException ite) { |
| if (!(ite.getCause() instanceof NoSuchFieldError) || |
| !(ite.getCause().getCause() instanceof NoClassDefFoundError)) { |
| throw ite; |
| } |
| NoClassDefFoundError ncdfe = (NoClassDefFoundError) ite.getCause().getCause(); |
| System.out.println(" Error message for " + signature + ": " + ncdfe.getMessage()); |
| } |
| } |
| } |
| |
| public static void testGetFieldId(Class<?> cls, String name, String signature) { |
| System.out.println("getFieldId(" + cls + ", \"" + name + "\", \"" + signature + "\")"); |
| try { |
| boolean result = getFieldId(cls, name, signature); |
| System.out.println("Result: " + result); |
| } catch (Throwable t) { |
| System.out.println("Caught " + DescribeThrowable(t)); |
| for (Throwable cause = t.getCause(); cause != null; cause = cause.getCause()) { |
| System.out.println(" caused by " + DescribeThrowable(cause)); |
| } |
| } |
| } |
| |
| public static String DescribeThrowable(Throwable t) { |
| return PRINT_MESSAGE ? t.getClass().getName() + ": " + t.getMessage() |
| : t.getClass().getName(); |
| } |
| |
| public static native boolean getFieldId(Class<?> cls, String name, String signature); |
| |
| // Set to true to see actual messages. |
| public static final boolean PRINT_MESSAGE = false; |
| } |
| |
| class TestClass { |
| public int intField; |
| public String stringField; |
| } |
| |
| class MyClassLoader extends DefiningLoader { |
| public MyClassLoader(ClassLoader parent) { |
| super(parent); |
| } |
| |
| public Class<?> loadClass(String name) throws ClassNotFoundException |
| { |
| if (name.equals("Bad.Class")) { |
| throw new Error("findClass(\"Bad.Class\")"); |
| } |
| return super.loadClass(name); |
| } |
| } |