1 /***************************************************************************************
2 * Copyright (c) Jonas Bon?r, Alexandre Vasseur. All rights reserved. *
3 * http://aspectwerkz.codehaus.org *
4 * ---------------------------------------------------------------------------------- *
5 * The software in this package is published under the terms of the LGPL license *
6 * a copy of which has been included with this distribution in the license.txt file. *
7 **************************************************************************************/
8 package test.aopc;
9
10 import org.codehaus.aspectwerkz.exception.WrappedRuntimeException;
11
12 import java.io.File;
13 import java.lang.reflect.Array;
14 import java.lang.reflect.Method;
15 import java.net.MalformedURLException;
16 import java.net.URL;
17 import java.net.URLClassLoader;
18
19 import javassist.ClassPool;
20 import javassist.CtClass;
21 import javassist.CtMethod;
22 import javassist.LoaderClassPath;
23 import javassist.Modifier;
24
25 /***
26 * Test helper for AspectContainer, emulates a ClassLoader hierarchy sys/sub/ sys/sub/a sys/sub/b
27 *
28 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
29 */
30 public class ClassCreator {
31 /***
32 * ClassLoader.defineClass(name, bytes, from, to)
33 */
34 private static Method CLASSLOADER_DEFINECLASS_METHOD;
35
36 static {
37 try {
38 Object b = Array.newInstance(byte.class, 1);
39 CLASSLOADER_DEFINECLASS_METHOD = ClassLoader.class.getDeclaredMethod(
40 "defineClass",
41 new Class[] {
42 String.class, b.getClass(), int.class, int.class
43 });
44 CLASSLOADER_DEFINECLASS_METHOD.setAccessible(true);
45 } catch (Throwable t) {
46 t.printStackTrace();
47 }
48 }
49
50 public static Object createInstance(String name, Class classPrototype, ClassLoader loader) {
51 try {
52 return createClass(name, classPrototype, loader).newInstance();
53 } catch (Throwable t) {
54 throw new WrappedRuntimeException(t);
55 }
56 }
57
58 public static Class createClass(String name, Class classPrototype, ClassLoader loader) {
59 try {
60 ClassPool cp = new ClassPool(null);
61 cp.appendClassPath(new LoaderClassPath(loader));
62 CtClass prototype = cp.get(classPrototype.getName());
63 prototype.setName(name);
64 return define(prototype.toBytecode(), name, loader);
65 } catch (Throwable throwable) {
66 throw new WrappedRuntimeException(throwable);
67 }
68 }
69
70 public static void main(String[] a) throws Throwable {
71 ClassLoader myCL = new URLClassLoader(new URL[] {
72 getPathFor(Callable.class.getResource("META-INF/aop.xml"))
73 }, ClassLoader.getSystemClassLoader());
74 ClassLoader mySubCLA = new URLClassLoader(new URL[] {
75 getPathFor(Callable.class.getResource("a/META-INF/aop.xml"))
76 }, myCL);
77 Callable ca = (Callable) (createClass("test.aopc.a.Callee", CallablePrototype.class, mySubCLA)).newInstance();
78 ca.methodAround();
79 ca.debug();
80 ClassLoader mySubCLB = new URLClassLoader(new URL[] {}, myCL);
81 Callable cb = (Callable) (createClass("test.aopc.b.Callee", CallablePrototype.class, mySubCLB)).newInstance();
82 cb.methodAround();
83 cb.debug();
84 }
85
86 public static URL getPathFor(URL definition) {
87 try {
88 System.out.println(definition);
89 System.out.println(definition.getFile());
90 File f = new File(definition.getFile());
91 if (!f.exists()) {
92 System.err.println("<WARN> could not find " + f);
93 }
94 String path = new File(f.getParent()).getParent();
95 File testExists = new File(path);
96 if (!testExists.isDirectory()) {
97 System.err.println("<WARN> could not find " + path);
98 }
99 return new File(path).toURL();
100 } catch (MalformedURLException e) {
101 throw new WrappedRuntimeException(e);
102 }
103 }
104
105 /***
106 * Helper to define a Class within a specific ClassLoader
107 *
108 * @param b
109 * @param name
110 * @param loader
111 * @return @throws Throwable
112 */
113 public static Class define(byte[] b, String name, ClassLoader loader) throws Throwable {
114 Object k = CLASSLOADER_DEFINECLASS_METHOD.invoke(loader, new Object[] {
115 name, b, new Integer(0), new Integer(b.length)
116 });
117 return (Class) k;
118 }
119 }