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
175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/**
185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Class loader test.
195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class Main {
215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Main entry point.
235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void main(String[] args) {
255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        FancyLoader loader;
265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        loader = new FancyLoader(ClassLoader.getSystemClassLoader());
285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //System.out.println("SYSTEM: " + ClassLoader.getSystemClassLoader());
295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //System.out.println("ALTERN: " + loader);
305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * This statement has no effect on this program, but it can
335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * change the point where a LinkageException is thrown in
345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * testImplement().  When this is present the "reference
355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * implementation" throws an exception from Class.newInstance(),
365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * when it's absent the exception is deferred until the first time
375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * we call a method that isn't actually implemented.
385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         *
395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * This isn't the class that fails -- it's a class with the same
405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * name in the "fancy" class loader --  but the VM thinks it has a
415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * reference to one of these; presumably the difference is that
425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * without this the VM finds itself holding a reference to an
435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * instance of an uninitialized class.
445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("base: " + DoubledImplement.class);
465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("base2: " + DoubledImplement2.class);
475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Run tests.
505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testAccess1(loader);
525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testAccess2(loader);
535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testAccess3(loader);
545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testExtend(loader);
565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testExtendOkay(loader);
575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testInterface(loader);
585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testAbstract(loader);
595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testImplement(loader);
605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testIfaceImplement(loader);
615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * See if we can load a class that isn't public to us.  We should be
655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * able to load it but not instantiate it.
665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testAccess1(ClassLoader loader) {
685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class altClass;
695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            altClass = loader.loadClass("Inaccessible1");
725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed");
745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            cnfe.printStackTrace();
755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = altClass.newInstance();
825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("ERROR: Inaccessible1 was accessible");
835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected access exception #1");
885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //System.out.println("+++ " + iae);
895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * See if we can load a class whose base class is not accessible to it
955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * (though the base *is* accessible to us).
965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testAccess2(ClassLoader loader) {
985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class altClass;
995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            altClass = loader.loadClass("Inaccessible2");
1024d9716c19cc25911e639272048abd0d6702bb082Brian Carlstrom            System.err.println("ERROR: Inaccessible2 was accessible: " + altClass);
1035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
1045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Throwable cause = cnfe.getCause();
1055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (cause instanceof IllegalAccessError) {
1065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println("Got expected CNFE/IAE #2");
1075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            } else {
1085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.err.println("Got unexpected CNFE/IAE #2");
1095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                cnfe.printStackTrace();
1105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
1115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
1155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * See if we can load a class with an inaccessible interface.
1165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
1175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testAccess3(ClassLoader loader) {
1185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class altClass;
1195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            altClass = loader.loadClass("Inaccessible3");
1224d9716c19cc25911e639272048abd0d6702bb082Brian Carlstrom            System.err.println("ERROR: Inaccessible3 was accessible: " + altClass);
1235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
1245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Throwable cause = cnfe.getCause();
1255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (cause instanceof IllegalAccessError) {
1265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println("Got expected CNFE/IAE #3");
1275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            } else {
1285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.err.println("Got unexpected CNFE/IAE #3");
1295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                cnfe.printStackTrace();
1305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
1315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
1355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Test a doubled class that extends the base class.
1365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
1375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testExtend(ClassLoader loader) {
1385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class doubledExtendClass;
1395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
1405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get the "alternate" version of DoubledExtend */
1425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            doubledExtendClass = loader.loadClass("DoubledExtend");
1445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //System.out.println("+++ DoubledExtend is " + doubledExtendClass
1455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //    + " in " + doubledExtendClass.getClassLoader());
1465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
1475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
1485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
1495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
1525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = doubledExtendClass.newInstance();
1545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
1555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
1565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
1575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
1585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
1595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
1605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
1615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected LinkageError on DE");
1625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
1635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* use the base class reference to get a CL-specific instance */
1665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Base baseRef = (Base) obj;
1675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        DoubledExtend de = baseRef.getExtended();
1685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* try to call through it */
1705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            String result;
1725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            result = Base.doStuff(de);
1745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("ERROR: did not get LinkageError on DE");
1755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("(result=" + result + ")");
1765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
1775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got expected LinkageError on DE");
1785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
1795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
1835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Test a doubled class that extends the base class, but is okay since
1845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * it doesn't override the base class method.
1855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
1865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testExtendOkay(ClassLoader loader) {
1875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class doubledExtendOkayClass;
1885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
1895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get the "alternate" version of DoubledExtendOkay */
1915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            doubledExtendOkayClass = loader.loadClass("DoubledExtendOkay");
1935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
1945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
1955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
1965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
1995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = doubledExtendOkayClass.newInstance();
2015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
2025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
2035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
2055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
2065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
2085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("Got unexpected LinkageError on DEO");
2095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            le.printStackTrace();
2105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* use the base class reference to get a CL-specific instance */
2145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        BaseOkay baseRef = (BaseOkay) obj;
2155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        DoubledExtendOkay de = baseRef.getExtended();
2165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* try to call through it */
2185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            String result;
2205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            result = BaseOkay.doStuff(de);
2225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got DEO result " + result);
2235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
2245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("Got unexpected LinkageError on DEO");
2255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            le.printStackTrace();
2265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
2315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Try to access a doubled class through a class that implements
2325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * an interface declared in a different class.
2335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
2345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testInterface(ClassLoader loader) {
2355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class getDoubledClass;
2365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
2375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get GetDoubled from the "alternate" class loader */
2395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            getDoubledClass = loader.loadClass("GetDoubled");
2415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
2425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
2435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
2475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = getDoubledClass.newInstance();
2495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
2505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
2515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
2535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
2545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
2565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            // Dalvik bails here
2575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on GD");
2585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
2625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Cast the object to the interface, and try to use it.
2635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
2645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        IGetDoubled iface = (IGetDoubled) obj;
2655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            /* "de" will be the wrong variety of DoubledExtendOkay */
2675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            DoubledExtendOkay de = iface.getDoubled();
2685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            // reference impl bails here
2695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            String str = de.getStr();
2705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
2715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on GD");
2725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.err.println("Should have failed by now on GetDoubled");
2755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
2785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Throw an abstract class into the middle and see what happens.
2795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
2805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testAbstract(ClassLoader loader) {
2815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class abstractGetClass;
2825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
2835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get AbstractGet from the "alternate" loader */
2855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            abstractGetClass = loader.loadClass("AbstractGet");
2875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
2885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass ta failed: " + cnfe);
2895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
2935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
2945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = abstractGetClass.newInstance();
2955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
2965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
2975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
2995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
3005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
3025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on TA");
3035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* use the base class reference to get a CL-specific instance */
3075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        BaseOkay baseRef = (BaseOkay) obj;
3085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        DoubledExtendOkay de = baseRef.getExtended();
3095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* try to call through it */
3115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            String result;
3135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            result = BaseOkay.doStuff(de);
3155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
3165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on TA");
3175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.err.println("Should have failed by now in testAbstract");
3205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
3235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Test a doubled class that implements a common interface.
3245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
3255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testImplement(ClassLoader loader) {
3265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class doubledImplementClass;
3275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
3285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        useImplement(new DoubledImplement(), true);
3305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* get the "alternate" version of DoubledImplement */
3325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            doubledImplementClass = loader.loadClass("DoubledImplement");
3345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
3355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
3365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
3405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = doubledImplementClass.newInstance();
3425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
3435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
3445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
3465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
3475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
3495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on DI (early)");
3505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* if we lived this long, try to do something with it */
3545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        ICommon icommon = (ICommon) obj;
3555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        useImplement(icommon.getDoubledInstance(), false);
3565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
3595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Do something with a DoubledImplement instance.
3605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
3615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void useImplement(DoubledImplement di, boolean isOne) {
3625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //System.out.println("useObject: " + di.toString() + " -- "
3635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        //    + di.getClass().getClassLoader());
3645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            di.one();
3665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (!isOne) {
3675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.err.println("ERROR: did not get LinkageError on DI");
3685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
3695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
3705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (!isOne) {
3715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println("Got LinkageError on DI (late)");
3725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            } else {
3735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                throw le;
3745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
3755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
3805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Test a class that implements an interface with a super-interface
3815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * that refers to a doubled class.
3825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
3835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void testIfaceImplement(ClassLoader loader) {
3845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Class ifaceImplClass;
3855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Object obj;
3865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
3885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Create an instance of IfaceImpl.  We also pull in
3895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * DoubledImplement2 from the other class loader; without this
3905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * we don't fail in some implementations.
3915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
3925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
3935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ifaceImplClass = loader.loadClass("IfaceImpl");
3945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ifaceImplClass = loader.loadClass("DoubledImplement2");
3955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (ClassNotFoundException cnfe) {
3965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("loadClass failed: " + cnfe);
3975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
3985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* instantiate */
4015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
4025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            obj = ifaceImplClass.newInstance();
4035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (InstantiationException ie) {
4045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + ie);
4055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (IllegalAccessException iae) {
4075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("newInstance failed: " + iae);
4085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (LinkageError le) {
4105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Got LinkageError on IDI (early)");
4115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            //System.out.println(le);
4125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
4135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
4145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
4155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
4165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Without the pre-load of FancyLoader->DoubledImplement2, some
4175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * implementations will happily execute through this part.  "obj"
4185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * comes from FancyLoader, but the di2 returned from ifaceSuper
4195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * comes from the application class loader.
4205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
4215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        IfaceSuper ifaceSuper = (IfaceSuper) obj;
4225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        DoubledImplement2 di2 = ifaceSuper.getDoubledInstance2();
4235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        di2.one();
4245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
4255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
426