1f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/*
2f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
4f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * you may not use this file except in compliance with the License.
6f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * You may obtain a copy of the License at
7f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
8f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project *
10f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * See the License for the specific language governing permissions and
14f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * limitations under the License.
15f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
16f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
17f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project/**
18f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project * Class loader test.
19f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project */
20f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Projectpublic class Main {
21f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
22f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Main entry point.
23f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
24f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    public static void main(String[] args) {
25f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        FancyLoader loader;
26f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
27f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        loader = new FancyLoader(ClassLoader.getSystemClassLoader());
2886c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        //System.out.println("SYSTEM: " + ClassLoader.getSystemClassLoader());
2986c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        //System.out.println("ALTERN: " + loader);
30f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
31f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
32f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * This statement has no effect on this program, but it can
33f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * change the point where a LinkageException is thrown in
34f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * testImplement().  When this is present the "reference
35f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * implementation" throws an exception from Class.newInstance(),
36f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * when it's absent the exception is deferred until the first time
37f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * we call a method that isn't actually implemented.
38f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         *
39f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * This isn't the class that fails -- it's a class with the same
40f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * name in the "fancy" class loader --  but the VM thinks it has a
41f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * reference to one of these; presumably the difference is that
42f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * without this the VM finds itself holding a reference to an
43f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * instance of an uninitialized class.
44f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
45f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println("base: " + DoubledImplement.class);
46f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        System.out.println("base2: " + DoubledImplement2.class);
47f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
48f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
49f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Run tests.
50f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
51f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        testAccess1(loader);
52f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        testAccess2(loader);
53f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        testAccess3(loader);
54f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
55f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        testExtend(loader);
56cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        testExtendOkay(loader);
57e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        testInterface(loader);
5886c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        testAbstract(loader);
59f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        testImplement(loader);
60f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        testIfaceImplement(loader);
61f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
62f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
63f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
64f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * See if we can load a class that isn't public to us.  We should be
65f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * able to load it but not instantiate it.
66f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
67f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void testAccess1(ClassLoader loader) {
68f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Class altClass;
69f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
70f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
71f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            altClass = loader.loadClass("Inaccessible1");
72f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ClassNotFoundException cnfe) {
73f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("loadClass failed");
74f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            cnfe.printStackTrace();
75f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
76f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
77f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
78f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* instantiate */
79f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object obj;
80f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
81f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            obj = altClass.newInstance();
82f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("ERROR: Inaccessible1 was accessible");
83f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (InstantiationException ie) {
84f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("newInstance failed: " + ie);
85f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
86f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (IllegalAccessException iae) {
87f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.out.println("Got expected access exception #1");
88f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //System.out.println("+++ " + iae);
89f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
90f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
91f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
92f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
93f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
94f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * See if we can load a class whose base class is not accessible to it
95f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * (though the base *is* accessible to us).
96f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
97f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void testAccess2(ClassLoader loader) {
98f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Class altClass;
99f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
100f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
101f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            altClass = loader.loadClass("Inaccessible2");
102f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("ERROR: Inaccessible2 was accessible");
103f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ClassNotFoundException cnfe) {
104f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Throwable cause = cnfe.getCause();
105f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (cause instanceof IllegalAccessError) {
106f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.out.println("Got expected CNFE/IAE #2");
107f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
108f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.err.println("Got unexpected CNFE/IAE #2");
109f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                cnfe.printStackTrace();
110f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
111f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
112f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
113f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
114f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
115f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * See if we can load a class with an inaccessible interface.
116f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
117f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void testAccess3(ClassLoader loader) {
118f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Class altClass;
119f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
120f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
121f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            altClass = loader.loadClass("Inaccessible3");
122f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("ERROR: Inaccessible3 was accessible");
123f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ClassNotFoundException cnfe) {
124f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            Throwable cause = cnfe.getCause();
125f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (cause instanceof IllegalAccessError) {
126f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.out.println("Got expected CNFE/IAE #3");
127f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
128f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.err.println("Got unexpected CNFE/IAE #3");
129f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                cnfe.printStackTrace();
130f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
131f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
132f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
133f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
134f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
135f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Test a doubled class that extends the base class.
136f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
137f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void testExtend(ClassLoader loader) {
138f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Class doubledExtendClass;
139f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object obj;
140f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
141f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* get the "alternate" version of DoubledExtend */
142f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
143f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            doubledExtendClass = loader.loadClass("DoubledExtend");
144f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //System.out.println("+++ DoubledExtend is " + doubledExtendClass
145f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //    + " in " + doubledExtendClass.getClassLoader());
146f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ClassNotFoundException cnfe) {
147f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("loadClass failed: " + cnfe);
148f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
149f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
150f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
151f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* instantiate */
152f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
153f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            obj = doubledExtendClass.newInstance();
154f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (InstantiationException ie) {
155f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("newInstance failed: " + ie);
156f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
157f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (IllegalAccessException iae) {
158f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("newInstance failed: " + iae);
159f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
160f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (LinkageError le) {
161f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.out.println("Got expected LinkageError on DE");
162f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
163f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
164f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
165f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* use the base class reference to get a CL-specific instance */
166f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Base baseRef = (Base) obj;
167f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DoubledExtend de = baseRef.getExtended();
168f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
169f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* try to call through it */
170f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
171f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            String result;
172f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
173f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            result = Base.doStuff(de);
174f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("ERROR: did not get LinkageError on DE");
175f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("(result=" + result + ")");
176f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (LinkageError le) {
177f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.out.println("Got expected LinkageError on DE");
178f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
179f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
180f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
181f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
182f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
183cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden     * Test a doubled class that extends the base class, but is okay since
184cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden     * it doesn't override the base class method.
185cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden     */
186cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden    static void testExtendOkay(ClassLoader loader) {
187cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        Class doubledExtendOkayClass;
188cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        Object obj;
189cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden
190cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        /* get the "alternate" version of DoubledExtendOkay */
191cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        try {
192cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            doubledExtendOkayClass = loader.loadClass("DoubledExtendOkay");
193cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        } catch (ClassNotFoundException cnfe) {
194cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            System.err.println("loadClass failed: " + cnfe);
195cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            return;
196cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        }
197cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden
198cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        /* instantiate */
199cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        try {
200cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            obj = doubledExtendOkayClass.newInstance();
201cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        } catch (InstantiationException ie) {
202cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            System.err.println("newInstance failed: " + ie);
203cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            return;
204cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        } catch (IllegalAccessException iae) {
205cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            System.err.println("newInstance failed: " + iae);
206cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            return;
207cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        } catch (LinkageError le) {
208cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            System.err.println("Got unexpected LinkageError on DEO");
209cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            le.printStackTrace();
210cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            return;
211cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        }
212cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden
213cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        /* use the base class reference to get a CL-specific instance */
214cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        BaseOkay baseRef = (BaseOkay) obj;
215cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        DoubledExtendOkay de = baseRef.getExtended();
216cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden
217cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        /* try to call through it */
218cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        try {
219cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            String result;
220cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden
221cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            result = BaseOkay.doStuff(de);
222cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            System.out.println("Got DEO result " + result);
223cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        } catch (LinkageError le) {
224cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            System.err.println("Got unexpected LinkageError on DEO");
225cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            le.printStackTrace();
226cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden            return;
227cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden        }
228cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden    }
229cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden
230cab8be0c6e1e9a683402d5a71b037723a6b15bb2Andy McFadden    /**
231e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden     * Try to access a doubled class through a class that implements
232e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden     * an interface declared in a different class.
233e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden     */
234e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden    static void testInterface(ClassLoader loader) {
235e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        Class getDoubledClass;
236e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        Object obj;
237e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden
23886c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        /* get GetDoubled from the "alternate" class loader */
239e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        try {
240e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            getDoubledClass = loader.loadClass("GetDoubled");
241e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        } catch (ClassNotFoundException cnfe) {
242e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            System.err.println("loadClass failed: " + cnfe);
243e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            return;
244e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        }
245e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden
246e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        /* instantiate */
247e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        try {
248e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            obj = getDoubledClass.newInstance();
249e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        } catch (InstantiationException ie) {
250e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            System.err.println("newInstance failed: " + ie);
251e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            return;
252e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        } catch (IllegalAccessException iae) {
253e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            System.err.println("newInstance failed: " + iae);
254e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            return;
255e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        } catch (LinkageError le) {
256e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            // Dalvik bails here
25786c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            System.out.println("Got LinkageError on GD");
258e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            return;
259e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        }
260e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden
261e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        /*
262e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden         * Cast the object to the interface, and try to use it.
263e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden         */
264e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        IGetDoubled iface = (IGetDoubled) obj;
265e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        try {
26686c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            /* "de" will be the wrong variety of DoubledExtendOkay */
26786c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            DoubledExtendOkay de = iface.getDoubled();
268e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            // reference impl bails here
269e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            String str = de.getStr();
270e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        } catch (LinkageError le) {
27186c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            System.out.println("Got LinkageError on GD");
272e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden            return;
273e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        }
274e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden        System.err.println("Should have failed by now on GetDoubled");
275e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden    }
276e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden
277e7b30940e1459c50b003edb3909eeeb919cab3d5Andy McFadden    /**
27886c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden     * Throw an abstract class into the middle and see what happens.
27986c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden     */
28086c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden    static void testAbstract(ClassLoader loader) {
28186c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        Class abstractGetClass;
28286c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        Object obj;
28386c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden
28486c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        /* get AbstractGet from the "alternate" loader */
28586c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        try {
28686c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            abstractGetClass = loader.loadClass("AbstractGet");
28786c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        } catch (ClassNotFoundException cnfe) {
28886c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            System.err.println("loadClass ta failed: " + cnfe);
28986c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            return;
29086c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        }
29186c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden
29286c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        /* instantiate */
29386c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        try {
29486c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            obj = abstractGetClass.newInstance();
29586c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        } catch (InstantiationException ie) {
29686c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            System.err.println("newInstance failed: " + ie);
29786c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            return;
29886c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        } catch (IllegalAccessException iae) {
29986c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            System.err.println("newInstance failed: " + iae);
30086c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            return;
30186c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        } catch (LinkageError le) {
30286c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            System.out.println("Got LinkageError on TA");
30386c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            return;
30486c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        }
30586c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden
30686c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        /* use the base class reference to get a CL-specific instance */
30786c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        BaseOkay baseRef = (BaseOkay) obj;
30886c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        DoubledExtendOkay de = baseRef.getExtended();
30986c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden
31086c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        /* try to call through it */
31186c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        try {
31286c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            String result;
31386c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden
31486c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            result = BaseOkay.doStuff(de);
31586c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        } catch (LinkageError le) {
31686c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            System.out.println("Got LinkageError on TA");
31786c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden            return;
31886c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        }
31986c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden        System.err.println("Should have failed by now in testAbstract");
32086c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden    }
32186c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden
32286c8643eca135fab0b8e21ba10244f3d6eb4bcf0Andy McFadden    /**
323f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Test a doubled class that implements a common interface.
324f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
325f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void testImplement(ClassLoader loader) {
326f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Class doubledImplementClass;
327f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object obj;
328f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
329f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        useImplement(new DoubledImplement(), true);
330f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
331f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* get the "alternate" version of DoubledImplement */
332f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
333f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            doubledImplementClass = loader.loadClass("DoubledImplement");
334f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ClassNotFoundException cnfe) {
335f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("loadClass failed: " + cnfe);
336f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
337f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
338f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
339f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* instantiate */
340f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
341f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            obj = doubledImplementClass.newInstance();
342f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (InstantiationException ie) {
343f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("newInstance failed: " + ie);
344f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
345f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (IllegalAccessException iae) {
346f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("newInstance failed: " + iae);
347f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
348f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (LinkageError le) {
349f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.out.println("Got LinkageError on DI (early)");
350f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
351f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
352f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
353f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* if we lived this long, try to do something with it */
354f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        ICommon icommon = (ICommon) obj;
355f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        useImplement(icommon.getDoubledInstance(), false);
356f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
357f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
358f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
359f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Do something with a DoubledImplement instance.
360f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
361f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void useImplement(DoubledImplement di, boolean isOne) {
362f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //System.out.println("useObject: " + di.toString() + " -- "
363f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        //    + di.getClass().getClassLoader());
364f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
365f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            di.one();
366f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!isOne) {
367f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.err.println("ERROR: did not get LinkageError on DI");
368f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
369f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (LinkageError le) {
370f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            if (!isOne) {
371f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                System.out.println("Got LinkageError on DI (late)");
372f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            } else {
373f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project                throw le;
374f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            }
375f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
376f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
377f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
378f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
379f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    /**
380f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * Test a class that implements an interface with a super-interface
381f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     * that refers to a doubled class.
382f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project     */
383f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    static void testIfaceImplement(ClassLoader loader) {
384f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Class ifaceImplClass;
385f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        Object obj;
386f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
387f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
388f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Create an instance of IfaceImpl.  We also pull in
389f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * DoubledImplement2 from the other class loader; without this
390f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * we don't fail in some implementations.
391f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
392f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
393f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ifaceImplClass = loader.loadClass("IfaceImpl");
394f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            ifaceImplClass = loader.loadClass("DoubledImplement2");
395f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (ClassNotFoundException cnfe) {
396f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("loadClass failed: " + cnfe);
397f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
398f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
399f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
400f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /* instantiate */
401f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        try {
402f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            obj = ifaceImplClass.newInstance();
403f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (InstantiationException ie) {
404f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("newInstance failed: " + ie);
405f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
406f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (IllegalAccessException iae) {
407f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.err.println("newInstance failed: " + iae);
408f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
409f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        } catch (LinkageError le) {
410f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            System.out.println("Got LinkageError on IDI (early)");
411f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            //System.out.println(le);
412f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project            return;
413f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        }
414f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project
415f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        /*
416f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * Without the pre-load of FancyLoader->DoubledImplement2, some
417f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * implementations will happily execute through this part.  "obj"
418f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * comes from FancyLoader, but the di2 returned from ifaceSuper
419f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         * comes from the application class loader.
420f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project         */
421f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        IfaceSuper ifaceSuper = (IfaceSuper) obj;
422f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        DoubledImplement2 di2 = ifaceSuper.getDoubledInstance2();
423f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project        di2.one();
424f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project    }
425f6c387128427e121477c1b32ad35cdcaa5101ba3The Android Open Source Project}
426