Home | History | Annotate | Download | only in src
      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      */
     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      */
     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      */
    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