1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17/*
18 * Copyright (C) 2008 The Android Open Source Project
19 *
20 * Licensed under the Apache License, Version 2.0 (the "License");
21 * you may not use this file except in compliance with the License.
22 * You may obtain a copy of the License at
23 *
24 * http://www.apache.org/licenses/LICENSE-2.0
25 *
26 * Unless required by applicable law or agreed to in writing, software
27 * distributed under the License is distributed on an "AS IS" BASIS,
28 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
29 * See the License for the specific language governing permissions and
30 * limitations under the License.
31 */
32
33package java.lang;
34
35import java.io.IOException;
36import java.io.InputStream;
37import java.net.URL;
38import java.nio.ByteBuffer;
39import java.security.ProtectionDomain;
40import java.util.Collection;
41import java.util.Enumeration;
42import java.util.Map;
43import java.util.HashMap;
44
45import dalvik.system.PathClassLoader;
46import dalvik.system.VMStack;
47
48/**
49 * Loads classes and resources from a repository. One or more class loaders are
50 * installed at runtime. These are consulted whenever the runtime system needs a
51 * specific class that is not yet available in-memory. Typically, class loaders
52 * are grouped into a tree where child class loaders delegate all requests to
53 * parent class loaders. Only if the parent class loader cannot satisfy the
54 * request, the child class loader itself tries to handle it.
55 * <p>
56 * {@code ClassLoader} is an abstract class that implements the common
57 * infrastructure required by all class loaders. Android provides several
58 * concrete implementations of the class, with
59 * {@link dalvik.system.PathClassLoader} being the one typically used. Other
60 * applications may implement subclasses of {@code ClassLoader} to provide
61 * special ways for loading classes.
62 * </p>
63 *
64 * @since Android 1.0
65 * @see Class
66 */
67public abstract class ClassLoader {
68
69    // BEGIN android-note
70    /*
71     * Because of a potential class initialization race between ClassLoader and
72     * java.lang.System, reproducible when using JDWP with "suspend=y", we defer
73     * creation of the system class loader until first use. We use a static
74     * inner class to get synchronization at init time without having to sync on
75     * every access.
76     */
77    // END android-note
78    /**
79     * The 'System' ClassLoader - the one that is responsible for loading
80     * classes from the classpath. It is not equal to the bootstrap class loader -
81     * that one handles the built-in classes.
82     *
83     * @see #getSystemClassLoader()
84     */
85    static private class SystemClassLoader {
86        public static ClassLoader loader = ClassLoader.createSystemClassLoader();
87    }
88
89    /**
90     * The parent ClassLoader.
91     */
92    private ClassLoader parent;
93
94    /**
95     * The packages known to the class loader.
96     */
97    private Map<String, Package> packages = new HashMap<String, Package>();
98
99    /**
100     * Create the system class loader. Note this is NOT the bootstrap class
101     * loader (which is managed by the VM). We use a null value for the parent
102     * to indicate that the bootstrap loader is our parent.
103     */
104    private static ClassLoader createSystemClassLoader() {
105        String classPath = System.getProperty("java.class.path", ".");
106
107        // String[] paths = classPath.split(":");
108        // URL[] urls = new URL[paths.length];
109        // for (int i = 0; i < paths.length; i++) {
110        // try {
111        // urls[i] = new URL("file://" + paths[i]);
112        // }
113        // catch (Exception ex) {
114        // ex.printStackTrace();
115        // }
116        // }
117        //
118        // return new java.net.URLClassLoader(urls, null);
119
120        // TODO Make this a java.net.URLClassLoader once we have those?
121        return new PathClassLoader(classPath, BootClassLoader.getInstance());
122    }
123
124    /**
125     * Returns the system class loader. This is the parent for new
126     * {@code ClassLoader} instances and is typically the class loader used to
127     * start the application. If a security manager is present and the caller's
128     * class loader is neither {@code null} nor the same as or an ancestor of
129     * the system class loader, then this method calls the security manager's
130     * checkPermission method with a RuntimePermission("getClassLoader")
131     * permission to ensure that it is ok to access the system class loader. If
132     * not, a {@code SecurityException} is thrown.
133     *
134     * @return the system class loader.
135     * @throws SecurityException
136     *             if a security manager exists and it does not allow access to
137     *             the system class loader.
138     * @since Android 1.0
139     */
140    public static ClassLoader getSystemClassLoader() {
141        SecurityManager smgr = System.getSecurityManager();
142        if (smgr != null) {
143            ClassLoader caller = VMStack.getCallingClassLoader();
144            if (caller != null && !caller.isAncestorOf(SystemClassLoader.loader)) {
145                smgr.checkPermission(new RuntimePermission("getClassLoader"));
146            }
147        }
148
149        return SystemClassLoader.loader;
150    }
151
152    /**
153     * Finds the URL of the resource with the specified name. The system class
154     * loader's resource lookup algorithm is used to find the resource.
155     *
156     * @return the {@code URL} object for the requested resource or {@code null}
157     *         if the resource can not be found.
158     * @param resName
159     *            the name of the resource to find.
160     * @see Class#getResource
161     * @since Android 1.0
162     */
163    public static URL getSystemResource(String resName) {
164        return SystemClassLoader.loader.getResource(resName);
165    }
166
167    /**
168     * Returns an enumeration of URLs for the resource with the specified name.
169     * The system class loader's resource lookup algorithm is used to find the
170     * resource.
171     *
172     * @return an enumeration of {@code URL} objects containing the requested
173     *         resources.
174     * @param resName
175     *            the name of the resource to find.
176     * @throws IOException
177     *             if an I/O error occurs.
178     * @since Android 1.0
179     */
180    public static Enumeration<URL> getSystemResources(String resName) throws IOException {
181        return SystemClassLoader.loader.getResources(resName);
182    }
183
184    /**
185     * Returns a stream for the resource with the specified name. The system
186     * class loader's resource lookup algorithm is used to find the resource.
187     * Basically, the contents of the java.class.path are searched in order,
188     * looking for a path which matches the specified resource.
189     *
190     * @return a stream for the resource or {@code null}.
191     * @param resName
192     *            the name of the resource to find.
193     * @see Class#getResourceAsStream
194     * @since Android 1.0
195     */
196    public static InputStream getSystemResourceAsStream(String resName) {
197        return SystemClassLoader.loader.getResourceAsStream(resName);
198    }
199
200    /**
201     * Constructs a new instance of this class with the system class loader as
202     * its parent.
203     *
204     * @throws SecurityException
205     *             if a security manager exists and it does not allow the
206     *             creation of a new {@code ClassLoader}.
207     * @since Android 1.0
208     */
209    protected ClassLoader() {
210        this(getSystemClassLoader(), false);
211    }
212
213    /**
214     * Constructs a new instance of this class with the specified class loader
215     * as its parent.
216     *
217     * @param parentLoader
218     *            The {@code ClassLoader} to use as the new class loader's
219     *            parent.
220     * @throws SecurityException
221     *             if a security manager exists and it does not allow the
222     *             creation of new a new {@code ClassLoader}.
223     * @since Android 1.0
224     */
225    protected ClassLoader(ClassLoader parentLoader) {
226        this(parentLoader, false);
227    }
228
229    /*
230     * constructor for the BootClassLoader which needs parent to be null.
231     */
232    ClassLoader(ClassLoader parentLoader, boolean nullAllowed) {
233        SecurityManager smgr = System.getSecurityManager();
234        if (smgr != null) {
235            smgr.checkCreateClassLoader();
236        }
237
238        if (parentLoader == null && !nullAllowed) {
239            throw new NullPointerException(
240                    "Parent ClassLoader may not be null");
241        }
242
243        parent = parentLoader;
244    }
245
246    /**
247     * Constructs a new class from an array of bytes containing a class
248     * definition in class file format.
249     *
250     * @param classRep
251     *            the memory image of a class file.
252     * @param offset
253     *            the offset into {@code classRep}.
254     * @param length
255     *            the length of the class file.
256     * @return the {@code Class} object created from the specified subset of
257     *         data in {@code classRep}.
258     * @throws ClassFormatError
259     *             if {@code classRep} does not contain a valid class.
260     * @throws IndexOutOfBoundsException
261     *             if {@code offset < 0}, {@code length < 0} or if
262     *             {@code offset + length} is greater than the length of
263     *             {@code classRep}.
264     * @deprecated Use {@link #defineClass(String, byte[], int, int)}
265     * @since Android 1.0
266     */
267    @Deprecated
268    protected final Class<?> defineClass(byte[] classRep, int offset, int length)
269            throws ClassFormatError {
270
271        return VMClassLoader.defineClass(this, classRep, offset, length, null);
272    }
273
274    /**
275     * Constructs a new class from an array of bytes containing a class
276     * definition in class file format.
277     *
278     * @param className
279     *            the expected name of the new class, may be {@code null} if not
280     *            known.
281     * @param classRep
282     *            the memory image of a class file.
283     * @param offset
284     *            the offset into {@code classRep}.
285     * @param length
286     *            the length of the class file.
287     * @return the {@code Class} object created from the specified subset of
288     *         data in {@code classRep}.
289     * @throws ClassFormatError
290     *             if {@code classRep} does not contain a valid class.
291     * @throws IndexOutOfBoundsException
292     *             if {@code offset < 0}, {@code length < 0} or if
293     *             {@code offset + length} is greater than the length of
294     *             {@code classRep}.
295     * @since Android 1.0
296     */
297    protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length)
298            throws ClassFormatError {
299
300        // TODO Define a default ProtectionDomain on first use
301        return defineClass(className, classRep, offset, length, null);
302    }
303
304    /**
305     * Constructs a new class from an array of bytes containing a class
306     * definition in class file format and assigns the specified protection
307     * domain to the new class. If the provided protection domain is
308     * {@code null} then a default protection domain is assigned to the class.
309     *
310     * @param className
311     *            the expected name of the new class, may be {@code null} if not
312     *            known.
313     * @param classRep
314     *            the memory image of a class file.
315     * @param offset
316     *            the offset into {@code classRep}.
317     * @param length
318     *            the length of the class file.
319     * @param protectionDomain
320     *            the protection domain to assign to the loaded class, may be
321     *            {@code null}.
322     * @return the {@code Class} object created from the specified subset of
323     *         data in {@code classRep}.
324     * @throws ClassFormatError
325     *             if {@code classRep} does not contain a valid class.
326     * @throws IndexOutOfBoundsException
327     *             if {@code offset < 0}, {@code length < 0} or if
328     *             {@code offset + length} is greater than the length of
329     *             {@code classRep}.
330     * @throws NoClassDefFoundError
331     *             if {@code className} is not equal to the name of the class
332     *             contained in {@code classRep}.
333     * @since Android 1.0
334     */
335    protected final Class<?> defineClass(String className, byte[] classRep, int offset, int length,
336            ProtectionDomain protectionDomain) throws java.lang.ClassFormatError {
337
338        return VMClassLoader.defineClass(this, className, classRep, offset, length,
339                protectionDomain);
340    }
341
342    /**
343     * Defines a new class with the specified name, byte code from the byte
344     * buffer and the optional protection domain. If the provided protection
345     * domain is {@code null} then a default protection domain is assigned to
346     * the class.
347     *
348     * @param name
349     *            the expected name of the new class, may be {@code null} if not
350     *            known.
351     * @param b
352     *            the byte buffer containing the byte code of the new class.
353     * @param protectionDomain
354     *            the protection domain to assign to the loaded class, may be
355     *            {@code null}.
356     * @return the {@code Class} object created from the data in {@code b}.
357     * @throws ClassFormatError
358     *             if {@code b} does not contain a valid class.
359     * @throws NoClassDefFoundError
360     *             if {@code className} is not equal to the name of the class
361     *             contained in {@code b}.
362     * @since Android 1.0
363     */
364    protected final Class<?> defineClass(String name, ByteBuffer b,
365            ProtectionDomain protectionDomain) throws ClassFormatError {
366
367        byte[] temp = new byte[b.remaining()];
368        b.get(temp);
369        return defineClass(name, temp, 0, temp.length, protectionDomain);
370    }
371
372    /**
373     * Overridden by subclasses, throws a {@code ClassNotFoundException} by
374     * default. This method is called by {@code loadClass} after the parent
375     * {@code ClassLoader} has failed to find a loaded class of the same name.
376     *
377     * @param className
378     *            the name of the class to look for.
379     * @return the {@code Class} object that is found.
380     * @throws ClassNotFoundException
381     *             if the class cannot be found.
382     * @since Android 1.0
383     */
384    protected Class<?> findClass(String className) throws ClassNotFoundException {
385        throw new ClassNotFoundException(className);
386    }
387
388    /**
389     * Returns the class with the specified name if it has already been loaded
390     * by the virtual machine or {@code null} if it has not yet been loaded.
391     *
392     * @param className
393     *            the name of the class to look for.
394     * @return the {@code Class} object or {@code null} if the requested class
395     *         has not been loaded.
396     * @since Android 1.0
397     */
398    protected final Class<?> findLoadedClass(String className) {
399        ClassLoader loader;
400        if (this == BootClassLoader.getInstance())
401            loader = null;
402        else
403            loader = this;
404        return VMClassLoader.findLoadedClass(loader, className);
405    }
406
407    /**
408     * Finds the class with the specified name, loading it using the system
409     * class loader if necessary.
410     *
411     * @param className
412     *            the name of the class to look for.
413     * @return the {@code Class} object with the requested {@code className}.
414     * @throws ClassNotFoundException
415     *             if the class can not be found.
416     * @since Android 1.0
417     */
418    protected final Class<?> findSystemClass(String className) throws ClassNotFoundException {
419        return Class.forName(className, false, getSystemClassLoader());
420    }
421
422    /**
423     * Returns this class loader's parent.
424     *
425     * @return this class loader's parent or {@code null}.
426     * @throws SecurityException
427     *             if a security manager exists and it does not allow to
428     *             retrieve the parent class loader.
429     * @since Android 1.0
430     */
431    public final ClassLoader getParent() {
432        SecurityManager smgr = System.getSecurityManager();
433        if (smgr != null) {
434            smgr.checkPermission(new RuntimePermission("getClassLoader"));
435        }
436
437        return parent;
438    }
439
440    /**
441     * Returns the URL of the resource with the specified name. This
442     * implementation first tries to use the parent class loader to find the
443     * resource; if this fails then {@link #findResource(String)} is called to
444     * find the requested resource.
445     *
446     * @param resName
447     *            the name of the resource to find.
448     * @return the {@code URL} object for the requested resource or {@code null}
449     *         if either the resource can not be found or a security manager
450     *         does not allow to access the resource.
451     * @see Class#getResource
452     * @since Android 1.0
453     */
454    public URL getResource(String resName) {
455        URL resource = null;
456
457        resource = parent.getResource(resName);
458
459        if (resource == null) {
460            resource = findResource(resName);
461        }
462
463        return resource;
464    }
465
466    /**
467     * Returns an enumeration of URLs for the resource with the specified name.
468     * This implementation first uses this class loader's parent to find the
469     * resource, then it calls {@link #findResources(String)} to get additional
470     * URLs. The returned enumeration contains the {@code URL} objects of both
471     * find operations.
472     *
473     * @return an enumeration of {@code URL} objects for the requested resource.
474     * @param resName
475     *            the name of the resource to find.
476     * @throws IOException
477     *             if an I/O error occurs.
478     * @since Android 1.0
479     */
480    @SuppressWarnings("unchecked")
481    public Enumeration<URL> getResources(String resName) throws IOException {
482
483        Enumeration first = parent.getResources(resName);
484        Enumeration second = findResources(resName);
485
486        return new TwoEnumerationsInOne(first, second);
487    }
488
489    /**
490     * Returns a stream for the resource with the specified name. See
491     * {@link #getResource(String)} for a description of the lookup algorithm
492     * used to find the resource.
493     *
494     * @return a stream for the resource or {@code null} if either the resource
495     *         can not be found or a security manager does not allow to access
496     *         the resource.
497     * @param resName
498     *            the name of the resource to find.
499     * @see Class#getResourceAsStream
500     * @since Android 1.0
501     */
502    public InputStream getResourceAsStream(String resName) {
503        try {
504            URL url = getResource(resName);
505            if (url != null) {
506                return url.openStream();
507            }
508        } catch (IOException ex) {
509            // Don't want to see the exception.
510        }
511
512        return null;
513    }
514
515    /**
516     * Loads the class with the specified name. Invoking this method is
517     * equivalent to calling {@code loadClass(className, false)}.
518     * <p>
519     * <strong>Note:</strong> In the Android reference implementation, the
520     * second parameter of {@link #loadClass(String, boolean)} is ignored
521     * anyway.
522     * </p>
523     *
524     * @return the {@code Class} object.
525     * @param className
526     *            the name of the class to look for.
527     * @throws ClassNotFoundException
528     *             if the class can not be found.
529     * @since Android 1.0
530     */
531    public Class<?> loadClass(String className) throws ClassNotFoundException {
532        return loadClass(className, false);
533    }
534
535    /**
536     * Loads the class with the specified name, optionally linking it after
537     * loading. The following steps are performed:
538     * <ol>
539     * <li> Call {@link #findLoadedClass(String)} to determine if the requested
540     * class has already been loaded.</li>
541     * <li>If the class has not yet been loaded: Invoke this method on the
542     * parent class loader.</li>
543     * <li>If the class has still not been loaded: Call
544     * {@link #findClass(String)} to find the class.</li>
545     * </ol>
546     * <p>
547     * <strong>Note:</strong> In the Android reference implementation, the
548     * {@code resolve} parameter is ignored; classes are never linked.
549     * </p>
550     *
551     * @return the {@code Class} object.
552     * @param className
553     *            the name of the class to look for.
554     * @param resolve
555     *            Indicates if the class should be resolved after loading. This
556     *            parameter is ignored on the Android reference implementation;
557     *            classes are not resolved.
558     * @throws ClassNotFoundException
559     *             if the class can not be found.
560     * @since Android 1.0
561     */
562    protected Class<?> loadClass(String className, boolean resolve) throws ClassNotFoundException {
563        Class<?> clazz = findLoadedClass(className);
564
565        if (clazz == null) {
566            try {
567                clazz = parent.loadClass(className, false);
568            } catch (ClassNotFoundException e) {
569                // Don't want to see this.
570            }
571
572            if (clazz == null) {
573                clazz = findClass(className);
574            }
575        }
576
577        return clazz;
578    }
579
580    /**
581     * Forces a class to be linked (initialized). If the class has already been
582     * linked this operation has no effect.
583     * <p>
584     * <strong>Note:</strong> In the Android reference implementation, this
585     * method has no effect.
586     * </p>
587     *
588     * @param clazz
589     *            the class to link.
590     * @since Android 1.0
591     */
592    protected final void resolveClass(Class<?> clazz) {
593        // no-op, doesn't make sense on android.
594    }
595
596    /**
597     * Indicates whether this class loader is the system class loader. This
598     * method must be provided by the virtual machine vendor, as it is used by
599     * other provided class implementations in this package. A sample
600     * implementation of this method is provided by the reference
601     * implementation. This method is used by
602     * SecurityManager.classLoaderDepth(), currentClassLoader() and
603     * currentLoadedClass(). Returns true if the receiver is a system class
604     * loader.
605     * <p>
606     * Note that this method has package visibility only. It is defined here to
607     * avoid the security manager check in getSystemClassLoader, which would be
608     * required to implement this method anywhere else.
609     * </p>
610     *
611     * @return {@code true} if the receiver is a system class loader
612     * @see Class#getClassLoaderImpl()
613     */
614    final boolean isSystemClassLoader() {
615        return false;
616    }
617
618    /**
619     * <p>
620     * Returns true if the receiver is ancestor of another class loader. It also
621     * returns true if the two class loader are equal.
622     * </p>
623     * <p>
624     * Note that this method has package visibility only. It is defined here to
625     * avoid the security manager check in getParent, which would be required to
626     * implement this method anywhere else. The method is also required in other
627     * places where class loaders are accesses.
628     * </p>
629     *
630     * @param child
631     *            A child candidate
632     * @return {@code true} if the receiver is ancestor of, or equal to,
633     *         the parameter
634     */
635    final boolean isAncestorOf(ClassLoader child) {
636        for (ClassLoader current = child; current != null;
637                current = current.parent) {
638            if (current == this) {
639                return true;
640            }
641        }
642        return false;
643    }
644
645    /**
646     * Finds the URL of the resource with the specified name. This
647     * implementation just returns {@code null}; it should be overridden in
648     * subclasses.
649     *
650     * @param resName
651     *            the name of the resource to find.
652     * @return the {@code URL} object for the requested resource.
653     * @since Android 1.0
654     */
655    protected URL findResource(String resName) {
656        return null;
657    }
658
659    /**
660     * Finds an enumeration of URLs for the resource with the specified name.
661     * This implementation just returns an empty {@code Enumeration}; it should
662     * be overridden in subclasses.
663     *
664     * @param resName
665     *            the name of the resource to find.
666     * @return an enumeration of {@code URL} objects for the requested resource.
667     * @throws IOException
668     *             if an I/O error occurs.
669     * @since Android 1.0
670     */
671    @SuppressWarnings( {
672            "unchecked", "unused"
673    })
674    protected Enumeration<URL> findResources(String resName) throws IOException {
675        return EmptyEnumeration.getInstance();
676    }
677
678    /**
679     * Returns the absolute path of the native library with the specified name,
680     * or {@code null}. If this method returns {@code null} then the virtual
681     * machine searches the directories specified by the system property
682     * "java.library.path".
683     * <p>
684     * This implementation always returns {@code null}.
685     * </p>
686     *
687     * @param libName
688     *            the name of the library to find.
689     * @return the absolute path of the library.
690     * @since Android 1.0
691     */
692    protected String findLibrary(String libName) {
693        return null;
694    }
695
696    /**
697     * Returns the package with the specified name. Package information is
698     * searched in this class loader.
699     *
700     * @param name
701     *            the name of the package to find.
702     * @return the package with the requested name; {@code null} if the package
703     *         can not be found.
704     * @since Android 1.0
705     */
706    protected Package getPackage(String name) {
707        synchronized (packages) {
708            Package p = packages.get(name);
709            return p;
710        }
711    }
712
713    /**
714     * Gets the package with the specified name, searching it in the specified
715     * class loader.
716     *
717     * @param loader
718     *            the class loader to search the package in.
719     * @param name
720     *            the name of the package to find.
721     * @return the package with the requested name; {@code null} if the package
722     *         can not be found.
723     * @since Android 1.0
724     */
725    static Package getPackage(ClassLoader loader, String name) {
726        return loader.getPackage(name);
727    }
728
729    /**
730     * Returns all the packages known to this class loader.
731     *
732     * @return an array with all packages known to this class loader.
733     * @since Android 1.0
734     */
735    protected Package[] getPackages() {
736        synchronized (packages) {
737            Collection<Package> col = packages.values();
738            Package[] result = new Package[col.size()];
739            col.toArray(result);
740            return result;
741        }
742    }
743
744    /**
745     * Defines and returns a new {@code Package} using the specified
746     * information. If {@code sealBase} is {@code null}, the package is left
747     * unsealed. Otherwise, the package is sealed using this URL.
748     *
749     * @param name
750     *            the name of the package.
751     * @param specTitle
752     *            the title of the specification.
753     * @param specVersion
754     *            the version of the specification.
755     * @param specVendor
756     *            the vendor of the specification.
757     * @param implTitle
758     *            the implementation title.
759     * @param implVersion
760     *            the implementation version.
761     * @param implVendor
762     *            the specification vendor.
763     * @param sealBase
764     *            the URL used to seal this package or {@code null} to leave the
765     *            package unsealed.
766     * @return the {@code Package} object that has been created.
767     * @throws IllegalArgumentException
768     *             if a package with the specified name already exists.
769     * @since Android 1.0
770     */
771    protected Package definePackage(String name, String specTitle, String specVersion,
772            String specVendor, String implTitle, String implVersion, String implVendor, URL sealBase)
773            throws IllegalArgumentException {
774
775        synchronized (packages) {
776            if (packages.containsKey(name)) {
777                throw new IllegalArgumentException("Package " + name + " already defined");
778            }
779
780            Package newPackage = new Package(name, specTitle, specVersion, specVendor, implTitle,
781                    implVersion, implVendor, sealBase);
782
783            packages.put(name, newPackage);
784
785            return newPackage;
786        }
787    }
788
789    /**
790     * Gets the signers of the specified class. This implementation returns
791     * {@code null}.
792     *
793     * @param c
794     *            the {@code Class} object for which to get the signers.
795     * @return signers the signers of {@code c}.
796     * @since Android 1.0
797     */
798    final Object[] getSigners(Class<?> c) {
799        return null;
800    }
801
802    /**
803     * Sets the signers of the specified class. This implementation does
804     * nothing.
805     *
806     * @param c
807     *            the {@code Class} object for which to set the signers.
808     * @param signers
809     *            the signers for {@code c}.
810     * @since Android 1.0
811     */
812    protected final void setSigners(Class<?> c, Object[] signers) {
813        return;
814    }
815
816    /**
817     * <p>
818     * This must be provided by the VM vendor. It is used by
819     * SecurityManager.checkMemberAccess() with depth = 3. Note that
820     * checkMemberAccess() assumes the following stack when called:<br>
821     * </p>
822     *
823     * <pre>
824     *          &lt; user code &amp;gt; &lt;- want this class
825     *          Class.getDeclared*();
826     *          Class.checkMemberAccess();
827     *          SecurityManager.checkMemberAccess(); &lt;- current frame
828     * </pre>
829     *
830     * <p>
831     * Returns the ClassLoader of the method (including natives) at the
832     * specified depth on the stack of the calling thread. Frames representing
833     * the VM implementation of java.lang.reflect are not included in the list.
834     * </p>
835     * Notes:
836     * <ul>
837     * <li>This method operates on the defining classes of methods on stack.
838     * NOT the classes of receivers.</li>
839     * <li>The item at depth zero is the caller of this method</li>
840     * </ul>
841     *
842     * @param depth
843     *            the stack depth of the requested ClassLoader
844     * @return the ClassLoader at the specified depth
845     */
846    static final ClassLoader getStackClassLoader(int depth) {
847        Class<?>[] stack = VMStack.getClasses(depth + 1, false);
848        if(stack.length < depth + 1) {
849            return null;
850        }
851        return stack[depth].getClassLoader();
852    }
853
854    /**
855     * This method must be provided by the VM vendor, as it is called by
856     * java.lang.System.loadLibrary(). System.loadLibrary() cannot call
857     * Runtime.loadLibrary() because this method loads the library using the
858     * ClassLoader of the calling method. Loads and links the library specified
859     * by the argument.
860     *
861     * @param libName
862     *            the name of the library to load
863     * @param loader
864     *            the classloader in which to load the library
865     * @throws UnsatisfiedLinkError
866     *             if the library could not be loaded
867     * @throws SecurityException
868     *             if the library was not allowed to be loaded
869     * <p>
870     * <strong>Note: </strong>This method does nothing in the Android reference
871     * implementation.
872     * </p>
873     */
874    static void loadLibraryWithClassLoader(String libName, ClassLoader loader) {
875        return;
876    }
877
878    /**
879     * This method must be provided by the VM vendor, as it is called by
880     * java.lang.System.load(). System.load() cannot call Runtime.load() because
881     * the library is loaded using the ClassLoader of the calling method. Loads
882     * and links the library specified by the argument. No security check is
883     * done.
884     * <p>
885     * <strong>Note: </strong>This method does nothing in the Android reference
886     * implementation.
887     * </p>
888     *
889     * @param libName
890     *            the name of the library to load
891     * @param loader
892     *            the classloader in which to load the library
893     * @param libraryPath
894     *            the library path to search, or null
895     * @throws UnsatisfiedLinkError
896     *             if the library could not be loaded
897     */
898    static void loadLibraryWithPath(String libName, ClassLoader loader, String libraryPath) {
899        return;
900    }
901
902    /**
903     * Sets the assertion status of the class with the specified name.
904     * <p>
905     * <strong>Note: </strong>This method does nothing in the Android reference
906     * implementation.
907     * </p>
908     *
909     * @param cname
910     *            the name of the class for which to set the assertion status.
911     * @param enable
912     *            the new assertion status.
913     * @since Android 1.0
914     */
915    public void setClassAssertionStatus(String cname, boolean enable) {
916        return;
917    }
918
919    /**
920     * Sets the assertion status of the package with the specified name.
921     * <p>
922     * <strong>Note: </strong>This method does nothing in the Android reference
923     * implementation.
924     * </p>
925     *
926     * @param pname
927     *            the name of the package for which to set the assertion status.
928     * @param enable
929     *            the new assertion status.
930     * @since Android 1.0
931     */
932    public void setPackageAssertionStatus(String pname, boolean enable) {
933        return;
934    }
935
936    /**
937     * Sets the default assertion status for this class loader.
938     * <p>
939     * <strong>Note: </strong>This method does nothing in the Android reference
940     * implementation.
941     * </p>
942     *
943     * @param enable
944     *            the new assertion status.
945     * @since Android 1.0
946     */
947    public void setDefaultAssertionStatus(boolean enable) {
948        return;
949    }
950
951    /**
952     * Sets the default assertion status for this class loader to {@code false}
953     * and removes any package default and class assertion status settings.
954     * <p>
955     * <strong>Note:</strong> This method does nothing in the Android reference
956     * implementation.
957     * </p>
958     *
959     * @since Android 1.0
960     */
961    public void clearAssertionStatus() {
962        return;
963    }
964
965    /**
966     * Returns the assertion status of the named class Returns the assertion
967     * status of the class or nested class if it has been set. Otherwise returns
968     * the assertion status of its package or superpackage if that has been set.
969     * Otherwise returns the default assertion status. Returns 1 for enabled and
970     * 0 for disabled.
971     *
972     * @return the assertion status.
973     * @param cname
974     *            the name of class.
975     */
976    boolean getClassAssertionStatus(String cname) {
977        return false;
978    }
979
980    /**
981     * Returns the assertion status of the named package Returns the assertion
982     * status of the named package or superpackage if that has been set.
983     * Otherwise returns the default assertion status. Returns 1 for enabled and
984     * 0 for disabled.
985     *
986     * @return the assertion status.
987     * @param pname
988     *            the name of package.
989     */
990    boolean getPackageAssertionStatus(String pname) {
991        return false;
992    }
993
994    /**
995     * Returns the default assertion status
996     *
997     * @return the default assertion status.
998     */
999    boolean getDefaultAssertionStatus() {
1000        return false;
1001    }
1002}
1003
1004/*
1005 * Provides a helper class that combines two existing URL enumerations into one.
1006 * It is required for the getResources() methods. Items are fetched from the
1007 * first enumeration until it's empty, then from the second one.
1008 */
1009class TwoEnumerationsInOne implements Enumeration<URL> {
1010
1011    private Enumeration<URL> first;
1012
1013    private Enumeration<URL> second;
1014
1015    public TwoEnumerationsInOne(Enumeration<URL> first, Enumeration<URL> second) {
1016        this.first = first;
1017        this.second = second;
1018    }
1019
1020    public boolean hasMoreElements() {
1021        return first.hasMoreElements() || second.hasMoreElements();
1022    }
1023
1024    public URL nextElement() {
1025        if (first.hasMoreElements()) {
1026            return first.nextElement();
1027        } else {
1028            return second.nextElement();
1029        }
1030    }
1031
1032}
1033
1034/**
1035 * Provides an explicit representation of the boot class loader. It sits at the
1036 * head of the class loader chain and delegates requests to the VM's internal
1037 * class loading mechanism.
1038 */
1039class BootClassLoader extends ClassLoader {
1040
1041    static BootClassLoader instance;
1042
1043    public static BootClassLoader getInstance() {
1044        if (instance == null) {
1045            instance = new BootClassLoader();
1046        }
1047
1048        return instance;
1049    }
1050
1051    public BootClassLoader() {
1052        super(null, true);
1053    }
1054
1055    @Override
1056    protected Class<?> findClass(String name) throws ClassNotFoundException {
1057        return VMClassLoader.loadClass(name, false);
1058    }
1059
1060    @Override
1061    protected URL findResource(String name) {
1062        return VMClassLoader.getResource(name);
1063    }
1064
1065    @SuppressWarnings("unused")
1066    @Override
1067    protected Enumeration<URL> findResources(String resName) throws IOException {
1068        Enumeration<URL> result = VMClassLoader.getResources(resName);
1069
1070        // VMClassLoader doesn't keep the contract for getResources()
1071        if (result == null) {
1072            result = EmptyEnumeration.getInstance();
1073        }
1074
1075        return result;
1076    }
1077
1078    /**
1079     * Returns package information for the given package. Unfortunately, the
1080     * Android BootClassLoader doesn't really have this information, and as a
1081     * non-secure ClassLoader, it isn't even required to, according to the spec.
1082     * Yet, we want to provide it, in order to make all those hopeful callers of
1083     * {@code myClass.getPackage().getName()} happy. Thus we construct a Package
1084     * object the first time it is being requested and fill most of the fields
1085     * with dummy values. The Package object is then put into the ClassLoader's
1086     * Package cache, so we see the same one next time. We don't create Package
1087     * objects for null arguments or for the default package.
1088     * <p>
1089     * There a limited chance that we end up with multiple Package objects
1090     * representing the same package: It can happen when when a package is
1091     * scattered across different JAR files being loaded by different
1092     * ClassLoaders. Rather unlikely, and given that this whole thing is more or
1093     * less a workaround, probably not worth the effort.
1094     */
1095    @Override
1096    protected Package getPackage(String name) {
1097        if (name != null && !"".equals(name)) {
1098            synchronized (this) {
1099                Package pack = super.getPackage(name);
1100
1101                if (pack == null) {
1102                    pack = definePackage(name, "Unknown", "0.0", "Unknown", "Unknown", "0.0",
1103                            "Unknown", null);
1104                }
1105
1106                return pack;
1107            }
1108        }
1109
1110        return null;
1111    }
1112
1113    @Override
1114    public URL getResource(String resName) {
1115        return findResource(resName);
1116    }
1117
1118    @Override
1119    protected Class<?> loadClass(String className, boolean resolve)
1120           throws ClassNotFoundException {
1121        Class<?> clazz = findLoadedClass(className);
1122
1123        if (clazz == null) {
1124            clazz = findClass(className);
1125        }
1126
1127        return clazz;
1128    }
1129
1130    @Override
1131    public Enumeration<URL> getResources(String resName) throws IOException {
1132        return findResources(resName);
1133    }
1134}
1135
1136/**
1137 * TODO Open issues - Missing / empty methods - Signer stuff - Protection
1138 * domains - Assertions
1139 */
1140