git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@27 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
@@ -7,7 +7,7 @@ | |||
<h1>Javassist version 2</h1> | |||
<h3>in May, 2003. | |||
<h3>in July, 2003. | |||
<br>Copyright (C) 2000-2003 by Shigeru Chiba, All rights reserved.</h3> | |||
<p><br></p> | |||
@@ -236,6 +236,13 @@ see javassist.Dump. | |||
<h2>Changes</h2> | |||
<p>- version 2.6 in July, 2003. | |||
<ul> | |||
<li>CtConstructor.setBody() now works for class initializers. | |||
<li>CtNewMethod.delegator() now works for static methods. | |||
</ul> | |||
<p>- version 2.5.1 in May, 2003. | |||
<br>Simple changes for integration with JBoss AOP | |||
<ul> | |||
@@ -484,7 +491,7 @@ the original license term described above. | |||
<h2>Acknowledgments</h2> | |||
<p>The development of this software is sponsored in part by the PRESTO | |||
programs of <a href="http://www.jst.go.jp/">Japan | |||
and CREST programs of <a href="http://www.jst.go.jp/">Japan | |||
Science and Technology Corporation</a>. | |||
<p>I'd like to thank Michiaki Tatsubori, Johan Cloetens, | |||
@@ -495,7 +502,7 @@ Marc Segura-Devillechaise, Jan Baudisch, Julien Blass, Yoshiki Sato, | |||
Fabian Crabus, Bo Norregaard Jorgensen, Bob Lee, Bill Burke, | |||
Remy Sanlaville, Muga Nishizawa, Alexey Loubyansky, Saori Oki, | |||
Andreas Salathe, Dante Torres estrada, S. Pam, Nuno Santos, | |||
Denis Taye, and Colin Sampaleanu | |||
Denis Taye, Colin Sampaleanu, and Robert Bialek | |||
for their contributions. | |||
<p><br> |
@@ -2,6 +2,6 @@ Manifest-Version: 1.0 | |||
Specification-Title: Javassist | |||
Created-By: Shigeru Chiba, Tokyo Institute of Technology | |||
Specification-Vendor: Shigeru Chiba, Tokyo Institute of Technology | |||
Specification-Version: 2.5.1 | |||
Specification-Version: 2.6 | |||
Name: javassist/ | |||
@@ -32,6 +32,8 @@ import java.io.InputStream; | |||
public interface ClassPath { | |||
/** | |||
* Opens a class file. | |||
* This method may be called just to examine whether the class file | |||
* exists as well as to read the contents of the file. | |||
* | |||
* <p>This method can return null if the specified class file is not | |||
* found. If null is returned, the next search path is examined. | |||
@@ -39,9 +41,11 @@ public interface ClassPath { | |||
* so that the search is terminated. | |||
* | |||
* <p>This method should not modify the contents of the class file. | |||
* Use <code>javassist.Translator</code> for modification. | |||
* | |||
* @param classname a fully-qualified class name | |||
* @return the input stream for reading a class file | |||
* @see javassist.Translator | |||
*/ | |||
InputStream openClassfile(String classname) throws NotFoundException; | |||
@@ -91,6 +91,7 @@ public class ClassPool { | |||
{ | |||
return (CtClass)classes.get(classname); | |||
} | |||
/** | |||
* Creates a class pool. | |||
* |
@@ -35,7 +35,7 @@ public abstract class CtClass { | |||
/** | |||
* The version number of this release. | |||
*/ | |||
public static final String version = "2.5.1"; | |||
public static final String version = "2.6"; | |||
static final String javaLangObject = "java.lang.Object"; | |||
@@ -377,7 +377,9 @@ public abstract class CtClass { | |||
/** | |||
* Obtains the class object representing the superclass of the | |||
* class. | |||
* It returns null if the class is <code>java.lang.Object</code>. | |||
* It returns null if this object represents the | |||
* <code>java.lang.Object</code> class and thus it does not have | |||
* the super class. | |||
*/ | |||
public CtClass getSuperclass() throws NotFoundException { | |||
return null; |
@@ -289,7 +289,10 @@ public final class CtConstructor extends CtBehavior { | |||
*/ | |||
public void setBody(String src) throws CannotCompileException { | |||
if (src == null) | |||
src = "super();"; | |||
if (isClassInitializer()) | |||
src = ";"; | |||
else | |||
src = "super();"; | |||
super.setBody(src); | |||
} |
@@ -307,12 +307,12 @@ public class CtNewMethod { | |||
CtClass[] params = delegate.getParameterTypes(); | |||
int s; | |||
if (isStatic) { | |||
s = code.addLoadParameters(params); | |||
s = code.addLoadParameters(params, 0); | |||
code.addInvokestatic(deleClass, methodName, desc); | |||
} | |||
else { | |||
code.addLoad(0, deleClass); | |||
s = code.addLoadParameters(params); | |||
s = code.addLoadParameters(params, 1); | |||
code.addInvokespecial(deleClass, methodName, desc); | |||
} | |||
@@ -63,7 +63,7 @@ class CtNewWrappedConstructor extends CtNewWrappedMethod { | |||
code.addInvokespecial(superclazz, "<init>", "()V"); | |||
} | |||
else if (howToCallSuper == PASS_PARAMS) { | |||
stacksize = code.addLoadParameters(parameters) + 1; | |||
stacksize = code.addLoadParameters(parameters, 1) + 1; | |||
code.addInvokespecial(superclazz, "<init>", | |||
Descriptor.ofConstructor(parameters)); | |||
} |
@@ -688,13 +688,16 @@ public class Bytecode implements Opcode { | |||
/** | |||
* Appends instructions for loading all the parameters onto the | |||
* operand stack. | |||
* | |||
* @param offset the index of the first parameter. It is 0 | |||
* if the method is static. Otherwise, it is 1. | |||
*/ | |||
public int addLoadParameters(CtClass[] params) { | |||
public int addLoadParameters(CtClass[] params, int offset) { | |||
int stacksize = 0; | |||
if (params != null) { | |||
int n = params.length; | |||
for (int i = 0; i < n; ++i) | |||
stacksize += addLoad(stacksize + 1, params[i]); | |||
stacksize += addLoad(stacksize + offset, params[i]); | |||
} | |||
return stacksize; |
@@ -1001,15 +1001,28 @@ class ClassInfo extends ConstInfo { | |||
public int getTag() { return tag; } | |||
public void renameClass(ConstPool cp, String oldName, String newName) { | |||
if (cp.getUtf8Info(name).equals(oldName)) | |||
String nameStr = cp.getUtf8Info(name); | |||
if (nameStr.equals(oldName)) | |||
name = cp.addUtf8Info(newName); | |||
else if (nameStr.charAt(0) == '[') { | |||
String nameStr2 = Descriptor.rename(nameStr, oldName, newName); | |||
if (nameStr != nameStr2) | |||
name = cp.addUtf8Info(nameStr2); | |||
} | |||
} | |||
public void renameClass(ConstPool cp, Map map) { | |||
String oldName = cp.getUtf8Info(name); | |||
String newName = (String)map.get(oldName); | |||
if (newName != null && !newName.equals(oldName)) | |||
name = cp.addUtf8Info(newName); | |||
if (oldName.charAt(0) == '[') { | |||
String newName = Descriptor.rename(oldName, map); | |||
if (oldName != newName) | |||
name = cp.addUtf8Info(newName); | |||
} | |||
else { | |||
String newName = (String)map.get(oldName); | |||
if (newName != null && !newName.equals(oldName)) | |||
name = cp.addUtf8Info(newName); | |||
} | |||
} | |||
public int copy(ConstPool src, ConstPool dest, Map map) { |
@@ -250,6 +250,10 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { | |||
method.getReturn().getType() == VOID); | |||
} | |||
/** | |||
* @param isCons true if super() must be called. | |||
* false if the method is a class initializer. | |||
*/ | |||
public void atMethodBody(Stmnt s, boolean isCons, boolean isVoid) | |||
throws CompileError | |||
{ |
@@ -200,7 +200,11 @@ public class Javac { | |||
Parser p = new Parser(new Lex(src)); | |||
SymbolTable stb = new SymbolTable(stable); | |||
Stmnt s = p.parseStatement(stb); | |||
gen.atMethodBody(s, method instanceof CtConstructor, isVoid); | |||
boolean callSuper = false; | |||
if (method instanceof CtConstructor) | |||
callSuper = !((CtConstructor)method).isClassInitializer(); | |||
gen.atMethodBody(s, callSuper, isVoid); | |||
} | |||
return bytecode; |
@@ -317,6 +317,13 @@ modified at load time. The users of Javassist can define their own | |||
version of class loader but they can also use a class loader provided | |||
by Javassist. | |||
<p>Using a class loader is not easy. Especially if you are a beginner, | |||
you should separate your program into an application program and an | |||
instrumentation program and each of the two programs should be loaded | |||
by a single class loader. You should | |||
avoid loading part of the application program with the default class loader | |||
and the rest of the program with a user-defined class loader. | |||
<p><br> | |||
<h3>4.1 Using <code>javassist.Loader</code></h3> | |||
@@ -462,6 +469,33 @@ a runtime exception because of type mismatch; the type of | |||
<code>L1</code> whereas the type of <code>this</code> is the class | |||
<code>Point</code> loaded by <code>L2</code>. | |||
<p><code>javassist.Loader</code> searches for classes in a different | |||
order from <code>java.lang.ClassLoader</code>. | |||
<code>ClassLoader</code> first delegates the loading operations to | |||
the parent class loader and then attempts to load the classes | |||
only if the parent class loader cannot find them. | |||
On the other hand, | |||
<code>javassist.Loader</code> attempts | |||
to load the classes before delegating to the parent class loader. | |||
It delegates only if: | |||
<ul><li>the classes are not found by using the <code>ClassPool</code> | |||
object, or | |||
<p><li>the classes have been specified by using | |||
<code>delegateLoadingOf()</code> | |||
to be loaded by the parent class loader. | |||
</ul> | |||
<p>This search order allows loading modified classes by Javassist into | |||
the JVM. However, it delegates to the parent class loader if it fails | |||
to find modified classes for some reason. Once a class is loaded by | |||
the parent class loader, the other classes used by that class will be | |||
also loaded without modification by the parent class loader. <em>If your | |||
program fails to load a modified class,</em> you should make sure whether | |||
all the classes using that class have been loaded by | |||
<code>javassist.Loader</code>. | |||
<p><br> | |||
<h3>4.2 Writing a class loader</h3> |