/*
* 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", "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);
}
}