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.

Aj.java 4.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /*******************************************************************************
  2. * Copyright (c) 2005 Contributors.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Common Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/cpl-v10.html
  7. *
  8. * Contributors:
  9. * Alexandre Vasseur initial implementation
  10. *******************************************************************************/
  11. package org.aspectj.weaver.loadtime;
  12. import org.aspectj.asm.IRelationship;
  13. import org.aspectj.bridge.IMessage;
  14. import org.aspectj.bridge.ISourceLocation;
  15. import org.aspectj.bridge.Message;
  16. import org.aspectj.weaver.ICrossReferenceHandler;
  17. import org.aspectj.weaver.World;
  18. import org.aspectj.weaver.patterns.PatternParser;
  19. import org.aspectj.weaver.patterns.TypePattern;
  20. import org.aspectj.weaver.bcel.BcelWeaver;
  21. import org.aspectj.weaver.bcel.BcelWorld;
  22. import org.aspectj.weaver.loadtime.definition.Definition;
  23. import org.aspectj.weaver.loadtime.definition.DocumentParser;
  24. import org.aspectj.weaver.tools.GeneratedClassHandler;
  25. import org.aspectj.weaver.tools.WeavingAdaptor;
  26. import java.io.File;
  27. import java.io.FileOutputStream;
  28. import java.lang.reflect.Method;
  29. import java.net.URL;
  30. import java.util.ArrayList;
  31. import java.util.Enumeration;
  32. import java.util.Iterator;
  33. import java.util.List;
  34. import java.util.Map;
  35. import java.util.WeakHashMap;
  36. /**
  37. * Adapter between the generic class pre processor interface and the AspectJ weaver
  38. * Load time weaving consistency relies on Bcel.setRepository
  39. *
  40. * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
  41. */
  42. public class Aj implements ClassPreProcessor {
  43. /**
  44. * Initialization
  45. */
  46. public void initialize() {
  47. ;
  48. }
  49. /**
  50. * Weave
  51. *
  52. * @param className
  53. * @param bytes
  54. * @param loader
  55. * @return
  56. */
  57. public byte[] preProcess(String className, byte[] bytes, ClassLoader loader) {
  58. //System.out.println("Aj.preProcess " + className + " @ " + loader + " " + Thread.currentThread());
  59. //TODO av needs to spec and doc that
  60. //TODO av should skip org.aspectj as well unless done somewhere else
  61. if (loader == null
  62. || className == null) {
  63. // skip boot loader or null classes (hibernate)
  64. return bytes;
  65. }
  66. try {
  67. byte[] weaved = WeaverContainer.getWeaver(loader).weaveClass(className, bytes);
  68. //TODO av make dump optionnal and configurable
  69. __dump(className, weaved);
  70. return weaved;
  71. } catch (Throwable t) {
  72. t.printStackTrace();
  73. return bytes;
  74. }
  75. }
  76. /**
  77. * Cache of weaver
  78. * There is one weaver per classloader
  79. */
  80. static class WeaverContainer {
  81. private static Map weavingAdaptors = new WeakHashMap();
  82. static WeavingAdaptor getWeaver(ClassLoader loader) {
  83. synchronized (weavingAdaptors) {
  84. WeavingAdaptor weavingAdaptor = (WeavingAdaptor) weavingAdaptors.get(loader);
  85. if (weavingAdaptor == null) {
  86. weavingAdaptor = new ClassLoaderWeavingAdaptor(loader);
  87. weavingAdaptors.put(loader, weavingAdaptor);
  88. }
  89. return weavingAdaptor;
  90. }
  91. }
  92. }
  93. static void defineClass(ClassLoader loader, String name, byte[] bytes) {
  94. try {
  95. //TODO av protection domain, and optimize
  96. Method defineClass = ClassLoader.class.getDeclaredMethod(
  97. "defineClass", new Class[]{
  98. String.class, bytes.getClass(), int.class, int.class
  99. }
  100. );
  101. defineClass.setAccessible(true);
  102. defineClass.invoke(
  103. loader, new Object[]{
  104. name,
  105. bytes,
  106. new Integer(0),
  107. new Integer(bytes.length)
  108. }
  109. );
  110. } catch (Throwable t) {
  111. t.printStackTrace();
  112. }
  113. }
  114. /**
  115. * Dump the given bytcode in _dump/...
  116. *
  117. * @param name
  118. * @param b
  119. * @throws Throwable
  120. */
  121. static void __dump(String name, byte[] b) throws Throwable {
  122. String className = name.replace('.', '/');
  123. final File dir;
  124. if (className.indexOf('/') > 0) {
  125. dir = new File("_dump" + File.separator + className.substring(0, className.lastIndexOf('/')));
  126. } else {
  127. dir = new File("_dump");
  128. }
  129. dir.mkdirs();
  130. String fileName = "_dump" + File.separator + className + ".class";
  131. FileOutputStream os = new FileOutputStream(fileName);
  132. os.write(b);
  133. os.close();
  134. }
  135. }