diff options
author | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2012-02-15 04:44:56 +0000 |
---|---|---|
committer | chiba <chiba@30ef5769-5b8d-40dd-aea6-55b5d6557bb3> | 2012-02-15 04:44:56 +0000 |
commit | 205b65d96c5fb9d0086eb98d31e21e927d79cf27 (patch) | |
tree | 3291bc8e8eebd667212477e7688278af88b6c227 /src/main | |
parent | cbc67704adef11473329e901ec99f3563be78de4 (diff) | |
download | javassist-205b65d96c5fb9d0086eb98d31e21e927d79cf27.tar.gz javassist-205b65d96c5fb9d0086eb98d31e21e927d79cf27.zip |
fixed JASSIST-155
git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@613 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
Diffstat (limited to 'src/main')
-rw-r--r-- | src/main/javassist/CtBehavior.java | 11 | ||||
-rw-r--r-- | src/main/javassist/CtClass.java | 38 | ||||
-rw-r--r-- | src/main/javassist/CtClassType.java | 13 | ||||
-rw-r--r-- | src/main/javassist/CtNewWrappedMethod.java | 2 | ||||
-rw-r--r-- | src/main/javassist/bytecode/ClassFile.java | 11 | ||||
-rw-r--r-- | src/main/javassist/tools/reflect/Reflection.java | 18 |
6 files changed, 77 insertions, 16 deletions
diff --git a/src/main/javassist/CtBehavior.java b/src/main/javassist/CtBehavior.java index 8a690da3..e01f868c 100644 --- a/src/main/javassist/CtBehavior.java +++ b/src/main/javassist/CtBehavior.java @@ -92,8 +92,15 @@ public abstract class CtBehavior extends CtMember { public abstract String getLongName(); /** - * Returns the MethodInfo representing this method/constructor in the + * Returns the <code>MethodInfo</code> representing this method/constructor in the * class file. + * + * <p>If you modify the bytecode through the returned + * <code>MethodInfo</code> object, you might have to explicitly + * rebuild a stack map table. Javassist does not automatically + * rebuild it for avoiding unnecessary rebuilding. + * + * @see javassist.bytecode.MethodInfo#rebuildStackMap(ClassPool) */ public MethodInfo getMethodInfo() { declaringClass.checkModify(); @@ -101,7 +108,7 @@ public abstract class CtBehavior extends CtMember { } /** - * Returns the MethodInfo representing the method/constructor in the + * Returns the <code>MethodInfo</code> representing the method/constructor in the * class file (read only). * Normal applications do not need calling this method. Use * <code>getMethodInfo()</code>. diff --git a/src/main/javassist/CtClass.java b/src/main/javassist/CtClass.java index e168a059..e8115319 100644 --- a/src/main/javassist/CtClass.java +++ b/src/main/javassist/CtClass.java @@ -51,6 +51,21 @@ public abstract class CtClass { protected String qualifiedName; /** + * If the value of this field is not null, then all class + * files modified by Javassist are saved under the directory + * specified by this variable. For example, if the value is + * <code>"./debug"</code>, then all class files are saved + * there. The directory name must not end with a directory + * separator such as <code>/</code>. + * + * <p>The default value is null. + * + * @see #debugWriteFile(String) + * @since 3.16 + */ + public static String debugDump = null; + + /** * The version number of this release. */ public static final String version = "3.16.0-GA"; @@ -64,7 +79,7 @@ public abstract class CtClass { */ public static void main(String[] args) { System.out.println("Javassist version " + CtClass.version); - System.out.println("Copyright (C) 1999-2011 Shigeru Chiba." + System.out.println("Copyright (C) 1999-2012 Shigeru Chiba." + " All Rights Reserved."); } @@ -1324,6 +1339,16 @@ public abstract class CtClass { public void writeFile(String directoryName) throws CannotCompileException, IOException { + DataOutputStream out = makeFileOutput(directoryName); + try { + toBytecode(out); + } + finally { + out.close(); + } + } + + protected DataOutputStream makeFileOutput(String directoryName) { String classname = getName(); String filename = directoryName + File.separatorChar + classname.replace('.', File.separatorChar) + ".class"; @@ -1334,15 +1359,8 @@ public abstract class CtClass { new File(dir).mkdirs(); } - DataOutputStream out - = new DataOutputStream(new BufferedOutputStream( - new DelayedFileOutputStream(filename))); - try { - toBytecode(out); - } - finally { - out.close(); - } + return new DataOutputStream(new BufferedOutputStream( + new DelayedFileOutputStream(filename))); } /** diff --git a/src/main/javassist/CtClassType.java b/src/main/javassist/CtClassType.java index 378ad880..abbc25fa 100644 --- a/src/main/javassist/CtClassType.java +++ b/src/main/javassist/CtClassType.java @@ -1414,6 +1414,9 @@ class CtClassType extends CtClass { modifyClassConstructor(cf); modifyConstructors(cf); + if (debugDump != null) + dumpClassFile(cf); + cf.write(out); out.flush(); fieldInitializers = null; @@ -1440,6 +1443,16 @@ class CtClassType extends CtClass { } } + private void dumpClassFile(ClassFile cf) throws IOException { + DataOutputStream dump = makeFileOutput(debugDump); + try { + cf.write(dump); + } + finally { + dump.close(); + } + } + /* See also checkModified() */ private void checkPruned(String method) { diff --git a/src/main/javassist/CtNewWrappedMethod.java b/src/main/javassist/CtNewWrappedMethod.java index 1ba5caf8..f3030f7d 100644 --- a/src/main/javassist/CtNewWrappedMethod.java +++ b/src/main/javassist/CtNewWrappedMethod.java @@ -151,7 +151,7 @@ class CtNewWrappedMethod { int acc = body.getAccessFlags(); body.setAccessFlags(AccessFlag.setPrivate(acc)); body.addAttribute(new SyntheticAttribute(classfile.getConstPool())); - // a stack map is copied. rebuilding it is not needed. + // a stack map is copied. rebuilding it is not needed. classfile.addMethod(body); bodies.put(src, bodyname); CtMember.Cache cache = clazz.hasMemberCache(); diff --git a/src/main/javassist/bytecode/ClassFile.java b/src/main/javassist/bytecode/ClassFile.java index c3fb10d9..5a6adc7b 100644 --- a/src/main/javassist/bytecode/ClassFile.java +++ b/src/main/javassist/bytecode/ClassFile.java @@ -89,8 +89,11 @@ public final class ClassFile { /** * The major version number of class files created - * from scratch. The default value is 47 (JDK 1.3) - * or 49 (JDK 1.5) if the JVM supports <code>java.lang.StringBuilder</code>. + * from scratch. The default value is 47 (JDK 1.3). + * It is 49 (JDK 1.5) + * if the JVM supports <code>java.lang.StringBuilder</code>. + * It is 50 (JDK 1.6) + * if the JVM supports <code>java.util.zip.DeflaterInputStream</code>. */ public static int MAJOR_VERSION = JAVA_3; @@ -98,6 +101,8 @@ public final class ClassFile { try { Class.forName("java.lang.StringBuilder"); MAJOR_VERSION = JAVA_5; + Class.forName("java.util.zip.DeflaterInputStream"); + MAJOR_VERSION = JAVA_6; } catch (Throwable t) {} } @@ -796,7 +801,7 @@ public final class ClassFile { } /** - * Writes a class file represened by this object into an output stream. + * Writes a class file represented by this object into an output stream. */ public void write(DataOutputStream out) throws IOException { int i, n; diff --git a/src/main/javassist/tools/reflect/Reflection.java b/src/main/javassist/tools/reflect/Reflection.java index 3b8277c8..30f8bb79 100644 --- a/src/main/javassist/tools/reflect/Reflection.java +++ b/src/main/javassist/tools/reflect/Reflection.java @@ -16,8 +16,12 @@ package javassist.tools.reflect; +import java.util.Iterator; import javassist.*; import javassist.CtMethod.ConstParameter; +import javassist.bytecode.ClassFile; +import javassist.bytecode.BadBytecode; +import javassist.bytecode.MethodInfo; /** * The class implementing the behavioral reflection mechanism. @@ -107,6 +111,7 @@ public class Reflection implements Translator { = "javassist.tools.reflect.Sample is not found or broken."; try { CtClass c = classPool.get("javassist.tools.reflect.Sample"); + rebuildClassFile(c.getClassFile()); trapMethod = c.getDeclaredMethod("trap"); trapStaticMethod = c.getDeclaredMethod("trapStatic"); trapRead = c.getDeclaredMethod("trapRead"); @@ -116,6 +121,8 @@ public class Reflection implements Translator { } catch (NotFoundException e) { throw new RuntimeException(msg); + } catch (BadBytecode e) { + throw new RuntimeException(msg); } } @@ -382,4 +389,15 @@ public class Reflection implements Translator { } } } + + public void rebuildClassFile(ClassFile cf) throws BadBytecode { + if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_6) + return; + + Iterator methods = cf.getMethods().iterator(); + while (methods.hasNext()) { + MethodInfo mi = (MethodInfo)methods.next(); + mi.rebuildStackMap(classPool); + } + } } |