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.

JRockitAgentTest.java 7.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  1. /*******************************************************************************
  2. * Copyright (c) 2006 IBM Corporation and others.
  3. * All rights reserved. This program and the accompanying materials
  4. * are made available under the terms of the Eclipse Public License v1.0
  5. * which accompanies this distribution, and is available at
  6. * http://www.eclipse.org/legal/epl-v10.html
  7. *
  8. * Contributors:
  9. * Matthew Webster - initial implementation
  10. *******************************************************************************/
  11. package org.aspectj.weaver.loadtime;
  12. import java.io.File;
  13. import java.io.FileInputStream;
  14. import java.io.IOException;
  15. import java.io.InputStream;
  16. import java.lang.reflect.InvocationTargetException;
  17. import java.lang.reflect.Method;
  18. import java.net.URL;
  19. import java.net.URLClassLoader;
  20. import java.util.Iterator;
  21. import java.util.LinkedList;
  22. import java.util.List;
  23. import java.util.jar.JarFile;
  24. import java.util.zip.ZipEntry;
  25. import org.aspectj.util.FileUtil;
  26. import org.aspectj.util.LangUtil;
  27. import com.bea.jvm.ClassPreProcessor;
  28. import com.bea.jvm.JVMFactory;
  29. import junit.framework.TestCase;
  30. public class JRockitAgentTest extends TestCase {
  31. protected void setUp() throws Exception {
  32. super.setUp();
  33. }
  34. protected void tearDown() throws Exception {
  35. super.tearDown();
  36. }
  37. public void testJRockitAgent() {
  38. ClassPreProcessor preProcessor = new JRockitAgent();
  39. ClassPreProcessor expectedPreProcessor = JVMFactory.getJVM().getClassLibrary().getClassPreProcessor();
  40. assertEquals("JRocketAgent must be registered", expectedPreProcessor, preProcessor);
  41. }
  42. public void testPreProcess() {
  43. ClassPreProcessor preProcessor = new JRockitAgent();
  44. preProcessor.preProcess(null, "foo.Bar", new byte[] {});
  45. }
  46. public void testJrockitRecursionProtection() {
  47. if (LangUtil.is11VMOrGreater()) {
  48. // Skip test, not castable to URLClassLoader
  49. return;
  50. }
  51. URLClassLoader thisLoader = (URLClassLoader) getClass().getClassLoader();
  52. URL jrockit = FileUtil.getFileURL(new File("../lib/ext/jrockit/jrockit.jar"));
  53. URL[] urls = new URL[] {jrockit};
  54. thisLoader = new URLClassLoader(urls, thisLoader);
  55. ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
  56. try {
  57. /* Needed by Commons Logging */
  58. Thread.currentThread().setContextClassLoader(thisLoader.getParent());
  59. ClassLoader loader = new JRockitClassLoader(thisLoader);
  60. Class.forName("java.lang.Object", false, loader);
  61. Class.forName("junit.framework.TestCase", false, loader);
  62. } catch (Exception ex) {
  63. ex.printStackTrace();
  64. fail(ex.toString());
  65. } finally {
  66. Thread.currentThread().setContextClassLoader(contextLoader);
  67. }
  68. }
  69. private class JRockitClassLoader extends ClassLoader {
  70. public final static boolean debug = false;
  71. private List path = new LinkedList();
  72. // private com.bea.jvm.ClassPreProcessor agent;
  73. private Object agent;
  74. private Method preProcess;
  75. public JRockitClassLoader(URLClassLoader clone) throws Exception {
  76. /* Use extensions loader */
  77. super(clone.getParent());
  78. URL[] urls = clone.getURLs();
  79. for (int i = 0; i < urls.length; i++) {
  80. Object pathElement;
  81. URL url = urls[i];
  82. if (debug)
  83. System.out.println("JRockitClassLoader.JRockitClassLoader() url=" + url.getPath());
  84. File file = new File(encode(url.getFile()));
  85. if (debug)
  86. System.out.println("JRockitClassLoader.JRockitClassLoader() file" + file);
  87. if (file.isDirectory())
  88. pathElement = file;
  89. else if (file.exists() && file.getName().endsWith(".jar"))
  90. pathElement = new JarFile(file);
  91. else
  92. throw new RuntimeException(file.getAbsolutePath());
  93. path.add(pathElement);
  94. }
  95. Class agentClazz = Class.forName("org.aspectj.weaver.loadtime.JRockitAgent", false, this);
  96. Object obj = agentClazz.newInstance();
  97. if (debug)
  98. System.out.println("JRockitClassLoader.JRockitClassLoader() obj=" + obj);
  99. this.agent = obj;
  100. byte[] bytes = new byte[] {};
  101. Class[] parameterTypes = new Class[] { java.lang.ClassLoader.class, java.lang.String.class, bytes.getClass() };
  102. preProcess = agentClazz.getMethod("preProcess", parameterTypes);
  103. }
  104. /* Get rid of escaped characters */
  105. private String encode(String s) {
  106. StringBuffer result = new StringBuffer();
  107. int i = s.indexOf("%");
  108. while (i != -1) {
  109. result.append(s.substring(0, i));
  110. String escaped = s.substring(i + 1, i + 3);
  111. s = s.substring(i + 3);
  112. Integer value = Integer.valueOf(escaped, 16);
  113. result.append(new Character((char) value.intValue()));
  114. i = s.indexOf("%");
  115. }
  116. result.append(s);
  117. return result.toString();
  118. }
  119. protected Class findClass(String name) throws ClassNotFoundException {
  120. if (debug)
  121. System.out.println("> JRockitClassLoader.findClass() name=" + name);
  122. Class clazz = null;
  123. try {
  124. clazz = super.findClass(name);
  125. } catch (ClassNotFoundException ex) {
  126. for (Iterator i = path.iterator(); clazz == null && i.hasNext();) {
  127. byte[] classBytes = null;
  128. try {
  129. Object pathElement = i.next();
  130. if (pathElement instanceof File) {
  131. File dir = (File) pathElement;
  132. String className = name.replace('.', '/') + ".class";
  133. File classFile = new File(dir, className);
  134. if (classFile.exists())
  135. classBytes = loadClassFromFile(name, classFile);
  136. } else {
  137. JarFile jar = (JarFile) pathElement;
  138. String className = name.replace('.', '/') + ".class";
  139. ZipEntry entry = jar.getEntry(className);
  140. if (entry != null)
  141. classBytes = loadBytesFromZipEntry(jar, entry);
  142. }
  143. if (classBytes != null) {
  144. clazz = defineClass(name, classBytes);
  145. }
  146. } catch (IOException ioException) {
  147. ex.printStackTrace();
  148. }
  149. }
  150. }
  151. if (debug)
  152. System.out.println("< JRockitClassLoader.findClass() name=" + name);
  153. return clazz;
  154. }
  155. private Class defineClass(String name, byte[] bytes) {
  156. if (debug)
  157. System.out.println("> JRockitClassLoader.defineClass() name=" + name);
  158. try {
  159. if (agent != null)
  160. preProcess.invoke(agent, new Object[] { this, name, bytes });
  161. } catch (IllegalAccessException iae) {
  162. iae.printStackTrace();
  163. throw new ClassFormatError(iae.getMessage());
  164. } catch (InvocationTargetException ite) {
  165. ite.printStackTrace();
  166. throw new ClassFormatError(ite.getTargetException().getMessage());
  167. }
  168. if (debug)
  169. System.out.println("< JRockitClassLoader.defineClass() name=" + name);
  170. return super.defineClass(name, bytes, 0, bytes.length);
  171. }
  172. private byte[] loadClassFromFile(String name, File file) throws IOException {
  173. if (debug)
  174. System.out.println("JRockitClassLoader.loadClassFromFile() file=" + file);
  175. byte[] bytes;
  176. bytes = new byte[(int) file.length()];
  177. FileInputStream fis = null;
  178. try {
  179. fis = new FileInputStream(file);
  180. bytes = readBytes(fis, bytes);
  181. } finally {
  182. if (fis != null)
  183. fis.close();
  184. }
  185. return bytes;
  186. }
  187. private byte[] loadBytesFromZipEntry(JarFile jar, ZipEntry entry) throws IOException {
  188. if (debug)
  189. System.out.println("JRockitClassLoader.loadBytesFromZipEntry() entry=" + entry);
  190. byte[] bytes;
  191. bytes = new byte[(int) entry.getSize()];
  192. InputStream is = null;
  193. try {
  194. is = jar.getInputStream(entry);
  195. bytes = readBytes(is, bytes);
  196. } finally {
  197. if (is != null)
  198. is.close();
  199. }
  200. return bytes;
  201. }
  202. private byte[] readBytes(InputStream is, byte[] bytes) throws IOException {
  203. for (int offset = 0; offset < bytes.length;) {
  204. int read = is.read(bytes, offset, bytes.length - offset);
  205. offset += read;
  206. }
  207. return bytes;
  208. }
  209. }
  210. }