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.

WeavingURLClassLoader.java 5.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. /* *******************************************************************
  2. * Copyright (c) 2004 IBM Corporation
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/epl-v10.html
  8. *
  9. * Contributors:
  10. * Matthew Webster, Adrian Colyer,
  11. * Martin Lippert initial implementation
  12. * ******************************************************************/
  13. package org.aspectj.weaver.loadtime;
  14. import java.io.File;
  15. import java.io.IOException;
  16. import java.net.MalformedURLException;
  17. import java.net.URL;
  18. import java.security.CodeSource;
  19. import java.util.ArrayList;
  20. import java.util.HashMap;
  21. import java.util.List;
  22. import java.util.Map;
  23. import java.util.StringTokenizer;
  24. import org.aspectj.weaver.ExtensibleURLClassLoader;
  25. import org.aspectj.weaver.tools.WeavingAdaptor;
  26. import org.aspectj.weaver.tools.WeavingClassLoader;
  27. public class WeavingURLClassLoader extends ExtensibleURLClassLoader implements WeavingClassLoader {
  28. public static final String WEAVING_CLASS_PATH = "aj.class.path";
  29. public static final String WEAVING_ASPECT_PATH = "aj.aspect.path";
  30. private URL[] aspectURLs;
  31. private WeavingAdaptor adaptor;
  32. private boolean initializingAdaptor;
  33. private Map generatedClasses = new HashMap(); /* String -> byte[] */
  34. /*
  35. * This constructor is needed when using "-Djava.system.class.loader".
  36. */
  37. public WeavingURLClassLoader (ClassLoader parent) {
  38. this(getURLs(getClassPath()),getURLs(getAspectPath()),parent);
  39. // System.out.println("? WeavingURLClassLoader.WeavingURLClassLoader()");
  40. }
  41. public WeavingURLClassLoader (URL[] urls, ClassLoader parent) {
  42. super(urls,parent);
  43. // System.out.println("WeavingURLClassLoader.WeavingURLClassLoader()");
  44. }
  45. public WeavingURLClassLoader (URL[] classURLs, URL[] aspectURLs, ClassLoader parent) {
  46. super(classURLs,parent);
  47. // System.out.println("> WeavingURLClassLoader.WeavingURLClassLoader() classURLs=" + Arrays.asList(classURLs));
  48. this.aspectURLs = aspectURLs;
  49. /* If either we nor our parent is using an ASPECT_PATH use a new-style
  50. * adaptor
  51. */
  52. if (this.aspectURLs.length > 0 || getParent() instanceof WeavingClassLoader) {
  53. try {
  54. adaptor = new WeavingAdaptor(this);
  55. }
  56. catch (ExceptionInInitializerError ex) {
  57. ex.printStackTrace(System.out);
  58. throw ex;
  59. }
  60. }
  61. // System.out.println("< WeavingURLClassLoader.WeavingURLClassLoader() adaptor=" + adaptor);
  62. }
  63. private static String getAspectPath () {
  64. return System.getProperty(WEAVING_ASPECT_PATH,"");
  65. }
  66. private static String getClassPath () {
  67. return System.getProperty(WEAVING_CLASS_PATH,"");
  68. }
  69. private static URL[] getURLs (String path) {
  70. List urlList = new ArrayList();
  71. for (StringTokenizer t = new StringTokenizer(path,File.pathSeparator);
  72. t.hasMoreTokens();) {
  73. File f = new File(t.nextToken().trim());
  74. try {
  75. if (f.exists()) {
  76. URL url = f.toURL();
  77. if (url != null) urlList.add(url);
  78. }
  79. } catch (MalformedURLException e) {}
  80. }
  81. URL[] urls = new URL[urlList.size()];
  82. urlList.toArray(urls);
  83. return urls;
  84. }
  85. protected void addURL(URL url) {
  86. adaptor.addURL(url);
  87. super.addURL(url);
  88. }
  89. /**
  90. * Override to weave class using WeavingAdaptor
  91. */
  92. protected Class defineClass(String name, byte[] b, CodeSource cs) throws IOException {
  93. // System.err.println("? WeavingURLClassLoader.defineClass(" + name + ", [" + b.length + "])");
  94. /* Avoid recursion during adaptor initialization */
  95. if (!initializingAdaptor) {
  96. /* Need to defer creation because of possible recursion during constructor execution */
  97. if (adaptor == null && !initializingAdaptor) {
  98. createAdaptor();
  99. }
  100. b = adaptor.weaveClass(name,b);
  101. }
  102. return super.defineClass(name, b, cs);
  103. }
  104. private void createAdaptor () {
  105. DefaultWeavingContext weavingContext = new DefaultWeavingContext (this) {
  106. /* Ensures consistent LTW messages for testing */
  107. public String getClassLoaderName() {
  108. return loader.getClass().getName();
  109. }
  110. };
  111. ClassLoaderWeavingAdaptor clwAdaptor = new ClassLoaderWeavingAdaptor();
  112. initializingAdaptor = true;
  113. clwAdaptor.initialize(this,weavingContext);
  114. initializingAdaptor = false;
  115. adaptor = clwAdaptor;
  116. }
  117. /**
  118. * Override to find classes generated by WeavingAdaptor
  119. */
  120. protected byte[] getBytes (String name) throws IOException {
  121. byte[] bytes = super.getBytes(name);
  122. if (bytes == null) {
  123. // return adaptor.findClass(name);
  124. return (byte[])generatedClasses.remove(name);
  125. }
  126. return bytes;
  127. }
  128. /**
  129. * Implement method from WeavingClassLoader
  130. */
  131. public URL[] getAspectURLs() {
  132. return aspectURLs;
  133. }
  134. public void acceptClass (String name, byte[] bytes) {
  135. generatedClasses.put(name,bytes);
  136. }
  137. // protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
  138. // System.err.println("> WeavingURLClassLoader.loadClass() name=" + name);
  139. // Class clazz= super.loadClass(name, resolve);
  140. // System.err.println("< WeavingURLClassLoader.loadClass() clazz=" + clazz + ", loader=" + clazz.getClassLoader());
  141. // return clazz;
  142. // }
  143. // private interface ClassPreProcessorAdaptor extends ClassPreProcessor {
  144. // public void addURL(URL url);
  145. // }
  146. //
  147. // private class WeavingAdaptorPreProcessor implements ClassPreProcessorAdaptor {
  148. //
  149. // private WeavingAdaptor adaptor;
  150. //
  151. // public WeavingAdaptorPreProcessor (WeavingClassLoader wcl) {
  152. // adaptor = new WeavingAdaptor(wcl);
  153. // }
  154. //
  155. // public void initialize() {
  156. // }
  157. //
  158. // public byte[] preProcess(String className, byte[] bytes, ClassLoader classLoader) {
  159. // return adaptor.weaveClass(className,bytes);
  160. // }
  161. //
  162. // public void addURL(URL url) {
  163. //
  164. // }
  165. // }
  166. }