1 /*
2  * Copyright (C) 2018 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 dalvik.system.DelegateLastClassLoader;
18 import dalvik.system.PathClassLoader;
19 
20 public class Main {
21     static final String TEST_NAME = "688-shared-library";
22     static final String MAIN_JAR_FILE = System.getenv("DEX_LOCATION") + "/" + TEST_NAME + ".jar";
23     static final String EX_JAR_FILE = System.getenv("DEX_LOCATION") + "/" + TEST_NAME + "-ex.jar";
24     static ClassLoader bootLoader = Object.class.getClassLoader();
25 
main(String[] args)26     public static void main(String[] args) throws Exception {
27       testNoLibrary();
28       testOneLibrary();
29       testTwoLibraries1();
30       testTwoLibraries2();
31       testTransitive1();
32       testTransitive2();
33       testTransitive3();
34       testTransitive4();
35     }
36 
assertIdentical(Object expected, Object actual)37     public static void assertIdentical(Object expected, Object actual) {
38       if (expected != actual) {
39         throw new Error("Expected " + expected + ", got " + actual);
40       }
41     }
42 
testNoLibrary()43     public static void testNoLibrary() throws Exception {
44       ClassLoader loader = new PathClassLoader(MAIN_JAR_FILE, null, bootLoader);
45       Class<?> cls = loader.loadClass("Main");
46       assertIdentical(loader, cls.getClassLoader());
47     }
48 
testOneLibrary()49     public static void testOneLibrary() throws Exception {
50       ClassLoader[] sharedLibraries = {
51           new PathClassLoader(EX_JAR_FILE, null, bootLoader),
52       };
53       ClassLoader delegateFirst =
54           new PathClassLoader(MAIN_JAR_FILE, null, bootLoader, sharedLibraries);
55       Class<?> cls = delegateFirst.loadClass("Main");
56       assertIdentical(sharedLibraries[0], cls.getClassLoader());
57       cls = delegateFirst.loadClass("SharedLibraryOne");
58       assertIdentical(sharedLibraries[0], cls.getClassLoader());
59 
60       ClassLoader delegateLast =
61           new DelegateLastClassLoader(MAIN_JAR_FILE, null, bootLoader, sharedLibraries);
62       cls = delegateLast.loadClass("Main");
63       assertIdentical(sharedLibraries[0], cls.getClassLoader());
64       cls = delegateLast.loadClass("SharedLibraryOne");
65       assertIdentical(sharedLibraries[0], cls.getClassLoader());
66     }
67 
testTwoLibraries1()68     public static void testTwoLibraries1() throws Exception {
69       ClassLoader[] sharedLibraries = {
70           new PathClassLoader(MAIN_JAR_FILE, null, bootLoader),
71           new PathClassLoader(EX_JAR_FILE, null, bootLoader),
72       };
73       ClassLoader delegateFirst = new PathClassLoader("", null, bootLoader, sharedLibraries);
74       Class<?> cls = delegateFirst.loadClass("Main");
75       assertIdentical(sharedLibraries[0], cls.getClassLoader());
76       cls = delegateFirst.loadClass("SharedLibraryOne");
77       assertIdentical(sharedLibraries[1], cls.getClassLoader());
78 
79       ClassLoader delegateLast =
80           new DelegateLastClassLoader(MAIN_JAR_FILE, null, bootLoader, sharedLibraries);
81       cls = delegateLast.loadClass("Main");
82       assertIdentical(sharedLibraries[0], cls.getClassLoader());
83       cls = delegateLast.loadClass("SharedLibraryOne");
84       assertIdentical(sharedLibraries[1], cls.getClassLoader());
85     }
86 
testTwoLibraries2()87     public static void testTwoLibraries2() throws Exception {
88       ClassLoader[] sharedLibraries = {
89           new PathClassLoader(EX_JAR_FILE, null, bootLoader),
90           new PathClassLoader(MAIN_JAR_FILE, null, bootLoader),
91       };
92       ClassLoader delegateFirst = new PathClassLoader("", null, bootLoader, sharedLibraries);
93       Class<?> cls = delegateFirst.loadClass("Main");
94       assertIdentical(sharedLibraries[0], cls.getClassLoader());
95       cls = delegateFirst.loadClass("SharedLibraryOne");
96       assertIdentical(sharedLibraries[0], cls.getClassLoader());
97 
98       ClassLoader delegateLast = new DelegateLastClassLoader("", null, bootLoader, sharedLibraries);
99       cls = delegateLast.loadClass("Main");
100       assertIdentical(sharedLibraries[0], cls.getClassLoader());
101       cls = delegateLast.loadClass("SharedLibraryOne");
102       assertIdentical(sharedLibraries[0], cls.getClassLoader());
103     }
104 
testTransitive1()105     public static void testTransitive1() throws Exception {
106       ClassLoader[] sharedLibraryLevel2 = {
107           new PathClassLoader(EX_JAR_FILE, null, bootLoader),
108       };
109       ClassLoader[] sharedLibraryLevel1 = {
110           new PathClassLoader(MAIN_JAR_FILE, null, bootLoader, sharedLibraryLevel2),
111       };
112 
113       ClassLoader delegateFirst = new PathClassLoader("", null, bootLoader, sharedLibraryLevel1);
114       Class<?> cls = delegateFirst.loadClass("Main");
115       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
116       cls = delegateFirst.loadClass("SharedLibraryOne");
117       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
118 
119       ClassLoader delegateLast =
120           new DelegateLastClassLoader("", null, bootLoader, sharedLibraryLevel1);
121       cls = delegateLast.loadClass("Main");
122       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
123       cls = delegateLast.loadClass("SharedLibraryOne");
124       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
125     }
126 
testTransitive2()127     public static void testTransitive2() throws Exception {
128       ClassLoader[] sharedLibraryLevel2 = {
129           new PathClassLoader(MAIN_JAR_FILE, null, bootLoader),
130       };
131       ClassLoader[] sharedLibraryLevel1 = {
132           new PathClassLoader(EX_JAR_FILE, null, bootLoader, sharedLibraryLevel2),
133       };
134 
135       ClassLoader delegateFirst = new PathClassLoader("", null, bootLoader, sharedLibraryLevel1);
136       Class<?> cls = delegateFirst.loadClass("Main");
137       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
138       cls = delegateFirst.loadClass("SharedLibraryOne");
139       assertIdentical(sharedLibraryLevel1[0], cls.getClassLoader());
140 
141       ClassLoader delegateLast =
142           new DelegateLastClassLoader("", null, bootLoader, sharedLibraryLevel1);
143       cls = delegateLast.loadClass("Main");
144       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
145       cls = delegateLast.loadClass("SharedLibraryOne");
146       assertIdentical(sharedLibraryLevel1[0], cls.getClassLoader());
147     }
148 
testTransitive3()149     public static void testTransitive3() throws Exception {
150       ClassLoader[] sharedLibraryLevel2 = {
151           new PathClassLoader(MAIN_JAR_FILE, null, bootLoader),
152       };
153       ClassLoader[] sharedLibraryLevel1 = {
154           new PathClassLoader(EX_JAR_FILE, null, bootLoader, sharedLibraryLevel2),
155           sharedLibraryLevel2[0],
156       };
157 
158       ClassLoader delegateFirst = new PathClassLoader("", null, bootLoader, sharedLibraryLevel1);
159       Class<?> cls = delegateFirst.loadClass("Main");
160       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
161       cls = delegateFirst.loadClass("SharedLibraryOne");
162       assertIdentical(sharedLibraryLevel1[0], cls.getClassLoader());
163 
164       ClassLoader delegateLast =
165           new DelegateLastClassLoader("", null, bootLoader, sharedLibraryLevel1);
166       cls = delegateLast.loadClass("Main");
167       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
168       cls = delegateLast.loadClass("SharedLibraryOne");
169       assertIdentical(sharedLibraryLevel1[0], cls.getClassLoader());
170     }
171 
testTransitive4()172     public static void testTransitive4() throws Exception {
173       ClassLoader[] sharedLibraryLevel2 = {
174           new PathClassLoader(EX_JAR_FILE, null, bootLoader),
175       };
176       ClassLoader[] sharedLibraryLevel1 = {
177           new PathClassLoader(MAIN_JAR_FILE, null, bootLoader, sharedLibraryLevel2),
178           sharedLibraryLevel2[0],
179       };
180 
181       ClassLoader delegateFirst = new PathClassLoader("", null, bootLoader, sharedLibraryLevel1);
182       Class<?> cls = delegateFirst.loadClass("Main");
183       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
184       cls = delegateFirst.loadClass("SharedLibraryOne");
185       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
186 
187       ClassLoader delegateLast =
188           new DelegateLastClassLoader("", null, bootLoader, sharedLibraryLevel1);
189       cls = delegateLast.loadClass("Main");
190       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
191       cls = delegateLast.loadClass("SharedLibraryOne");
192       assertIdentical(sharedLibraryLevel2[0], cls.getClassLoader());
193     }
194 }
195