VMClassLoader.java 11 KB

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