xref: /aosp_15_r20/art/test/1964-add-to-dex-classloader-file/src/Main.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2019 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker import art.Redefinition;
18*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Constructor;
19*795d594fSAndroid Build Coastguard Worker import java.lang.reflect.Method;
20*795d594fSAndroid Build Coastguard Worker import java.net.URL;
21*795d594fSAndroid Build Coastguard Worker import java.net.URLClassLoader;
22*795d594fSAndroid Build Coastguard Worker import java.nio.ByteBuffer;
23*795d594fSAndroid Build Coastguard Worker import java.util.ArrayList;
24*795d594fSAndroid Build Coastguard Worker import java.util.Arrays;
25*795d594fSAndroid Build Coastguard Worker import java.util.Base64;
26*795d594fSAndroid Build Coastguard Worker 
27*795d594fSAndroid Build Coastguard Worker public class Main {
28*795d594fSAndroid Build Coastguard Worker   private static String TEST_NAME = "1964-add-to-dex-classloader-file";
29*795d594fSAndroid Build Coastguard Worker   private static boolean IS_ART = System.getProperty("java.vm.name").equals("Dalvik");
30*795d594fSAndroid Build Coastguard Worker 
31*795d594fSAndroid Build Coastguard Worker   private static String TEST_CLASS_NAME = "foobar.TestClass";
32*795d594fSAndroid Build Coastguard Worker   private static String NEW_CLASS_NAME = "foobar.NewClass";
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker   /**
35*795d594fSAndroid Build Coastguard Worker    * base64 encoded class/dex file for
36*795d594fSAndroid Build Coastguard Worker    * package foobar;
37*795d594fSAndroid Build Coastguard Worker    * public class TestClass {
38*795d594fSAndroid Build Coastguard Worker    *   public static void sayHi() {
39*795d594fSAndroid Build Coastguard Worker    *    System.out.println("Hello again from TestClass sayHi function");
40*795d594fSAndroid Build Coastguard Worker    *    TestClass.sayBye();
41*795d594fSAndroid Build Coastguard Worker    *   }
42*795d594fSAndroid Build Coastguard Worker    *   static void sayBye() {
43*795d594fSAndroid Build Coastguard Worker    *    System.out.println("Goodbye from TestClass!");
44*795d594fSAndroid Build Coastguard Worker    *   }
45*795d594fSAndroid Build Coastguard Worker    * }
46*795d594fSAndroid Build Coastguard Worker    */
47*795d594fSAndroid Build Coastguard Worker   private static byte[] CLASS_BYTES = Base64.getDecoder().decode(
48*795d594fSAndroid Build Coastguard Worker       "yv66vgAAADUAIQoACAARCQASABMIABQKABUAFgoABwAXCAAYBwAZBwAaAQAGPGluaXQ+AQADKClW"
49*795d594fSAndroid Build Coastguard Worker       + "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAGc2F5QnllAQAKU291cmNlRmlsZQEA"
50*795d594fSAndroid Build Coastguard Worker       + "DlRlc3RDbGFzcy5qYXZhDAAJAAoHABsMABwAHQEAI0hlbGxvIGZyb20gVGVzdENsYXNzIHNheUhp"
51*795d594fSAndroid Build Coastguard Worker       + "IGZ1bmN0aW9uBwAeDAAfACAMAA4ACgEAF0dvb2RieWUgZnJvbSBUZXN0Q2xhc3MhAQAQZm9vYmFy"
52*795d594fSAndroid Build Coastguard Worker       + "L1Rlc3RDbGFzcwEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcvU3lzdGVtAQADb3V0AQAV"
53*795d594fSAndroid Build Coastguard Worker       + "TGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVhbQEAB3ByaW50bG4BABUo"
54*795d594fSAndroid Build Coastguard Worker       + "TGphdmEvbGFuZy9TdHJpbmc7KVYAIQAHAAgAAAAAAAMAAQAJAAoAAQALAAAAHQABAAEAAAAFKrcA"
55*795d594fSAndroid Build Coastguard Worker       + "AbEAAAABAAwAAAAGAAEAAAACAAkADQAKAAEACwAAACwAAgAAAAAADLIAAhIDtgAEuAAFsQAAAAEA"
56*795d594fSAndroid Build Coastguard Worker       + "DAAAAA4AAwAAAAQACAAFAAsABgAIAA4ACgABAAsAAAAlAAIAAAAAAAmyAAISBrYABLEAAAABAAwA"
57*795d594fSAndroid Build Coastguard Worker       + "AAAKAAIAAAAIAAgACQABAA8AAAACABA=");
58*795d594fSAndroid Build Coastguard Worker 
59*795d594fSAndroid Build Coastguard Worker   private static byte[] DEX_BYTES = Base64.getDecoder().decode(
60*795d594fSAndroid Build Coastguard Worker       "ZGV4CjAzNQARmtFTPdWXebnrTNy5b71tEiJKC96qIPXAAwAAcAAAAHhWNBIAAAAAAAAAABQDAAAQ"
61*795d594fSAndroid Build Coastguard Worker       + "AAAAcAAAAAYAAACwAAAAAgAAAMgAAAABAAAA4AAAAAUAAADoAAAAAQAAABABAACQAgAAMAEAAKYB"
62*795d594fSAndroid Build Coastguard Worker       + "AACuAQAAxwEAAOwBAAAAAgAAFwIAACsCAAA/AgAAUwIAAGMCAABmAgAAagIAAG8CAAB4AgAAgAIA"
63*795d594fSAndroid Build Coastguard Worker       + "AIcCAAADAAAABAAAAAUAAAAGAAAABwAAAAkAAAAJAAAABQAAAAAAAAAKAAAABQAAAKABAAAEAAEA"
64*795d594fSAndroid Build Coastguard Worker       + "CwAAAAAAAAAAAAAAAAAAAA0AAAAAAAAADgAAAAEAAQAMAAAAAgAAAAAAAAAAAAAAAQAAAAIAAAAA"
65*795d594fSAndroid Build Coastguard Worker       + "AAAACAAAAAAAAAD+AgAAAAAAAAEAAQABAAAAjgEAAAQAAABwEAQAAAAOAAIAAAACAAAAkgEAAAgA"
66*795d594fSAndroid Build Coastguard Worker       + "AABiAAAAGgEBAG4gAwAQAA4AAgAAAAIAAACXAQAACwAAAGIAAAAaAQIAbiADABAAcQABAAAADgAC"
67*795d594fSAndroid Build Coastguard Worker       + "AA4ACAAOeAAEAA54PAAAAAABAAAAAwAGPGluaXQ+ABdHb29kYnllIGZyb20gVGVzdENsYXNzIQAj"
68*795d594fSAndroid Build Coastguard Worker       + "SGVsbG8gZnJvbSBUZXN0Q2xhc3Mgc2F5SGkgZnVuY3Rpb24AEkxmb29iYXIvVGVzdENsYXNzOwAV"
69*795d594fSAndroid Build Coastguard Worker       + "TGphdmEvaW8vUHJpbnRTdHJlYW07ABJMamF2YS9sYW5nL09iamVjdDsAEkxqYXZhL2xhbmcvU3Ry"
70*795d594fSAndroid Build Coastguard Worker       + "aW5nOwASTGphdmEvbGFuZy9TeXN0ZW07AA5UZXN0Q2xhc3MuamF2YQABVgACVkwAA291dAAHcHJp"
71*795d594fSAndroid Build Coastguard Worker       + "bnRsbgAGc2F5QnllAAVzYXlIaQB1fn5EOHsiY29tcGlsYXRpb24tbW9kZSI6ImRlYnVnIiwibWlu"
72*795d594fSAndroid Build Coastguard Worker       + "LWFwaSI6MSwic2hhLTEiOiJkMzI4MmI4ZjU0N2MyMzRjNGU0YzkzMDljMzZjNzk1YTI5ODU2ZWFi"
73*795d594fSAndroid Build Coastguard Worker       + "IiwidmVyc2lvbiI6IjEuNi4xLWRldiJ9AAAAAwAAgYAEsAIBCMgCAQnoAgAAAAAOAAAAAAAAAAEA"
74*795d594fSAndroid Build Coastguard Worker       + "AAAAAAAAAQAAABAAAABwAAAAAgAAAAYAAACwAAAAAwAAAAIAAADIAAAABAAAAAEAAADgAAAABQAA"
75*795d594fSAndroid Build Coastguard Worker       + "AAUAAADoAAAABgAAAAEAAAAQAQAAASAAAAMAAAAwAQAAAyAAAAMAAACOAQAAARAAAAEAAACgAQAA"
76*795d594fSAndroid Build Coastguard Worker       + "AiAAABAAAACmAQAAACAAAAEAAAD+AgAAAxAAAAEAAAAQAwAAABAAAAEAAAAUAwAA");
77*795d594fSAndroid Build Coastguard Worker   /**
78*795d594fSAndroid Build Coastguard Worker    * base64 encoded class/dex file for
79*795d594fSAndroid Build Coastguard Worker    * package foobar;
80*795d594fSAndroid Build Coastguard Worker    * public class TestClass {
81*795d594fSAndroid Build Coastguard Worker    *   public static void sayHi() {
82*795d594fSAndroid Build Coastguard Worker    *    System.out.println("Hello again from TestClass sayHi function");
83*795d594fSAndroid Build Coastguard Worker    *    NewClass.sayHi();
84*795d594fSAndroid Build Coastguard Worker    *   }
85*795d594fSAndroid Build Coastguard Worker    *   static void sayBye() {
86*795d594fSAndroid Build Coastguard Worker    *    System.out.println("Goodbye again from TestClass!");
87*795d594fSAndroid Build Coastguard Worker    *   }
88*795d594fSAndroid Build Coastguard Worker    * }
89*795d594fSAndroid Build Coastguard Worker    */
90*795d594fSAndroid Build Coastguard Worker   private static byte[] REDEF_CLASS_BYTES = Base64.getDecoder().decode(
91*795d594fSAndroid Build Coastguard Worker       "yv66vgAAADUAIwoACAARCQASABMIABQKABUAFgoAFwAYCAAZBwAaBwAbAQAGPGluaXQ+AQADKClW"
92*795d594fSAndroid Build Coastguard Worker       + "AQAEQ29kZQEAD0xpbmVOdW1iZXJUYWJsZQEABXNheUhpAQAGc2F5QnllAQAKU291cmNlRmlsZQEA"
93*795d594fSAndroid Build Coastguard Worker       + "DlRlc3RDbGFzcy5qYXZhDAAJAAoHABwMAB0AHgEAKUhlbGxvIGFnYWluIGZyb20gVGVzdENsYXNz"
94*795d594fSAndroid Build Coastguard Worker       + "IHNheUhpIGZ1bmN0aW9uBwAfDAAgACEHACIMAA0ACgEAHUdvb2RieWUgYWdhaW4gZnJvbSBUZXN0"
95*795d594fSAndroid Build Coastguard Worker       + "Q2xhc3MhAQAQZm9vYmFyL1Rlc3RDbGFzcwEAEGphdmEvbGFuZy9PYmplY3QBABBqYXZhL2xhbmcv"
96*795d594fSAndroid Build Coastguard Worker       + "U3lzdGVtAQADb3V0AQAVTGphdmEvaW8vUHJpbnRTdHJlYW07AQATamF2YS9pby9QcmludFN0cmVh"
97*795d594fSAndroid Build Coastguard Worker       + "bQEAB3ByaW50bG4BABUoTGphdmEvbGFuZy9TdHJpbmc7KVYBAA9mb29iYXIvTmV3Q2xhc3MAIQAH"
98*795d594fSAndroid Build Coastguard Worker       + "AAgAAAAAAAMAAQAJAAoAAQALAAAAHQABAAEAAAAFKrcAAbEAAAABAAwAAAAGAAEAAAACAAkADQAK"
99*795d594fSAndroid Build Coastguard Worker       + "AAEACwAAACwAAgAAAAAADLIAAhIDtgAEuAAFsQAAAAEADAAAAA4AAwAAAAQACAAFAAsABgAIAA4A"
100*795d594fSAndroid Build Coastguard Worker       + "CgABAAsAAAAlAAIAAAAAAAmyAAISBrYABLEAAAABAAwAAAAKAAIAAAAIAAgACQABAA8AAAACABA=");
101*795d594fSAndroid Build Coastguard Worker 
102*795d594fSAndroid Build Coastguard Worker   private static byte[] REDEF_DEX_BYTES = Base64.getDecoder().decode(
103*795d594fSAndroid Build Coastguard Worker       "ZGV4CjAzNQA2plEeYRH4vl6wJgnAZOVcZ537QN9NXB3wAwAAcAAAAHhWNBIAAAAAAAAAAEQDAAAR"
104*795d594fSAndroid Build Coastguard Worker       + "AAAAcAAAAAcAAAC0AAAAAgAAANAAAAABAAAA6AAAAAYAAADwAAAAAQAAACABAACwAgAAQAEAALYB"
105*795d594fSAndroid Build Coastguard Worker       + "AAC+AQAA3QEAAAgCAAAbAgAALwIAAEYCAABaAgAAbgIAAIICAACSAgAAlQIAAJkCAACeAgAApwIA"
106*795d594fSAndroid Build Coastguard Worker       + "AK8CAAC2AgAAAwAAAAQAAAAFAAAABgAAAAcAAAAIAAAACgAAAAoAAAAGAAAAAAAAAAsAAAAGAAAA"
107*795d594fSAndroid Build Coastguard Worker       + "sAEAAAUAAgAMAAAAAAAAAA8AAAABAAAAAAAAAAEAAAAOAAAAAQAAAA8AAAACAAEADQAAAAMAAAAA"
108*795d594fSAndroid Build Coastguard Worker       + "AAAAAQAAAAEAAAADAAAAAAAAAAkAAAAAAAAALQMAAAAAAAABAAEAAQAAAJ4BAAAEAAAAcBAFAAAA"
109*795d594fSAndroid Build Coastguard Worker       + "DgACAAAAAgAAAKIBAAAIAAAAYgAAABoBAQBuIAQAEAAOAAIAAAACAAAApwEAAAsAAABiAAAAGgEC"
110*795d594fSAndroid Build Coastguard Worker       + "AG4gBAAQAHEAAAAAAA4AAgAOAAgADngABAAOeDwAAAAAAQAAAAQABjxpbml0PgAdR29vZGJ5ZSBh"
111*795d594fSAndroid Build Coastguard Worker       + "Z2FpbiBmcm9tIFRlc3RDbGFzcyEAKUhlbGxvIGFnYWluIGZyb20gVGVzdENsYXNzIHNheUhpIGZ1"
112*795d594fSAndroid Build Coastguard Worker       + "bmN0aW9uABFMZm9vYmFyL05ld0NsYXNzOwASTGZvb2Jhci9UZXN0Q2xhc3M7ABVMamF2YS9pby9Q"
113*795d594fSAndroid Build Coastguard Worker       + "cmludFN0cmVhbTsAEkxqYXZhL2xhbmcvT2JqZWN0OwASTGphdmEvbGFuZy9TdHJpbmc7ABJMamF2"
114*795d594fSAndroid Build Coastguard Worker       + "YS9sYW5nL1N5c3RlbTsADlRlc3RDbGFzcy5qYXZhAAFWAAJWTAADb3V0AAdwcmludGxuAAZzYXlC"
115*795d594fSAndroid Build Coastguard Worker       + "eWUABXNheUhpAHV+fkQ4eyJjb21waWxhdGlvbi1tb2RlIjoiZGVidWciLCJtaW4tYXBpIjoxLCJz"
116*795d594fSAndroid Build Coastguard Worker       + "aGEtMSI6ImQzMjgyYjhmNTQ3YzIzNGM0ZTRjOTMwOWMzNmM3OTVhMjk4NTZlYWIiLCJ2ZXJzaW9u"
117*795d594fSAndroid Build Coastguard Worker       + "IjoiMS42LjEtZGV2In0AAAADAAGBgATAAgEI2AIBCfgCAAAAAAAOAAAAAAAAAAEAAAAAAAAAAQAA"
118*795d594fSAndroid Build Coastguard Worker       + "ABEAAABwAAAAAgAAAAcAAAC0AAAAAwAAAAIAAADQAAAABAAAAAEAAADoAAAABQAAAAYAAADwAAAA"
119*795d594fSAndroid Build Coastguard Worker       + "BgAAAAEAAAAgAQAAASAAAAMAAABAAQAAAyAAAAMAAACeAQAAARAAAAEAAACwAQAAAiAAABEAAAC2"
120*795d594fSAndroid Build Coastguard Worker       + "AQAAACAAAAEAAAAtAwAAAxAAAAEAAABAAwAAABAAAAEAAABEAwAA");
121*795d594fSAndroid Build Coastguard Worker 
SafePrintCause(Throwable t)122*795d594fSAndroid Build Coastguard Worker   public static void SafePrintCause(Throwable t) {
123*795d594fSAndroid Build Coastguard Worker     StackTraceElement cause = t.getStackTrace()[0];
124*795d594fSAndroid Build Coastguard Worker     System.out.println(" --- " + t.getClass().getName() + " At " + cause.getClassName() + "." +
125*795d594fSAndroid Build Coastguard Worker                        cause.getMethodName() + "(" + cause.getFileName() + ":" +
126*795d594fSAndroid Build Coastguard Worker                        cause.getLineNumber() + ")");
127*795d594fSAndroid Build Coastguard Worker   }
128*795d594fSAndroid Build Coastguard Worker 
run()129*795d594fSAndroid Build Coastguard Worker   public static void run() throws Exception {
130*795d594fSAndroid Build Coastguard Worker     System.out.println(" - Run while adding new referenced class.");
131*795d594fSAndroid Build Coastguard Worker     try {
132*795d594fSAndroid Build Coastguard Worker       run(true);
133*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
134*795d594fSAndroid Build Coastguard Worker       // Unfortunately art and RI have different messages here so just return the type.
135*795d594fSAndroid Build Coastguard Worker       System.out.println(" -- Exception caught when running test with new class added! " +
136*795d594fSAndroid Build Coastguard Worker                          e.getCause().getClass().getName());
137*795d594fSAndroid Build Coastguard Worker       SafePrintCause(e.getCause());
138*795d594fSAndroid Build Coastguard Worker       System.out.println(e);
139*795d594fSAndroid Build Coastguard Worker       e.printStackTrace();
140*795d594fSAndroid Build Coastguard Worker     }
141*795d594fSAndroid Build Coastguard Worker     System.out.println(" - Run without adding new referenced class.");
142*795d594fSAndroid Build Coastguard Worker     try {
143*795d594fSAndroid Build Coastguard Worker       run(false);
144*795d594fSAndroid Build Coastguard Worker     } catch (Exception e) {
145*795d594fSAndroid Build Coastguard Worker       // Unfortunately art and RI have different messages here so just return the type.
146*795d594fSAndroid Build Coastguard Worker       System.out.println(" -- Exception caught when running test without new class added! " +
147*795d594fSAndroid Build Coastguard Worker                          e.getCause().getClass().getName());
148*795d594fSAndroid Build Coastguard Worker       SafePrintCause(e.getCause());
149*795d594fSAndroid Build Coastguard Worker     }
150*795d594fSAndroid Build Coastguard Worker   }
151*795d594fSAndroid Build Coastguard Worker 
run(boolean add_new)152*795d594fSAndroid Build Coastguard Worker   public static void run(boolean add_new) throws Exception {
153*795d594fSAndroid Build Coastguard Worker     ClassLoader cl = getClassLoader();
154*795d594fSAndroid Build Coastguard Worker     Class<?> target = cl.loadClass(TEST_CLASS_NAME);
155*795d594fSAndroid Build Coastguard Worker     Method sayHi = target.getDeclaredMethod("sayHi");
156*795d594fSAndroid Build Coastguard Worker     System.out.println(" -- Running sayHi before redefinition");
157*795d594fSAndroid Build Coastguard Worker     sayHi.invoke(null);
158*795d594fSAndroid Build Coastguard Worker     if (add_new) {
159*795d594fSAndroid Build Coastguard Worker       System.out.println(" -- Adding NewClass to classloader!");
160*795d594fSAndroid Build Coastguard Worker       addToClassLoader(cl);
161*795d594fSAndroid Build Coastguard Worker     }
162*795d594fSAndroid Build Coastguard Worker     System.out.println(" -- Redefine the TestClass");
163*795d594fSAndroid Build Coastguard Worker     Redefinition.doCommonClassRedefinition(target, REDEF_CLASS_BYTES, REDEF_DEX_BYTES);
164*795d594fSAndroid Build Coastguard Worker     System.out.println(" -- call TestClass again, now with NewClass refs");
165*795d594fSAndroid Build Coastguard Worker     sayHi.invoke(null);
166*795d594fSAndroid Build Coastguard Worker   }
167*795d594fSAndroid Build Coastguard Worker 
168*795d594fSAndroid Build Coastguard Worker   public static class ExtensibleClassLoader extends URLClassLoader {
ExtensibleClassLoader()169*795d594fSAndroid Build Coastguard Worker     public ExtensibleClassLoader() {
170*795d594fSAndroid Build Coastguard Worker       // Initially we don't have any URLs
171*795d594fSAndroid Build Coastguard Worker       super(new URL[] {}, ExtensibleClassLoader.class.getClassLoader());
172*795d594fSAndroid Build Coastguard Worker     }
173*795d594fSAndroid Build Coastguard Worker 
addSingleUrl(String file)174*795d594fSAndroid Build Coastguard Worker     public void addSingleUrl(String file) throws Exception {
175*795d594fSAndroid Build Coastguard Worker       this.addURL(new URL("file://" + file));
176*795d594fSAndroid Build Coastguard Worker     }
177*795d594fSAndroid Build Coastguard Worker 
findClass(String name)178*795d594fSAndroid Build Coastguard Worker     protected Class<?> findClass(String name) throws ClassNotFoundException {
179*795d594fSAndroid Build Coastguard Worker       // Just define the TestClass without other jars.
180*795d594fSAndroid Build Coastguard Worker       if (name.equals(TEST_CLASS_NAME)) {
181*795d594fSAndroid Build Coastguard Worker         return this.defineClass(TEST_CLASS_NAME, CLASS_BYTES, 0, CLASS_BYTES.length);
182*795d594fSAndroid Build Coastguard Worker       } else {
183*795d594fSAndroid Build Coastguard Worker         return super.findClass(name);
184*795d594fSAndroid Build Coastguard Worker       }
185*795d594fSAndroid Build Coastguard Worker     }
186*795d594fSAndroid Build Coastguard Worker   }
187*795d594fSAndroid Build Coastguard Worker 
getClassLoader()188*795d594fSAndroid Build Coastguard Worker   public static ClassLoader getClassLoader() throws Exception {
189*795d594fSAndroid Build Coastguard Worker     if (!IS_ART) {
190*795d594fSAndroid Build Coastguard Worker       return new ExtensibleClassLoader();
191*795d594fSAndroid Build Coastguard Worker     } else {
192*795d594fSAndroid Build Coastguard Worker       Class<?> class_loader_class = Class.forName("dalvik.system.InMemoryDexClassLoader");
193*795d594fSAndroid Build Coastguard Worker       Constructor<?> ctor = class_loader_class.getConstructor(ByteBuffer.class, ClassLoader.class);
194*795d594fSAndroid Build Coastguard Worker       return (ClassLoader)ctor.newInstance(ByteBuffer.wrap(DEX_BYTES), Main.class.getClassLoader());
195*795d594fSAndroid Build Coastguard Worker     }
196*795d594fSAndroid Build Coastguard Worker   }
197*795d594fSAndroid Build Coastguard Worker 
addToClassLoader(ClassLoader cl)198*795d594fSAndroid Build Coastguard Worker   public static void addToClassLoader(ClassLoader cl) throws Exception {
199*795d594fSAndroid Build Coastguard Worker     if (IS_ART) {
200*795d594fSAndroid Build Coastguard Worker       addToClassLoaderNative(cl, System.getenv("DEX_LOCATION") + "/" + TEST_NAME + "-ex.jar");
201*795d594fSAndroid Build Coastguard Worker     } else {
202*795d594fSAndroid Build Coastguard Worker       ((ExtensibleClassLoader)cl).addSingleUrl(System.getenv("DEX_LOCATION") + "/classes-ex/");
203*795d594fSAndroid Build Coastguard Worker     }
204*795d594fSAndroid Build Coastguard Worker   }
205*795d594fSAndroid Build Coastguard Worker 
addToClassLoaderNative(ClassLoader loader, String segment)206*795d594fSAndroid Build Coastguard Worker   public static native void addToClassLoaderNative(ClassLoader loader, String segment);
main(String[] args)207*795d594fSAndroid Build Coastguard Worker   public static void main(String[] args) throws Exception {
208*795d594fSAndroid Build Coastguard Worker     run();
209*795d594fSAndroid Build Coastguard Worker   }
210*795d594fSAndroid Build Coastguard Worker }
211