From: chiba Date: Wed, 15 Feb 2012 04:44:56 +0000 (+0000) Subject: fixed JASSIST-155 X-Git-Tag: rel_3_17_1_ga~46 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=205b65d96c5fb9d0086eb98d31e21e927d79cf27;p=javassist.git fixed JASSIST-155 git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@613 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- diff --git a/Readme.html b/Readme.html index c4b488b5..2553a29f 100644 --- a/Readme.html +++ b/Readme.html @@ -283,7 +283,7 @@ see javassist.Dump.

-version 3.16

diff --git a/build.xml b/build.xml index 3815e9d1..fa68728d 100644 --- a/build.xml +++ b/build.xml @@ -95,6 +95,7 @@ + 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 MethodInfo representing this method/constructor in the * class file. + * + *

If you modify the bytecode through the returned + * MethodInfo 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 MethodInfo representing the method/constructor in the * class file (read only). * Normal applications do not need calling this method. Use * getMethodInfo(). 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 @@ -50,6 +50,21 @@ import javassist.expr.ExprEditor; 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 + * "./debug", then all class files are saved + * there. The directory name must not end with a directory + * separator such as /. + * + *

The default value is null. + * + * @see #debugWriteFile(String) + * @since 3.16 + */ + public static String debugDump = null; + /** * The version number of this release. */ @@ -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 java.lang.StringBuilder. + * from scratch. The default value is 47 (JDK 1.3). + * It is 49 (JDK 1.5) + * if the JVM supports java.lang.StringBuilder. + * It is 50 (JDK 1.6) + * if the JVM supports java.util.zip.DeflaterInputStream. */ 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); + } + } } diff --git a/src/test/javassist/JvstTest4.java b/src/test/javassist/JvstTest4.java index 54e24584..4070eb74 100644 --- a/src/test/javassist/JvstTest4.java +++ b/src/test/javassist/JvstTest4.java @@ -20,8 +20,10 @@ public class JvstTest4 extends JvstTestRoot { CtMethod m1 = cc.getDeclaredMethod("run"); m1.getMethodInfo().getCodeAttribute().insertLocalVar(2, 20); + m1.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile()); CtMethod m2 = cc.getDeclaredMethod("run2"); m2.getMethodInfo().getCodeAttribute().insertLocalVar(2, 0x101); + m2.getMethodInfo().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile()); cc.writeFile(); Object obj = make(cc.getName()); @@ -83,6 +85,7 @@ public class JvstTest4 extends JvstTestRoot { } } }); + // m3.getMethodInfo2().rebuildStackMapIf6(cc.getClassPool(), cc.getClassFile2()); cc.writeFile(); Object obj = make(cc.getName()); diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html index dea83069..44bfd9eb 100644 --- a/tutorial/tutorial.html +++ b/tutorial/tutorial.html @@ -26,6 +26,7 @@ Shigeru Chiba
6. Generics
7. Varargs
8. J2ME +
9. Debug


@@ -1098,6 +1099,6 @@ For more information, see the API documentation of


Java(TM) is a trademark of Sun Microsystems, Inc.
-Copyright (C) 2000-2010 by Shigeru Chiba, All rights reserved. +Copyright (C) 2000-2012 by Shigeru Chiba, All rights reserved. diff --git a/tutorial/tutorial3.html b/tutorial/tutorial3.html index dd4fb791..e07372bd 100644 --- a/tutorial/tutorial3.html +++ b/tutorial/tutorial3.html @@ -28,6 +28,8 @@

8. J2ME +

9. Debug +


@@ -357,10 +359,27 @@ objects, call the getDeclaredMethods method on a CtClass
+

9. Debug

+ +

Set CtClass.debugDump to a directory name. +Then all class files modified and generated by Javassist are saved in that +directory. To stop this, set CtClass.debugDump to null. +The default value is null. + +

For example, + +

    +CtClass.debugDump = "./dump";
    +
+ +

All modified class files are saved in ./dump. + +


+
Previous page


Java(TM) is a trademark of Sun Microsystems, Inc.
-Copyright (C) 2000-2010 by Shigeru Chiba, All rights reserved. +Copyright (C) 2000-2012 by Shigeru Chiba, All rights reserved.