1 /* 2 * Copyright (C) 2008 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.io.File; 18 import java.io.IOException; 19 import java.lang.reflect.Constructor; 20 21 /** 22 * DexFile tests (Dalvik-specific). 23 */ 24 public class Main { 25 private static final String CLASS_PATH = System.getenv("DEX_LOCATION") + "/071-dexfile-ex.jar"; 26 private static final String ODEX_DIR = System.getenv("DEX_LOCATION"); 27 //private static final String ODEX_DIR = "."; 28 private static final String ODEX_ALT = "/tmp"; 29 private static final String LIB_DIR = "/nowhere/nothing/"; 30 31 /** 32 * Prep the environment then run the test. 33 */ 34 public static void main(String[] args) { 35 Process p; 36 try { 37 /* 38 * Create a sub-process to see if the ProcessManager wait 39 * interferes with the dexopt invocation wait. 40 * 41 * /dev/random never hits EOF, so we're sure that we'll still 42 * be waiting for the process to complete. On the device it 43 * stops pretty quickly (which means the child won't be 44 * spinning). 45 */ 46 ProcessBuilder pb = new ProcessBuilder("cat", "/dev/random"); 47 p = pb.start(); 48 } catch (IOException ioe) { 49 System.err.println("cmd failed: " + ioe.getMessage()); 50 p = null; 51 } 52 53 try { 54 testDexClassLoader(); 55 } finally { 56 // shouldn't be necessary, but it's good to be tidy 57 if (p != null) { 58 p.destroy(); 59 } 60 61 // let the ProcessManager's daemon thread finish before we shut down 62 // (avoids the occasional segmentation fault) 63 try { 64 Thread.sleep(500); 65 } catch (Exception ex) {} 66 } 67 68 System.out.println("done"); 69 } 70 71 /** 72 * Create a class loader, explicitly specifying the source DEX and 73 * the location for the optimized DEX. 74 */ 75 private static void testDexClassLoader() { 76 ClassLoader dexClassLoader = getDexClassLoader(); 77 78 Class anotherClass; 79 try { 80 anotherClass = dexClassLoader.loadClass("Another"); 81 } catch (ClassNotFoundException cnfe) { 82 throw new RuntimeException("Another?", cnfe); 83 } 84 85 Object another; 86 try { 87 another = anotherClass.newInstance(); 88 } catch (IllegalAccessException ie) { 89 throw new RuntimeException("new another", ie); 90 } catch (InstantiationException ie) { 91 throw new RuntimeException("new another", ie); 92 } 93 94 // not expected to work; just exercises the call 95 dexClassLoader.getResource("nonexistent"); 96 } 97 98 /* 99 * Create an instance of DexClassLoader. The test harness doesn't 100 * have visibility into dalvik.system.*, so we do this through 101 * reflection. 102 */ 103 private static ClassLoader getDexClassLoader() { 104 String odexDir; 105 106 if (false) { 107 String androidData = System.getenv("ANDROID_DATA"); 108 if (androidData == null) { 109 androidData = ""; 110 } 111 odexDir = androidData + "/" + ODEX_DIR; 112 } 113 114 File test = new File(ODEX_DIR); 115 if (test.isDirectory()) { 116 odexDir = ODEX_DIR; 117 } else { 118 odexDir = ODEX_ALT; 119 } 120 if (false) { 121 System.out.println("Output dir is " + odexDir); 122 } 123 124 ClassLoader myLoader = Main.class.getClassLoader(); 125 Class dclClass; 126 try { 127 dclClass = myLoader.loadClass("dalvik.system.DexClassLoader"); 128 } catch (ClassNotFoundException cnfe) { 129 throw new RuntimeException("dalvik.system.DexClassLoader not found", cnfe); 130 } 131 132 Constructor ctor; 133 try { 134 ctor = dclClass.getConstructor(String.class, String.class, 135 String.class, ClassLoader.class); 136 } catch (NoSuchMethodException nsme) { 137 throw new RuntimeException("DCL ctor", nsme); 138 } 139 140 // create an instance, using the path we found 141 Object dclObj; 142 try { 143 dclObj = ctor.newInstance(CLASS_PATH, odexDir, LIB_DIR, myLoader); 144 } catch (Exception ex) { 145 throw new RuntimeException("DCL newInstance", ex); 146 } 147 148 return (ClassLoader) dclObj; 149 } 150 } 151