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 = "test-ex.jar"; 26 private static final String ODEX_DIR = "/sdcard"; 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 */ main(String[] args)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 // let the ProcessManager's daemon thread finish before we shut down 61 // (avoids the occasional segmentation fault) 62 try { 63 Thread.sleep(500); 64 } catch (Exception ex) {} 65 } 66 67 System.out.println("done"); 68 } 69 70 /** 71 * Create a class loader, explicitly specifying the source DEX and 72 * the location for the optimized DEX. 73 */ testDexClassLoader()74 private static void testDexClassLoader() { 75 ClassLoader dexClassLoader = getDexClassLoader(); 76 77 Class anotherClass; 78 try { 79 anotherClass = dexClassLoader.loadClass("Another"); 80 } catch (ClassNotFoundException cnfe) { 81 throw new RuntimeException("Another?"); 82 } 83 84 Object another; 85 try { 86 another = anotherClass.newInstance(); 87 } catch (IllegalAccessException ie) { 88 throw new RuntimeException("new another", ie); 89 } catch (InstantiationException ie) { 90 throw new RuntimeException("new another", ie); 91 } 92 93 // not expected to work; just exercises the call 94 dexClassLoader.getResource("nonexistent"); 95 } 96 97 /* 98 * Create an instance of DexClassLoader. The test harness doesn't 99 * have visibility into dalvik.system.*, so we do this through 100 * reflection. 101 */ getDexClassLoader()102 private static ClassLoader getDexClassLoader() { 103 String odexDir; 104 105 /* 106 String androidData = System.getenv("ANDROID_DATA"); 107 if (androidData == null) 108 androidData = ""; 109 odexDir = androidData + "/" + ODEX_DIR; 110 */ 111 112 File test = new File(ODEX_DIR); 113 if (test.isDirectory()) 114 odexDir = ODEX_DIR; 115 else 116 odexDir = ODEX_ALT; 117 //System.out.println("Output dir is " + odexDir); 118 119 ClassLoader myLoader = Main.class.getClassLoader(); 120 Class dclClass; 121 try { 122 dclClass = myLoader.loadClass("dalvik.system.DexClassLoader"); 123 } catch (ClassNotFoundException cnfe) { 124 throw new RuntimeException("dalvik.system.DexClassLoader not found"); 125 } 126 127 Constructor ctor; 128 try { 129 ctor = dclClass.getConstructor(String.class, String.class, 130 String.class, ClassLoader.class); 131 } catch (NoSuchMethodException nsme) { 132 throw new RuntimeException("DCL ctor", nsme); 133 } 134 135 // create an instance, using the path we found 136 Object dclObj; 137 try { 138 dclObj = ctor.newInstance(CLASS_PATH, odexDir, LIB_DIR, myLoader); 139 } catch (Exception ex) { 140 throw new RuntimeException("DCL newInstance", ex); 141 } 142 143 return (ClassLoader) dclObj; 144 } 145 } 146