OSDN Git Service

* Makefile.in: Rebuilt.
[pf3gnuchains/gcc-fork.git] / libjava / java / lang / VMClassLoader.java
1 /* VMClassLoader.java -- Reference implementation of native interface
2    required by ClassLoader
3    Copyright (C) 1998, 2001, 2002, 2003, 2004, 2005 Free Software Foundation
4
5 This file is part of GNU Classpath.
6
7 GNU Classpath is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU Classpath is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU Classpath; see the file COPYING.  If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
20 02111-1307 USA.
21
22 Linking this library statically or dynamically with other modules is
23 making a combined work based on this library.  Thus, the terms and
24 conditions of the GNU General Public License cover the whole
25 combination.
26
27 As a special exception, the copyright holders of this library give you
28 permission to link this library with independent modules to produce an
29 executable, regardless of the license terms of these independent
30 modules, and to copy and distribute the resulting executable under
31 terms of your choice, provided that you also meet, for each linked
32 independent module, the terms and conditions of the license of that
33 module.  An independent module is a module which is not derived from
34 or based on this library.  If you modify this library, you may extend
35 this exception to your version of the library, but you are not
36 obligated to do so.  If you do not wish to do so, delete this
37 exception statement from your version. */
38
39 package java.lang;
40
41 import gnu.java.util.EmptyEnumeration;
42 import java.lang.reflect.Constructor;
43 import java.io.File;
44 import java.io.IOException;
45 import java.net.URL;
46 import java.net.URLClassLoader;
47 import java.security.AllPermission;
48 import java.security.Permission;
49 import java.security.Permissions;
50 import java.security.ProtectionDomain;
51 import java.util.ArrayList;
52 import java.util.Enumeration;
53 import java.util.HashMap;
54 import java.util.Map;
55 import java.util.StringTokenizer;
56 import gnu.gcj.runtime.BootClassLoader;
57
58 /**
59  * java.lang.VMClassLoader is a package-private helper for VMs to implement
60  * on behalf of java.lang.ClassLoader.
61  *
62  * @author John Keiser
63  * @author Mark Wielaard <mark@klomp.org>
64  * @author Eric Blake <ebb9@email.byu.edu>
65  */
66 final class VMClassLoader
67 {
68   // Protection Domain definitions 
69   // FIXME: should there be a special protection domain used for native code?
70   
71   // The permission required to check what a classes protection domain is.
72   static final Permission protectionDomainPermission
73     = new RuntimePermission("getProtectionDomain");
74   // The protection domain returned if we cannot determine it. 
75   static ProtectionDomain unknownProtectionDomain;
76
77   static
78   {
79     Permissions permissions = new Permissions();
80     permissions.add(new AllPermission());
81     unknownProtectionDomain = new ProtectionDomain(null, permissions);  
82   }
83
84   static final HashMap definedPackages = new HashMap();
85
86   // This is a helper for handling java.endorsed.dirs.  It is null
87   // until we've initialized the system, at which point it is created.
88   static BootClassLoader bootLoader;
89
90   /**
91    * Helper to define a class using a string of bytes. This assumes that
92    * the security checks have already been performed, if necessary.
93    *
94    * <strong>For backward compatibility, this just ignores the protection
95    * domain; that is the wrong behavior, and you should directly implement
96    * this method natively if you can.</strong>
97    *
98    * @param name the name to give the class, or null if unknown
99    * @param data the data representing the classfile, in classfile format
100    * @param offset the offset into the data where the classfile starts
101    * @param len the length of the classfile data in the array
102    * @param pd the protection domain
103    * @return the class that was defined
104    * @throws ClassFormatError if data is not in proper classfile format
105    */
106   static final native Class defineClass(ClassLoader cl, String name,
107                                         byte[] data, int offset, int len,
108                                         ProtectionDomain pd)
109     throws ClassFormatError;
110
111   /**
112    * Helper to resolve all references to other classes from this class.
113    *
114    * @param c the class to resolve
115    */
116   static final native void resolveClass(Class clazz);
117
118   static final void transformException(Class clazz, Throwable x)
119   {
120     LinkageError e;
121     if (x instanceof LinkageError)
122       e = (LinkageError) x;
123     else if (x instanceof ClassNotFoundException)
124       {
125         e = new NoClassDefFoundError("while resolving class: "
126                                      + clazz.getName());
127         e.initCause (x);
128       }
129     else
130       {
131         e = new LinkageError ("unexpected exception during linking: "
132                               + clazz.getName());
133         e.initCause (x);
134       }
135     throw e;
136   }
137
138   /**
139    * Helper to load a class from the bootstrap class loader.
140    *
141    * @param name the class name to load
142    * @param resolve whether to resolve it
143    * @return the class, loaded by the bootstrap classloader or null
144    * if the class wasn't found. Returning null is equivalent to throwing
145    * a ClassNotFoundException (but a possible performance optimization).
146    */
147   static final native Class loadClass(String name, boolean resolve)
148     throws ClassNotFoundException;
149
150   /**
151    * Helper to load a resource from the bootstrap class loader.
152    *
153    * In libgcj, this does nothing, as the default system loader knows
154    * how to find resources that have been linked in.
155    *
156    * @param name the resource to find
157    * @return the URL to the resource
158    */
159   static URL getResource(String name)
160   {
161     if (bootLoader != null)
162       return bootLoader.bootGetResource(name);
163     return null;
164   }
165
166   /**
167    * Helper to get a list of resources from the bootstrap class loader.
168    *
169    * In libgcj, this does nothing, as the default system loader knows
170    * how to find resources that have been linked in.
171    *
172    * @param name the resource to find
173    * @return an enumeration of resources
174    * @throws IOException if one occurs
175    */
176   static Enumeration getResources(String name) throws IOException
177   {
178     if (bootLoader != null)
179       return bootLoader.bootGetResources(name);
180     return EmptyEnumeration.getInstance();
181   }
182
183   /**
184    * Helper to get a package from the bootstrap class loader.  The default
185    * implementation of returning null may be adequate, or you may decide
186    * that this needs some native help.
187    *
188    * @param name the name to find
189    * @return the named package, if it exists
190    */
191   static synchronized Package getPackage(String name)
192   {
193     return (Package) definedPackages.get(name);
194   }
195
196   /**
197    * Helper to get all packages from the bootstrap class loader.  The default
198    * implementation of returning an empty array may be adequate, or you may
199    * decide that this needs some native help.
200    *
201    * @return all named packages, if any exist
202    */
203   static synchronized Package[] getPackages()
204   {
205     Package[] packages = new Package[definedPackages.size()];
206     return (Package[]) definedPackages.values().toArray(packages);
207   }
208
209   // Define a package for something loaded natively.
210   static synchronized void definePackageForNative(String className)
211   {
212     int lastDot = className.lastIndexOf('.');
213     if (lastDot != -1)
214       {
215         String packageName = className.substring(0, lastDot);
216         if (getPackage(packageName) == null)
217           {
218             // FIXME: this assumes we're defining the core, which
219             // isn't necessarily so.  We could detect this and set up
220             // appropriately.  We could also look at a manifest file
221             // compiled into the .so.
222             Package p = new Package(packageName,
223                                     "Java Platform API Specification",
224                                     "GNU", "1.4", "gcj", "GNU",
225                                     null, // FIXME: gcj version.
226                                     null);
227             definedPackages.put(packageName, p);
228           }
229       }
230   }
231
232   /**
233    * Helper for java.lang.Integer, Byte, etc to get the TYPE class
234    * at initialization time. The type code is one of the chars that
235    * represents the primitive type as in JNI.
236    *
237    * <ul>
238    * <li>'Z' - boolean</li>
239    * <li>'B' - byte</li>
240    * <li>'C' - char</li>
241    * <li>'D' - double</li>
242    * <li>'F' - float</li>
243    * <li>'I' - int</li>
244    * <li>'J' - long</li>
245    * <li>'S' - short</li>
246    * <li>'V' - void</li>
247    * </ul>
248    *
249    * @param type the primitive type
250    * @return a "bogus" class representing the primitive type
251    */
252   static final native Class getPrimitiveClass(char type);
253
254   /**
255    * The system default for assertion status. This is used for all system
256    * classes (those with a null ClassLoader), as well as the initial value for
257    * every ClassLoader's default assertion status.
258    *
259    * XXX - Not implemented yet; this requires native help.
260    *
261    * @return the system-wide default assertion status
262    */
263   static final boolean defaultAssertionStatus()
264   {
265     return true;
266   }
267
268   /**
269    * The system default for package assertion status. This is used for all
270    * ClassLoader's packageAssertionStatus defaults. It must be a map of
271    * package names to Boolean.TRUE or Boolean.FALSE, with the unnamed package
272    * represented as a null key.
273    *
274    * XXX - Not implemented yet; this requires native help.
275    *
276    * @return a (read-only) map for the default packageAssertionStatus
277    */
278   static final Map packageAssertionStatus()
279   {
280     return new HashMap();
281   }
282
283   /**
284    * The system default for class assertion status. This is used for all
285    * ClassLoader's classAssertionStatus defaults. It must be a map of
286    * class names to Boolean.TRUE or Boolean.FALSE
287    *
288    * XXX - Not implemented yet; this requires native help.
289    *
290    * @return a (read-only) map for the default classAssertionStatus
291    */
292   static final Map classAssertionStatus()
293   {
294     return new HashMap();
295   }
296
297   static native ClassLoader getSystemClassLoaderInternal();
298
299   static native void initBootLoader(String libdir);
300
301   static ClassLoader getSystemClassLoader()
302   {
303     // This method is called as the initialization of systemClassLoader,
304     // so if there is a null value, this is the first call and we must check
305     // for java.system.class.loader.
306     String loader = System.getProperty("java.system.class.loader");
307     ClassLoader default_sys = getSystemClassLoaderInternal();
308     if (loader != null)
309       {
310         try
311           {
312             Class load_class = Class.forName(loader, true, default_sys);
313             Constructor c
314               = load_class.getConstructor(new Class[] { ClassLoader.class });
315             default_sys
316               = (ClassLoader) c.newInstance(new Object[] { default_sys });
317           }
318         catch (Exception ex)
319           {
320             throw new Error("Failed to load requested system classloader "
321                                + loader, ex);
322           }
323       }
324
325     return default_sys;
326   }
327 }