15d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/*
25d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Copyright (C) 2008 The Android Open Source Project
35d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
45d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Licensed under the Apache License, Version 2.0 (the "License");
55d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * you may not use this file except in compliance with the License.
65d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * You may obtain a copy of the License at
75d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
85d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *      http://www.apache.org/licenses/LICENSE-2.0
95d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao *
105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Unless required by applicable law or agreed to in writing, software
115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * distributed under the License is distributed on an "AS IS" BASIS,
125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * See the License for the specific language governing permissions and
145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * limitations under the License.
155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
17f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartierimport java.lang.reflect.Constructor;
18f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartierimport java.lang.reflect.Method;
19f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier
205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/**
215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Class loader test.
225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class Main {
245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Main entry point.
265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
27598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom    public static void main(String[] args) throws Exception {
285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        FancyLoader loader;
295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        loader = new FancyLoader(ClassLoader.getSystemClassLoader());
315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //System.out.println("SYSTEM: " + ClassLoader.getSystemClassLoader());
325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //System.out.println("ALTERN: " + loader);
335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * This statement has no effect on this program, but it can
365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * change the point where a LinkageException is thrown in
375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * testImplement().  When this is present the "reference
385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * implementation" throws an exception from Class.newInstance(),
395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * when it's absent the exception is deferred until the first time
405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * we call a method that isn't actually implemented.
415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         *
425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * This isn't the class that fails -- it's a class with the same
435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * name in the "fancy" class loader --  but the VM thinks it has a
445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * reference to one of these; presumably the difference is that
455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * without this the VM finds itself holding a reference to an
465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * instance of an uninitialized class.
475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("base: " + DoubledImplement.class);
495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("base2: " + DoubledImplement2.class);
505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Run tests.
535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testAccess1(loader);
555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testAccess2(loader);
565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testAccess3(loader);
575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testExtend(loader);
595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testExtendOkay(loader);
605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testInterface(loader);
615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testAbstract(loader);
625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testImplement(loader);
635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testIfaceImplement(loader);
6426684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
6526684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        testSeparation();
66598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom
67598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom        testClassForName();
68f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier
69f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier        testNullClassLoader();
70f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier    }
71f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier
72f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier    static void testNullClassLoader() {
73f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier        try {
74f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            /* this is the "alternate" DEX/Jar file */
75f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            String DEX_FILE = System.getenv("DEX_LOCATION") + "/068-classloader-ex.jar";
76f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            /* on Dalvik, this is a DexFile; otherwise, it's null */
77f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            Class mDexClass = Class.forName("dalvik.system.DexFile");
78f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            Constructor ctor = mDexClass.getConstructor(new Class[] {String.class});
79f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            Object mDexFile = ctor.newInstance(DEX_FILE);
80f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            Method meth = mDexClass.getMethod("loadClass",
81f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier                    new Class[] { String.class, ClassLoader.class });
82f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            Object klass = meth.invoke(mDexFile, "Mutator", null);
83f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            if (klass == null) {
84f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier                throw new AssertionError("loadClass with nullclass loader failed");
85f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            }
86f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier        } catch (Exception e) {
87f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier            System.out.println(e);
88f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier        }
89f2bf9d640e37b72be8b4f6016d4aa95a0e27b7b4Mathieu Chartier        System.out.println("Loaded class into null class loader");
9026684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe    }
9126684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
9226684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe    static void testSeparation() {
9326684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        FancyLoader loader1 = new FancyLoader(ClassLoader.getSystemClassLoader());
9426684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        FancyLoader loader2 = new FancyLoader(ClassLoader.getSystemClassLoader());
9526684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
9626684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        try {
9726684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            Class target1 = loader1.loadClass("MutationTarget");
9826684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            Class target2 = loader2.loadClass("MutationTarget");
9926684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
10026684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            if (target1 == target2) {
10126684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe                throw new RuntimeException("target1 should not be equal to target2");
10226684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            }
10326684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
10426684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            Class mutator1 = loader1.loadClass("Mutator");
10526684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            Class mutator2 = loader2.loadClass("Mutator");
10626684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
10726684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            if (mutator1 == mutator2) {
10826684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe                throw new RuntimeException("mutator1 should not be equal to mutator2");
10926684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            }
11026684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
11126684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            runMutator(mutator1, 1);
11226684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
11326684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            int value = getMutationTargetValue(target1);
11426684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            if (value != 1) {
11526684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe                throw new RuntimeException("target 1 has unexpected value " + value);
11626684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            }
11726684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            value = getMutationTargetValue(target2);
11826684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            if (value != 0) {
11926684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe                throw new RuntimeException("target 2 has unexpected value " + value);
12026684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            }
12126684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
12226684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            runMutator(mutator2, 2);
12326684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
12426684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            value = getMutationTargetValue(target1);
12526684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            if (value != 1) {
12626684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe                throw new RuntimeException("target 1 has unexpected value " + value);
12726684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            }
12826684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            value = getMutationTargetValue(target2);
12926684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            if (value != 2) {
13026684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe                throw new RuntimeException("target 2 has unexpected value " + value);
13126684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            }
13226684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        } catch (Exception ex) {
13326684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe            ex.printStackTrace();
13426684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        }
13526684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe    }
13626684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
13726684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe    private static void runMutator(Class c, int v) throws Exception {
13826684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        java.lang.reflect.Method m = c.getDeclaredMethod("mutate", int.class);
13926684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        m.invoke(null, v);
14026684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe    }
14126684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe
14226684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe    private static int getMutationTargetValue(Class c) throws Exception {
14326684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        java.lang.reflect.Field f = c.getDeclaredField("value");
14426684c0fc0c77f057c9c25f15cd42553491ac4a9Andreas Gampe        return f.getInt(null);
1455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
1485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * See if we can load a class that isn't public to us.  We should be
1495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * able to load it but not instantiate it.
1505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
1515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testAccess1(ClassLoader loader) {
1525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class altClass;
1535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            altClass = loader.loadClass("Inaccessible1");
1565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
1575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed");
1585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            cnfe.printStackTrace();
1595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
1605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
1635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
1645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = altClass.newInstance();
1665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("ERROR: Inaccessible1 was accessible");
1675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
1685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
1695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
1705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
1715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected access exception #1");
1725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //System.out.println("+++ " + iae);
1735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
1745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
1785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * See if we can load a class whose base class is not accessible to it
1795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * (though the base *is* accessible to us).
1805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
1815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testAccess2(ClassLoader loader) {
1825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class altClass;
1835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            altClass = loader.loadClass("Inaccessible2");
1864d9716c19cc25911e639272048abd0d6702bb082Brian Carlstrom            System.err.println("ERROR: Inaccessible2 was accessible: " + altClass);
1875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
1885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Throwable cause = cnfe.getCause();
1895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (cause instanceof IllegalAccessError) {
1905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println("Got expected CNFE/IAE #2");
1915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            } else {
1925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.err.println("Got unexpected CNFE/IAE #2");
1935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                cnfe.printStackTrace();
1945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
1955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
1995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * See if we can load a class with an inaccessible interface.
2005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
2015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testAccess3(ClassLoader loader) {
2025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class altClass;
2035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            altClass = loader.loadClass("Inaccessible3");
2064d9716c19cc25911e639272048abd0d6702bb082Brian Carlstrom            System.err.println("ERROR: Inaccessible3 was accessible: " + altClass);
2075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
2085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Throwable cause = cnfe.getCause();
2095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (cause instanceof IllegalAccessError) {
2105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println("Got expected CNFE/IAE #3");
2115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            } else {
2125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.err.println("Got unexpected CNFE/IAE #3");
2135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                cnfe.printStackTrace();
2145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
2155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
2195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Test a doubled class that extends the base class.
2205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
2215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testExtend(ClassLoader loader) {
2225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class doubledExtendClass;
2235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
2245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get the "alternate" version of DoubledExtend */
2265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            doubledExtendClass = loader.loadClass("DoubledExtend");
2285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //System.out.println("+++ DoubledExtend is " + doubledExtendClass
2295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //    + " in " + doubledExtendClass.getClassLoader());
2305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
2315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
2325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
2365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = doubledExtendClass.newInstance();
2385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
2395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
2405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
2425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
2435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
2455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected LinkageError on DE");
2465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* use the base class reference to get a CL-specific instance */
2505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Base baseRef = (Base) obj;
2515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        DoubledExtend de = baseRef.getExtended();
2525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* try to call through it */
2545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            String result;
2565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            result = Base.doStuff(de);
2585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("ERROR: did not get LinkageError on DE");
2595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("(result=" + result + ")");
2605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
2615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected LinkageError on DE");
2625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
2675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Test a doubled class that extends the base class, but is okay since
2685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * it doesn't override the base class method.
2695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
2705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testExtendOkay(ClassLoader loader) {
2715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class doubledExtendOkayClass;
2725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
2735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get the "alternate" version of DoubledExtendOkay */
2755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            doubledExtendOkayClass = loader.loadClass("DoubledExtendOkay");
2775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
2785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
2795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
2835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = doubledExtendOkayClass.newInstance();
2855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
2865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
2875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
2895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
2905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
2925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("Got unexpected LinkageError on DEO");
2935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            le.printStackTrace();
2945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* use the base class reference to get a CL-specific instance */
2985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        BaseOkay baseRef = (BaseOkay) obj;
2995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        DoubledExtendOkay de = baseRef.getExtended();
3005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* try to call through it */
3025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            String result;
3045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            result = BaseOkay.doStuff(de);
3065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got DEO result " + result);
3075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
3085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("Got unexpected LinkageError on DEO");
3095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            le.printStackTrace();
3105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
3155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Try to access a doubled class through a class that implements
3165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * an interface declared in a different class.
3175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
3185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testInterface(ClassLoader loader) {
3195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class getDoubledClass;
3205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
3215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get GetDoubled from the "alternate" class loader */
3235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            getDoubledClass = loader.loadClass("GetDoubled");
3255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
3265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
3275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
3315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = getDoubledClass.newInstance();
3335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
3345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
3355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
3375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
3385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
3405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            // Dalvik bails here
3415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on GD");
3425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
3465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Cast the object to the interface, and try to use it.
3475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
3485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        IGetDoubled iface = (IGetDoubled) obj;
3495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            /* "de" will be the wrong variety of DoubledExtendOkay */
3515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            DoubledExtendOkay de = iface.getDoubled();
3525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            // reference impl bails here
3535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            String str = de.getStr();
3545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
3555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on GD");
3565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.err.println("Should have failed by now on GetDoubled");
3595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
3625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Throw an abstract class into the middle and see what happens.
3635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
3645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testAbstract(ClassLoader loader) {
3655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class abstractGetClass;
3665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
3675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get AbstractGet from the "alternate" loader */
3695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            abstractGetClass = loader.loadClass("AbstractGet");
3715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
3725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass ta failed: " + cnfe);
3735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
3775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = abstractGetClass.newInstance();
3795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
3805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
3815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
3835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
3845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
3865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on TA");
3875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* use the base class reference to get a CL-specific instance */
3915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        BaseOkay baseRef = (BaseOkay) obj;
3925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        DoubledExtendOkay de = baseRef.getExtended();
3935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* try to call through it */
3955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            String result;
3975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            result = BaseOkay.doStuff(de);
3995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
4005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on TA");
4015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
4035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.err.println("Should have failed by now in testAbstract");
4045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
4055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
4075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Test a doubled class that implements a common interface.
4085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
4095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testImplement(ClassLoader loader) {
4105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class doubledImplementClass;
4115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
4125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        useImplement(new DoubledImplement(), true);
4145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get the "alternate" version of DoubledImplement */
4165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
4175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            doubledImplementClass = loader.loadClass("DoubledImplement");
4185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
4195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
4205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
4225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
4245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
4255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = doubledImplementClass.newInstance();
4265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
4275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
4285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
4305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
4315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
4335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on DI (early)");
4345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
4365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* if we lived this long, try to do something with it */
4385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        ICommon icommon = (ICommon) obj;
4395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        useImplement(icommon.getDoubledInstance(), false);
4405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
4415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
4435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Do something with a DoubledImplement instance.
4445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
4455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void useImplement(DoubledImplement di, boolean isOne) {
4465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //System.out.println("useObject: " + di.toString() + " -- "
4475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //    + di.getClass().getClassLoader());
4485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
4495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            di.one();
4505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (!isOne) {
4515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.err.println("ERROR: did not get LinkageError on DI");
4525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
4535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
4545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (!isOne) {
4555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println("Got LinkageError on DI (late)");
4565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            } else {
4575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                throw le;
4585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
4595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
4605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
4615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
4645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Test a class that implements an interface with a super-interface
4655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * that refers to a doubled class.
4665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
4675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testIfaceImplement(ClassLoader loader) {
4685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class ifaceImplClass;
4695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
4705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
4725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Create an instance of IfaceImpl.  We also pull in
4735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * DoubledImplement2 from the other class loader; without this
4745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * we don't fail in some implementations.
4755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
4765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
4775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ifaceImplClass = loader.loadClass("IfaceImpl");
4785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ifaceImplClass = loader.loadClass("DoubledImplement2");
4795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
4805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
4815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
4835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
4855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
4865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = ifaceImplClass.newInstance();
4875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
4885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
4895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
4915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
4925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
4945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on IDI (early)");
4955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //System.out.println(le);
4965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
4985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
5005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Without the pre-load of FancyLoader->DoubledImplement2, some
5015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * implementations will happily execute through this part.  "obj"
5025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * comes from FancyLoader, but the di2 returned from ifaceSuper
5035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * comes from the application class loader.
5045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
5055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        IfaceSuper ifaceSuper = (IfaceSuper) obj;
5065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        DoubledImplement2 di2 = ifaceSuper.getDoubledInstance2();
5075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        di2.one();
5085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
509598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom
510598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom    static void testClassForName() throws Exception {
511598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom        System.out.println(Class.forName("Main").toString());
512598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom        try {
513598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom            System.out.println(Class.forName("Main", false, null).toString());
514598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom        } catch (ClassNotFoundException expected) {
515598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom            System.out.println("Got expected ClassNotFoundException");
516598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom        }
517598854726a5d50c18fa720af6b097279e5e01584Brian Carlstrom    }
5185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
519