Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (C) 2017 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 import java.lang.reflect.InvocationTargetException;
     18 import java.lang.reflect.Method;
     19 
     20 public class Main {
     21     public static void main(String[] args) {
     22         System.loadLibrary(args[0]);
     23 
     24         testGetFieldId(TestClass.class, "intField", "I");
     25         testGetFieldId(TestClass.class, "intField", "int");
     26         testGetFieldId(TestClass.class, "intField", "Lint;");
     27         testGetFieldId(TestClass.class, "stringField", "I");
     28         testGetFieldId(TestClass.class, "stringField", "Ljava/lang/String;");
     29         testGetFieldId(TestClass.class, "stringField", "java/lang/String");
     30         testGetFieldId(TestClass.class, "stringField", "Ljava.lang.String;");
     31         testGetFieldId(TestClass.class, "stringField", "java.lang.String");
     32 
     33         try {
     34             Method get = Main.class.getDeclaredMethod("getFieldId",
     35                                                       Class.class,
     36                                                       String.class,
     37                                                       String.class);
     38             MyClassLoader loader = new MyClassLoader(Main.class.getClassLoader());
     39             Class<?> otherMain = Class.forName("Main", true, loader);
     40             Method m = otherMain.getDeclaredMethod("testClassLoading", Method.class);
     41             m.invoke(null, get);
     42         } catch (Throwable t) {
     43             t.printStackTrace(System.out);
     44         }
     45     }
     46 
     47     public static void testClassLoading(Method get) throws Exception {
     48         System.out.println("Test that MyClassLoader.loadClass(\"Bad.Class\") shall not be called.");
     49         String[] bad_class_names = { "Bad/Class", "Bad.Class", "LBad.Class;" };
     50         for (String signature : bad_class_names) {
     51             try {
     52                 get.invoke(null, TestClass.class, "bogus", signature);
     53                 System.out.println("FAIL!");
     54             } catch (InvocationTargetException ite) {
     55                 if (!(ite.getCause() instanceof NoSuchFieldError) ||
     56                     !(ite.getCause().getCause() instanceof NoClassDefFoundError)) {
     57                   throw ite;
     58                 }
     59                 NoClassDefFoundError ncdfe = (NoClassDefFoundError) ite.getCause().getCause();
     60                 System.out.println("  Error message for " + signature + ": " + ncdfe.getMessage());
     61             }
     62         }
     63     }
     64 
     65     public static void testGetFieldId(Class<?> cls, String name, String signature) {
     66         System.out.println("getFieldId(" + cls + ", \"" + name + "\", \"" + signature + "\")");
     67         try {
     68             boolean result = getFieldId(cls, name, signature);
     69             System.out.println("Result: " + result);
     70         } catch (Throwable t) {
     71             System.out.println("Caught " + DescribeThrowable(t));
     72             for (Throwable cause = t.getCause(); cause != null; cause = cause.getCause()) {
     73                 System.out.println("  caused by " + DescribeThrowable(cause));
     74             }
     75         }
     76     }
     77 
     78     public static String DescribeThrowable(Throwable t) {
     79         return PRINT_MESSAGE ? t.getClass().getName() + ": " + t.getMessage()
     80                              : t.getClass().getName();
     81     }
     82 
     83     public static native boolean getFieldId(Class<?> cls, String name, String signature);
     84 
     85     // Set to true to see actual messages.
     86     public static final boolean PRINT_MESSAGE = false;
     87 }
     88 
     89 class TestClass {
     90     public int intField;
     91     public String stringField;
     92 }
     93 
     94 class MyClassLoader extends DefiningLoader {
     95   public MyClassLoader(ClassLoader parent) {
     96       super(parent);
     97   }
     98 
     99   public Class<?> loadClass(String name) throws ClassNotFoundException
    100   {
    101       if (name.equals("Bad.Class")) {
    102           throw new Error("findClass(\"Bad.Class\")");
    103       }
    104       return super.loadClass(name);
    105   }
    106 }
    107