git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@613 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
@@ -283,7 +283,7 @@ see javassist.Dump. | |||
<p>-version 3.16 | |||
<ul> | |||
<li>JIRA JASSIST-126, 127, 144, 145, 146, 147, 149. | |||
<li>JIRA JASSIST-126, 127, 144, 145, 146, 147, 149, 150, 153, 155. | |||
<li><code>javassist.bytecode.analysis.ControlFlow</code> was added. | |||
</ul> | |||
@@ -95,6 +95,7 @@ | |||
<target name="runtest" depends="test-compile"> | |||
<junit fork="true" printsummary="true" dir="${test.run.dir}"> | |||
<jvmarg value="-XX:-FailOverToOldVerifier" /> | |||
<classpath refid="test.classpath"/> | |||
<formatter type="xml" extension=".xml"/> | |||
<test name="javassist.JvstTest" outfile="TestLog" /> |
@@ -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>. |
@@ -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 | |||
* <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. | |||
*/ | |||
@@ -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))); | |||
} | |||
/** |
@@ -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) { |
@@ -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(); |
@@ -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; |
@@ -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); | |||
} | |||
} | |||
} |
@@ -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()); |
@@ -26,6 +26,7 @@ Shigeru Chiba | |||
<br>6. <a href="tutorial3.html#generics">Generics</a> | |||
<br>7. <a href="tutorial3.html#varargs">Varargs</a> | |||
<br>8. <a href="tutorial3.html#j2me">J2ME</a> | |||
<br>9. <a href="tutorial3.html#debug">Debug</a> | |||
</ul> | |||
<p><br> | |||
@@ -1098,6 +1099,6 @@ For more information, see the API documentation of | |||
<hr> | |||
Java(TM) is a trademark of Sun Microsystems, Inc.<br> | |||
Copyright (C) 2000-2010 by Shigeru Chiba, All rights reserved. | |||
Copyright (C) 2000-2012 by Shigeru Chiba, All rights reserved. | |||
</body> | |||
</html> |
@@ -28,6 +28,8 @@ | |||
<p><a href="#j2me">8. J2ME</a> | |||
<p><a href="#debug">9. Debug</a> | |||
<p><br> | |||
<a name="intro"> | |||
@@ -357,10 +359,27 @@ objects, call the <code>getDeclaredMethods</code> method on a <code>CtClass</cod | |||
<p><br> | |||
<h2><a name="debug">9. Debug</h2> | |||
<p>Set <code>CtClass.debugDump</code> to a directory name. | |||
Then all class files modified and generated by Javassist are saved in that | |||
directory. To stop this, set <code>CtClass.debugDump</code> to null. | |||
The default value is null. | |||
<p>For example, | |||
<ul><pre> | |||
CtClass.debugDump = "./dump"; | |||
</pre></ul> | |||
<p>All modified class files are saved in <code>./dump</code>. | |||
<p><br> | |||
<a href="tutorial2.html">Previous page</a> | |||
<hr> | |||
Java(TM) is a trademark of Sun Microsystems, Inc.<br> | |||
Copyright (C) 2000-2010 by Shigeru Chiba, All rights reserved. | |||
Copyright (C) 2000-2012 by Shigeru Chiba, All rights reserved. | |||
</body> | |||
</html> |