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 org.codehaus.aspectwerkz.hook.impl;
9
10 import org.codehaus.aspectwerkz.hook.ClassPreProcessor;
11
12 import java.io.File;
13 import java.io.IOException;
14 import java.net.MalformedURLException;
15 import java.net.URL;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.Enumeration;
19 import java.util.Hashtable;
20 import java.util.Iterator;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.WeakHashMap;
24
25 /***
26 * A simple implementation of class preprocessor. <p/>It does not modify the bytecode. It just prints on stdout some
27 * messages.
28 *
29 * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
30 */
31 public class StdoutPreProcessor implements ClassPreProcessor {
32 /***
33 * Classloaders repository, based on a synchronized weak hashmap key = classloader value = List of URL[]
34 * representing the local search path for .class files of the classloader value is completed at each class loading
35 */
36 private static Map classloaders;
37
38 /***
39 * ms interval betwee classloader hierarchy printing
40 */
41 private static final long stepms = 15000;
42
43 private static transient long lastPrinted = 0;
44
45 private void log(String s) {
46 System.out.println(Thread.currentThread().getName() + ": StdoutPreProcessor: " + s);
47 }
48
49 public void initialize() {
50 log("initialize");
51 log("loaded by " + this.getClass().getClassLoader());
52 classloaders = Collections.synchronizedMap(new WeakHashMap());
53
54
55 registerClassLoader(this.getClass().getClassLoader(), this.getClass().getName());
56 }
57
58 public byte[] preProcess(String klass, byte[] abyte, ClassLoader caller) {
59
60 klass = klass.replace('.', '/') + ".class";
61 URL u = caller.getResource(klass);
62 log("> " + klass + " [" + ((u == null) ? "?" : u.toString()) + "] [" + caller + "]");
63
64
65
66
67
68
69
70
71
72
73 registerClassLoader(caller, klass);
74
75
76 registerSearchPath(caller, klass);
77
78
79 if (System.currentTimeMillis() > (lastPrinted + stepms)) {
80 lastPrinted = System.currentTimeMillis();
81 log("*******************************");
82 log("size=" + classloaders.size());
83 dumpHierarchy(null, "");
84 log("*******************************");
85 }
86 return abyte;
87 }
88
89 /***
90 * Register a weak reference on the classloader Looks for META-INF/manifest.mf resource and log a line
91 *
92 * @param loader
93 * @param firstClassLoaded
94 */
95 private void registerClassLoader(ClassLoader loader, String firstClassLoaded) {
96 if (loader != null) {
97 if (!classloaders.containsKey(loader)) {
98
99 registerClassLoader(loader.getParent(), loader.getClass().getName());
100 registerSearchPath(loader.getParent(), loader.getClass().getName());
101 URL u = null;
102
103
104
105
106
107
108
109
110
111
112 try {
113
114
115 Enumeration ue = loader.getResources("META-INF/MANIFEST.MF");
116 if (ue.hasMoreElements()) {
117 log("--- in scope for " + loader);
118 }
119 while (ue.hasMoreElements()) {
120 log("--- " + ue.nextElement().toString());
121 }
122 } catch (IOException e) {
123 ;
124 }
125
126
127 log("****" + loader + " [" + ((u == null) ? "?" : u.toString()) + "] [" + firstClassLoaded + ']');
128 classloaders.put(loader, new ArrayList());
129 }
130
131
132 }
133 }
134
135 /***
136 * Dumps on stdout the registered classloader hierarchy child of "parent" Using the depth to track recursivity level
137 */
138 private void dumpHierarchy(ClassLoader parent, String depth) {
139
140 List cl = new ArrayList(classloaders.keySet());
141 ClassLoader current = null;
142 for (Iterator i = cl.iterator(); i.hasNext();) {
143 current = (ClassLoader) i.next();
144 if (current.getParent() == parent) {
145 log(depth + current + '[' + classloaders.get(current));
146
147
148 List path = (List) classloaders.get(current);
149 ClassLoader currentParent = current.getParent();
150 while (currentParent != null) {
151 for (Iterator us = path.iterator(); us.hasNext();) {
152 URL u = (URL) us.next();
153 if (((List) classloaders.get(currentParent)).contains(u)) {
154 log("!!!! duplicate detected for " + u + " in " + current);
155 }
156 }
157 currentParent = currentParent.getParent();
158 }
159 dumpHierarchy(current, depth + " ");
160 }
161 }
162 }
163
164 private void registerSearchPath(final ClassLoader loader, final String klass) {
165
166 if (loader == null) {
167 return;
168 }
169
170
171 String klassFile = klass.replace('.', '/') + ".class";
172 URL uKlass = loader.getResource(klassFile);
173 if (uKlass == null) {
174 return;
175 }
176
177
178 URL uRoot = null;
179 int i = uKlass.toString().indexOf('!');
180 if (i > 0) {
181
182 try {
183
184
185 uRoot = (new File(uKlass.toString().substring(4, i))).getCanonicalFile().toURL();
186
187
188 } catch (MalformedURLException e) {
189 e.printStackTrace();
190 return;
191 } catch (IOException e2) {
192 e2.printStackTrace();
193 return;
194 }
195 } else {
196
197 i = uKlass.toString().indexOf(klassFile);
198 try {
199 uRoot = (new File(uKlass.toString().substring(0, i))).getCanonicalFile().toURL();
200 } catch (MalformedURLException e) {
201 e.printStackTrace();
202 return;
203 } catch (IOException e2) {
204 e2.printStackTrace();
205 return;
206 }
207 }
208
209
210 ClassLoader parent = loader.getParent();
211 while (parent != null) {
212 if (((List) classloaders.get(parent)).contains(uRoot)) {
213 return;
214 }
215 parent = parent.getParent();
216 }
217
218
219
220 List path = (List) classloaders.get(loader);
221 if (!path.contains(uRoot)) {
222 log("adding path " + uRoot + " to " + loader);
223 path.add(uRoot);
224 }
225 }
226
227 public static void main(String[] args) throws Exception {
228 URL u = new URL(
229 "jar:file:/C:/bea/user_projects/domains/mydomain/myserver/.wlnotdelete/gallery/gallery-rar.jar!/"
230 );
231
232
233 URL u2 = new URL(
234 "jar:file:/C:/bea/user_projects/domains/mydomain/./myserver/.wlnotdelete/gallery/gallery-rar.jar!/"
235 );
236 if (u.sameFile(u2)) {
237 System.out.println("same");
238 } else {
239 System.out.println("differ");
240 }
241 }
242 }