001 package com.croftsoft.core.lang.classloader; 002 003 /********************************************************************* 004 * <P> 005 * Assumes that Java 1.1 is being used and classes are cached as the 006 * default behavior as part of the defineClass() method. 007 * <P> 008 * This should be upgraded when the switch is made from Java 1.1 to 009 * Java 1.2. 010 * <P> 011 * <B> 012 * References 013 * </B> 014 * Scott Oaks, <U>Java Security</U>, O'Reilly, 1998. 015 * <P> 016 * @version 017 * 1998-05-25 018 * @author 019 * <a href="https://www.croftsoft.com/">David Wallace Croft</a> 020 *********************************************************************/ 021 022 public abstract class CustomClassLoader extends ClassLoader 023 ////////////////////////////////////////////////////////////////////// 024 ////////////////////////////////////////////////////////////////////// 025 { 026 027 /********************************************************************* 028 * Parses the package name out of a full class name. 029 * Returns the empty string ("") if the class is not in a package. 030 *********************************************************************/ 031 public static String parsePackageName ( String className ) 032 ////////////////////////////////////////////////////////////////////// 033 { 034 String packageName = ""; 035 int i = className.lastIndexOf ( '.' ); 036 if ( i > -1 ) packageName = className.substring ( 0, i ); 037 return packageName; 038 } 039 040 /********************************************************************* 041 * Returns the Class of the given name. 042 * <P> 043 * Calls loadClassData() if the class was not previously loaded and 044 * is not a system class. 045 *********************************************************************/ 046 public Class loadClass ( String name, boolean resolve ) 047 ////////////////////////////////////////////////////////////////////// 048 // See Ch. 3, "Java Class Loaders", "Implementing a Class Loader", 049 // pp44-45. 050 ////////////////////////////////////////////////////////////////////// 051 { 052 // Step 1 -- Check for a previously loaded class 053 Class c = findLoadedClass ( name ); 054 if ( c != null ) return c; 055 056 // Step 2 -- Check to make sure that we can access this class 057 String packageName = null; 058 SecurityManager securityManager = System.getSecurityManager ( ); 059 if ( securityManager != null ) 060 { 061 packageName = parsePackageName ( name ); 062 // What if in "default" package? 063 securityManager.checkPackageAccess ( packageName ); 064 } 065 066 // Step 3 -- Check for system class first 067 try 068 { 069 c = findSystemClass ( name ); 070 if ( c != null ) return c; 071 } 072 catch ( ClassNotFoundException ex ) { } 073 074 // Step 4 -- Check to make sure that we can define this class 075 if ( securityManager != null ) 076 { 077 securityManager.checkPackageDefinition ( packageName ); 078 } 079 080 // Step 5 -- Read in the class file 081 byte [ ] data = loadClassData ( name ); 082 if ( data == null ) return null; 083 084 // Step 6 and 7 -- Define the class from the data; 085 // this also passes the data through the bytecode verifier 086 c = defineClass ( name, data, 0, data.length ); 087 088 // Step 8 -- Resolve the internal references of the class 089 if ( resolve ) resolveClass ( c ); 090 091 return c; 092 } 093 094 /********************************************************************* 095 * Implement to load the raw bytecode from an external source. 096 * @return 097 * May return null on failure. 098 *********************************************************************/ 099 // Better to thrown an exception than to return null. 100 protected abstract byte [ ] loadClassData ( String name ); 101 102 /********************************************************************* 103 * Calls getSystemResource(name). 104 *********************************************************************/ 105 /* 106 public URL getResource ( String name ) 107 ////////////////////////////////////////////////////////////////////// 108 { 109 return getSystemResource ( name ); 110 } 111 */ 112 113 /********************************************************************* 114 * Calls getSystemResourceAsStream(name). 115 *********************************************************************/ 116 /* 117 public InputStream getResourceAsStream ( String name ) 118 ////////////////////////////////////////////////////////////////////// 119 { 120 return getSystemResourceAsStream ( name ); 121 } 122 */ 123 124 ////////////////////////////////////////////////////////////////////// 125 ////////////////////////////////////////////////////////////////////// 126 }