You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

URLClassLoader.java 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. package java.net;
  2. import java.io.ByteArrayInputStream;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.IOException;
  6. import java.io.InputStream;
  7. import java.security.SecureClassLoader;
  8. import java.util.Enumeration;
  9. import java.util.Iterator;
  10. import java.util.LinkedList;
  11. import java.util.List;
  12. import java.util.Vector;
  13. import java.util.jar.JarFile;
  14. import java.util.zip.ZipEntry;
  15. import org.aspectj.weaver.loadtime.Aj;
  16. public class URLClassLoader extends SecureClassLoader {
  17. public final static boolean debug = false;
  18. private List path = new LinkedList();
  19. private Aj agent;
  20. public URLClassLoader() {
  21. super();
  22. }
  23. public URLClassLoader(ClassLoader parent) {
  24. super(parent);
  25. }
  26. public URLClassLoader(URL[] urls) throws IOException {
  27. this(urls,null,null);
  28. }
  29. public URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) throws IOException {
  30. super(parent);
  31. if (debug) System.err.println("> URLClassLoader.URLClassLoader() parent=" + parent);
  32. for (int i = 0; i < urls.length; i++) {
  33. Object pathElement;
  34. URL url = urls[i];
  35. if (debug) System.err.println("- URLClassLoader.URLClassLoader() url=" + url.getPath());
  36. File file = new File(encode(url.getFile()));
  37. if (debug) System.err.println("- URLClassLoader.URLClassLoader() file" + file);
  38. if (file.isDirectory()) pathElement = file;
  39. else if (file.exists() && file.getName().endsWith(".jar")) pathElement = new JarFile(file);
  40. else throw new RuntimeException(file.getAbsolutePath().toString());
  41. path.add(pathElement);
  42. }
  43. agent = new Aj();
  44. if (debug) System.err.println("< URLClassLoader.URLClassLoader() path=" + path);
  45. }
  46. /* Get rid of escaped characters */
  47. private String encode (String s) {
  48. StringBuffer result = new StringBuffer();
  49. int i = s.indexOf("%");
  50. while (i != -1) {
  51. result.append(s.substring(0,i));
  52. String escaped = s.substring(i+1,i+3);
  53. s = s.substring(i+3);
  54. Integer value = Integer.valueOf(escaped,16);
  55. result.append(new Character((char)value.intValue()));
  56. i = s.indexOf("%");
  57. }
  58. result.append(s);
  59. return result.toString();
  60. }
  61. protected Class findClass(String name) throws ClassNotFoundException {
  62. if (debug) System.err.println("> URLClassLoader.findClass() name=" + name);
  63. Class clazz = null;
  64. try {
  65. clazz = super.findClass(name);
  66. }
  67. catch (ClassNotFoundException ex) {
  68. for (Iterator i = path.iterator(); clazz == null && i.hasNext();) {
  69. byte[] classBytes = null;
  70. try {
  71. Object pathElement = i.next();
  72. if (pathElement instanceof File) {
  73. File dir = (File)pathElement;
  74. String className = name.replace('.','/') + ".class";
  75. File classFile = new File(dir,className);
  76. if (debug) System.err.println("- URLClassLoader.findClass() classFile=" + classFile);
  77. if (classFile.exists()) classBytes = loadClassFromFile(name,classFile);
  78. }
  79. else {
  80. JarFile jar = (JarFile)pathElement;
  81. String className = name.replace('.','/') + ".class";
  82. ZipEntry entry = jar.getEntry(className);
  83. if (entry != null) classBytes = loadBytesFromZipEntry(jar,entry);
  84. }
  85. if (classBytes != null) {
  86. clazz = defineClass(name,classBytes);
  87. }
  88. }
  89. catch (IOException ioException) {
  90. ex.printStackTrace();
  91. }
  92. }
  93. }
  94. if (debug) System.err.println("< URLClassLoader.findClass() clazz=" + clazz);
  95. if (clazz == null) throw new ClassNotFoundException(name);
  96. return clazz;
  97. }
  98. protected URL findResource (String name) {
  99. if (debug) System.err.println("> URLClassLoader.findResource() name=" + name);
  100. URL url = null;
  101. try {
  102. Enumeration enu = findResources(name);
  103. if (enu.hasMoreElements()) url = (URL)enu.nextElement();
  104. }
  105. catch (IOException ex) {
  106. ex.printStackTrace();
  107. }
  108. if (debug) System.err.println("< URLClassLoader.findResource() url=" + url);
  109. return url;
  110. }
  111. protected Enumeration findResources (String name) throws IOException {
  112. if (debug) System.err.println("> URLClassLoader.findResources() name=" + name);
  113. Vector urls = new Vector();
  114. for (Iterator i = path.iterator(); i.hasNext();) {
  115. Object pathElement = i.next();
  116. if (pathElement instanceof File) {
  117. File dir = (File)pathElement;
  118. File resourceFile = new File(dir,name);
  119. // if (debug) System.err.println("- URLClassLoader.findResources() file=" + resourceFile);
  120. }
  121. else {
  122. JarFile jar = (JarFile)pathElement;
  123. ZipEntry entry = jar.getEntry(name);
  124. // if (debug) System.err.println("- URLClassLoader.findResources() entry=" + entry);
  125. if (entry != null) {
  126. if (debug) System.err.println("- URLClassLoader.findResources() jar=" + jar.getName());
  127. final byte[] bytes = loadBytesFromZipEntry(jar,entry);
  128. URLStreamHandler streamHandler = new URLStreamHandler() {
  129. protected URLConnection openConnection(URL u) throws IOException {
  130. URLConnection connection = new URLConnection(u) {
  131. public void connect() throws IOException {
  132. }
  133. public InputStream getInputStream() throws IOException {
  134. return new ByteArrayInputStream(bytes);
  135. }
  136. };
  137. return connection;
  138. }
  139. };
  140. URL url = new URL("file",null,0,jar.getName(),streamHandler);
  141. urls.add(url);
  142. }
  143. }
  144. }
  145. Enumeration enu = urls.elements();
  146. if (debug) System.err.println("< URLClassLoader.findResources() enu=" + enu);
  147. return enu;
  148. }
  149. private Class defineClass (String name, byte[] bytes) {
  150. if (debug) System.err.println("> URLClassLoader.defineClass() name=" + name);
  151. // try {
  152. if (agent != null) bytes = agent.preProcess(name,bytes,this);
  153. // }
  154. // catch (IllegalAccessException iae) {
  155. // iae.printStackTrace();
  156. // throw new ClassFormatError(iae.getMessage());
  157. // }
  158. // catch (InvocationTargetException ite) {
  159. // ite.printStackTrace();
  160. // throw new ClassFormatError(ite.getTargetException().getMessage());
  161. // }
  162. if (debug) System.err.println("< URLClassLoader.defineClass() name=" + name);
  163. return super.defineClass(name,bytes,0,bytes.length);
  164. }
  165. private byte[] loadClassFromFile (String name, File file) throws IOException {
  166. if (debug) System.err.println("> URLClassLoader.loadClassFromFile() file=" + file);
  167. byte[] bytes;
  168. bytes = new byte[(int)file.length()];
  169. FileInputStream fis = null;
  170. try {
  171. fis = new FileInputStream(file);
  172. bytes = readBytes(fis,bytes);
  173. }
  174. finally {
  175. if (fis != null) fis.close();
  176. }
  177. if (debug) System.err.println("< URLClassLoader.loadClassFromFile() bytes=b[" + bytes.length + "]");
  178. return bytes;
  179. }
  180. private byte[] loadBytesFromZipEntry (JarFile jar, ZipEntry entry) throws IOException {
  181. if (debug) System.err.println("> URLClassLoader.loadBytesFromZipEntry() entry=" + entry);
  182. byte[] bytes;
  183. bytes = new byte[(int)entry.getSize()];
  184. InputStream is = null;
  185. try {
  186. is = jar.getInputStream(entry);
  187. bytes = readBytes(is,bytes);
  188. }
  189. finally {
  190. if (is != null) is.close();
  191. }
  192. if (debug) System.err.println("< URLClassLoader.loadBytesFromZipEntry() bytes=b[" + bytes.length + "]");
  193. return bytes;
  194. }
  195. private byte[] readBytes (InputStream is, byte[] bytes) throws IOException {
  196. for (int offset = 0; offset < bytes.length;) {
  197. int read = is.read(bytes,offset,bytes.length - offset);
  198. offset += read;
  199. }
  200. return bytes;
  201. }
  202. }