Source Code Cross Referenced for ClassLoaderPreProcessorImpl.java in  » Aspect-oriented » aspectwerkz-2.0 » org » codehaus » aspectwerkz » hook » impl » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Aspect oriented » aspectwerkz 2.0 » org.codehaus.aspectwerkz.hook.impl 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /**************************************************************************************
002:         * Copyright (c) Jonas BonŽr, Alexandre Vasseur. All rights reserved.                 *
003:         * http://aspectwerkz.codehaus.org                                                    *
004:         * ---------------------------------------------------------------------------------- *
005:         * The software in this package is published under the terms of the LGPL license      *
006:         * a copy of which has been included with this distribution in the license.txt file.  *
007:         **************************************************************************************/package org.codehaus.aspectwerkz.hook.impl;
008:
009:        import org.codehaus.aspectwerkz.hook.ClassLoaderPatcher;
010:        import org.codehaus.aspectwerkz.hook.ClassLoaderPreProcessor;
011:        import org.objectweb.asm.ClassWriter;
012:        import org.objectweb.asm.CodeVisitor;
013:        import org.objectweb.asm.Attribute;
014:        import org.objectweb.asm.ClassReader;
015:        import org.objectweb.asm.ClassVisitor;
016:        import org.objectweb.asm.ClassAdapter;
017:        import org.objectweb.asm.CodeAdapter;
018:        import org.objectweb.asm.Type;
019:        import org.objectweb.asm.Constants;
020:        import org.objectweb.asm.Label;
021:        import org.objectweb.asm.attrs.Attributes;
022:
023:        import java.io.InputStream;
024:        import java.io.OutputStream;
025:        import java.io.FileOutputStream;
026:        import java.io.File;
027:        import java.util.HashMap;
028:        import java.util.Map;
029:
030:        /**
031:         * Instruments the java.lang.ClassLoader to plug in the Class PreProcessor mechanism using ASM. <p/>We are using a
032:         * lazy initialization of the class preprocessor to allow all class pre processor logic to be in system classpath and
033:         * not in bootclasspath. <p/>This implementation should support IBM custom JRE
034:         *
035:         * @author Chris Nokleberg
036:         * @author <a href="mailto:alex@gnilux.com">Alexandre Vasseur </a>
037:         */
038:        public class ClassLoaderPreProcessorImpl implements 
039:                ClassLoaderPreProcessor {
040:
041:            private final static String CLASSLOADER_CLASS_NAME = "java/lang/ClassLoader";
042:            private final static String DEFINECLASS0_METHOD_NAME = "defineClass0";
043:            private final static String DEFINECLASS1_METHOD_NAME = "defineClass1";//For JDK 5
044:            private final static String DEFINECLASS2_METHOD_NAME = "defineClass2";//For JDK 5
045:
046:            private static final String DESC_CORE = "Ljava/lang/String;[BIILjava/security/ProtectionDomain;";
047:            private static final String DESC_PREFIX = "(" + DESC_CORE;
048:            private static final String DESC_HELPER = "(Ljava/lang/ClassLoader;"
049:                    + DESC_CORE + ")[B";
050:
051:            private static final String DESC_BYTEBUFFER_CORE = "Ljava/lang/String;Ljava/nio/ByteBuffer;IILjava/security/ProtectionDomain;";
052:            private static final String DESC_BYTEBUFFER_PREFIX = "("
053:                    + DESC_BYTEBUFFER_CORE;
054:            private static final String DESC_BYTEBUFFER_HELPER = "(Ljava/lang/ClassLoader;"
055:                    + DESC_BYTEBUFFER_CORE + ")[B";
056:
057:            public ClassLoaderPreProcessorImpl() {
058:            }
059:
060:            /**
061:             * Patch caller side of defineClass0
062:             * byte[] weaved = ..hook.impl.ClassPreProcessorHelper.defineClass0Pre(this, args..);
063:             * klass = defineClass0(name, weaved, 0, weaved.length, protectionDomain);
064:             *
065:             * @param classLoaderBytecode
066:             * @return
067:             */
068:            public byte[] preProcess(byte[] classLoaderBytecode) {
069:                try {
070:                    ClassWriter cw = new ClassWriter(true);
071:                    ClassLoaderVisitor cv = new ClassLoaderVisitor(cw);
072:                    ClassReader cr = new ClassReader(classLoaderBytecode);
073:                    cr.accept(cv, Attributes.getDefaultAttributes(), false);
074:                    return cw.toByteArray();
075:                } catch (Exception e) {
076:                    System.err.println("failed to patch ClassLoader:");
077:                    e.printStackTrace();
078:                    return classLoaderBytecode;
079:                }
080:            }
081:
082:            private static class ClassLoaderVisitor extends ClassAdapter {
083:                public ClassLoaderVisitor(ClassVisitor cv) {
084:                    super (cv);
085:                }
086:
087:                public CodeVisitor visitMethod(int access, String name,
088:                        String desc, String[] exceptions, Attribute attrs) {
089:                    CodeVisitor cv = super .visitMethod(access, name, desc,
090:                            exceptions, attrs);
091:                    Type[] args = Type.getArgumentTypes(desc);
092:                    return new PreProcessingVisitor(cv, access, args);
093:                }
094:            }
095:
096:            /**
097:             * @author Chris Nokleberg
098:             */
099:            private static class PreProcessingVisitor extends
100:                    RemappingCodeVisitor {
101:                public PreProcessingVisitor(CodeVisitor cv, int access,
102:                        Type[] args) {
103:                    super (cv, access, args);
104:                }
105:
106:                public void visitMethodInsn(int opcode, String owner,
107:                        String name, String desc) {
108:                    if ((DEFINECLASS0_METHOD_NAME.equals(name) || (DEFINECLASS1_METHOD_NAME
109:                            .equals(name)))
110:                            && CLASSLOADER_CLASS_NAME.equals(owner)) {
111:                        Type[] args = Type.getArgumentTypes(desc);
112:                        if (args.length < 5 || !desc.startsWith(DESC_PREFIX)) {
113:                            throw new Error(
114:                                    "non supported JDK, native call not supported: "
115:                                            + desc);
116:                        }
117:                        // store all args in local variables
118:                        int[] locals = new int[args.length];
119:                        for (int i = args.length - 1; i >= 0; i--) {
120:                            cv.visitVarInsn(
121:                                    args[i].getOpcode(Constants.ISTORE),
122:                                    locals[i] = nextLocal(args[i].getSize()));
123:                        }
124:                        for (int i = 0; i < 5; i++) {
125:                            cv.visitVarInsn(args[i].getOpcode(Constants.ILOAD),
126:                                    locals[i]);
127:                        }
128:                        super 
129:                                .visitMethodInsn(
130:                                        Constants.INVOKESTATIC,
131:                                        "org/codehaus/aspectwerkz/hook/impl/ClassPreProcessorHelper",
132:                                        "defineClass0Pre", DESC_HELPER);
133:                        cv.visitVarInsn(Constants.ASTORE, locals[1]);
134:                        cv.visitVarInsn(Constants.ALOAD, 0);
135:                        cv.visitVarInsn(Constants.ALOAD, locals[0]); // name
136:                        cv.visitVarInsn(Constants.ALOAD, locals[1]); // bytes
137:                        cv.visitInsn(Constants.ICONST_0); // offset
138:                        cv.visitVarInsn(Constants.ALOAD, locals[1]);
139:                        cv.visitInsn(Constants.ARRAYLENGTH); // length
140:                        cv.visitVarInsn(Constants.ALOAD, locals[4]); // protection domain
141:                        for (int i = 5; i < args.length; i++) {
142:                            cv.visitVarInsn(args[i].getOpcode(Constants.ILOAD),
143:                                    locals[i]);
144:                        }
145:                    } else if (DEFINECLASS2_METHOD_NAME.equals(name)
146:                            && CLASSLOADER_CLASS_NAME.equals(owner)) {
147:                        Type[] args = Type.getArgumentTypes(desc);
148:                        if (args.length < 5
149:                                || !desc.startsWith(DESC_BYTEBUFFER_PREFIX)) {
150:                            throw new Error(
151:                                    "non supported JDK, bytebuffer native call not supported: "
152:                                            + desc);
153:                        }
154:                        // store all args in local variables
155:                        int[] locals = new int[args.length];
156:                        for (int i = args.length - 1; i >= 0; i--) {
157:                            cv.visitVarInsn(
158:                                    args[i].getOpcode(Constants.ISTORE),
159:                                    locals[i] = nextLocal(args[i].getSize()));
160:                        }
161:                        for (int i = 0; i < 5; i++) {
162:                            cv.visitVarInsn(args[i].getOpcode(Constants.ILOAD),
163:                                    locals[i]);
164:                        }
165:                        super 
166:                                .visitMethodInsn(
167:                                        Constants.INVOKESTATIC,
168:                                        "org/codehaus/aspectwerkz/hook/impl/ClassPreProcessorHelper",
169:                                        "defineClass0Pre",
170:                                        DESC_BYTEBUFFER_HELPER);
171:                        cv.visitVarInsn(Constants.ASTORE, locals[1]);
172:                        cv.visitVarInsn(Constants.ALOAD, 0);
173:                        cv.visitVarInsn(Constants.ALOAD, locals[0]); // name
174:                        cv.visitVarInsn(Constants.ALOAD, locals[1]); // bytes
175:                        cv.visitInsn(Constants.ICONST_0); // offset
176:                        cv.visitVarInsn(Constants.ALOAD, locals[1]);
177:                        cv.visitMethodInsn(Constants.INVOKEVIRTUAL,
178:                                "Ljava/nio/Buffer;", "remaining", "()I");
179:                        cv.visitVarInsn(Constants.ALOAD, locals[4]); // protection domain
180:                        for (int i = 5; i < args.length; i++) {
181:                            cv.visitVarInsn(args[i].getOpcode(Constants.ILOAD),
182:                                    locals[i]);
183:                        }
184:                        // we should rebuild a new ByteBuffer...
185:
186:                    }
187:                    super .visitMethodInsn(opcode, owner, name, desc);
188:                }
189:            }
190:
191:            /**
192:             * @author Chris Nokleberg
193:             */
194:            private static class State {
195:                Map locals = new HashMap();
196:                int firstLocal;
197:                int nextLocal;
198:
199:                State(int access, Type[] args) {
200:                    nextLocal = ((Constants.ACC_STATIC & access) != 0) ? 0 : 1;
201:                    for (int i = 0; i < args.length; i++) {
202:                        nextLocal += args[i].getSize();
203:                    }
204:                    firstLocal = nextLocal;
205:                }
206:            }
207:
208:            /**
209:             * @author Chris Nokleberg
210:             */
211:            private static class IntRef {
212:                int key;
213:
214:                public boolean equals(Object o) {
215:                    return key == ((IntRef) o).key;
216:                }
217:
218:                public int hashCode() {
219:                    return key;
220:                }
221:            }
222:
223:            /**
224:             * @author Chris Nokleberg
225:             */
226:            private static class RemappingCodeVisitor extends CodeAdapter {
227:                private State state;
228:                private IntRef check = new IntRef();
229:
230:                public RemappingCodeVisitor(CodeVisitor v, int access,
231:                        Type[] args) {
232:                    super (v);
233:                    state = new State(access, args);
234:                }
235:
236:                public RemappingCodeVisitor(RemappingCodeVisitor wrap) {
237:                    super (wrap.cv);
238:                    this .state = wrap.state;
239:                }
240:
241:                protected int nextLocal(int size) {
242:                    int var = state.nextLocal;
243:                    state.nextLocal += size;
244:                    return var;
245:                }
246:
247:                private int remap(int var, int size) {
248:                    if (var < state.firstLocal) {
249:                        return var;
250:                    }
251:                    check.key = (size == 2) ? ~var : var;
252:                    Integer value = (Integer) state.locals.get(check);
253:                    if (value == null) {
254:                        IntRef ref = new IntRef();
255:                        ref.key = check.key;
256:                        state.locals.put(ref, value = new Integer(
257:                                nextLocal(size)));
258:                    }
259:                    return value.intValue();
260:                }
261:
262:                public void visitIincInsn(int var, int increment) {
263:                    cv.visitIincInsn(remap(var, 1), increment);
264:                }
265:
266:                public void visitLocalVariable(String name, String desc,
267:                        Label start, Label end, int index) {
268:                    cv.visitLocalVariable(name, desc, start, end, remap(index,
269:                            0));
270:                }
271:
272:                public void visitVarInsn(int opcode, int var) {
273:                    int size;
274:                    switch (opcode) {
275:                    case Constants.LLOAD:
276:                    case Constants.LSTORE:
277:                    case Constants.DLOAD:
278:                    case Constants.DSTORE:
279:                        size = 2;
280:                        break;
281:                    default:
282:                        size = 1;
283:                    }
284:                    cv.visitVarInsn(opcode, remap(var, size));
285:                }
286:
287:                public void visitMaxs(int maxStack, int maxLocals) {
288:                    cv.visitMaxs(0, 0);
289:                }
290:            }
291:
292:            public static void main(String args[]) throws Exception {
293:                ClassLoaderPreProcessor me = new ClassLoaderPreProcessorImpl();
294:                InputStream is = ClassLoader.getSystemClassLoader().getParent()
295:                        .getResourceAsStream("java/lang/ClassLoader.class");
296:                byte[] out = me.preProcess(ClassLoaderPatcher
297:                        .inputStreamToByteArray(is));
298:                is.close();
299:                File dir = new File("_boot/java/lang/");
300:                dir.mkdirs();
301:                OutputStream os = new FileOutputStream(
302:                        "_boot/java/lang/ClassLoader.class");
303:                os.write(out);
304:                os.close();
305:            }
306:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.