Browse Source

restructred sub packages


git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@233 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
tags/rel_3_17_1_ga
chiba 18 years ago
parent
commit
52a455616e
55 changed files with 1303 additions and 140 deletions
  1. 14
    10
      Readme.html
  2. 9
    6
      build.xml
  3. 1
    1
      sample/duplicate/DuplicatedObject.java
  4. 4
    4
      sample/duplicate/Main.java
  5. 1
    1
      sample/evolve/DemoServer.java
  6. 3
    3
      sample/evolve/Evolution.java
  7. 1
    1
      sample/evolve/VersionManager.java
  8. 1
    1
      sample/hotswap/Test.java
  9. 3
    3
      sample/reflect/Main.java
  10. 2
    2
      sample/reflect/Person.java
  11. 1
    1
      sample/reflect/VerboseMetaobj.java
  12. 3
    3
      sample/rmi/CountApplet.java
  13. 1
    1
      sample/rmi/Counter.java
  14. 1
    1
      sample/rmi/start.html
  15. 4
    4
      sample/rmi/webdemo.html
  16. 1
    1
      src/main/javassist/CtClass.java
  17. 1
    1
      src/main/javassist/CtMethod.java
  18. 1
    1
      src/main/javassist/bytecode/Bytecode.java
  19. 0
    1
      src/main/javassist/bytecode/Descriptor.java
  20. 1
    1
      src/main/javassist/bytecode/annotation/package.html
  21. 1
    1
      src/main/javassist/expr/MethodCall.java
  22. 1
    1
      src/main/javassist/tools/package.html
  23. 1
    1
      src/main/javassist/tools/reflect/CannotCreateException.java
  24. 4
    4
      src/main/javassist/tools/reflect/CannotInvokeException.java
  25. 2
    2
      src/main/javassist/tools/reflect/CannotReflectException.java
  26. 3
    3
      src/main/javassist/tools/reflect/ClassMetaobject.java
  27. 8
    8
      src/main/javassist/tools/reflect/Compiler.java
  28. 17
    17
      src/main/javassist/tools/reflect/Loader.java
  29. 1
    1
      src/main/javassist/tools/reflect/Metalevel.java
  30. 4
    4
      src/main/javassist/tools/reflect/Metaobject.java
  31. 18
    18
      src/main/javassist/tools/reflect/Reflection.java
  32. 1
    1
      src/main/javassist/tools/reflect/Sample.java
  33. 0
    0
      src/main/javassist/tools/reflect/package.html
  34. 5
    4
      src/main/javassist/tools/rmi/AppletServer.java
  35. 8
    7
      src/main/javassist/tools/rmi/ObjectImporter.java
  36. 1
    1
      src/main/javassist/tools/rmi/ObjectNotFoundException.java
  37. 2
    2
      src/main/javassist/tools/rmi/Proxy.java
  38. 1
    1
      src/main/javassist/tools/rmi/RemoteException.java
  39. 1
    1
      src/main/javassist/tools/rmi/RemoteRef.java
  40. 1
    1
      src/main/javassist/tools/rmi/Sample.java
  41. 6
    6
      src/main/javassist/tools/rmi/StubGenerator.java
  42. 0
    0
      src/main/javassist/tools/rmi/package.html
  43. 1
    1
      src/main/javassist/tools/web/BadHttpRequest.java
  44. 4
    4
      src/main/javassist/tools/web/Viewer.java
  45. 2
    2
      src/main/javassist/tools/web/Webserver.java
  46. 0
    0
      src/main/javassist/tools/web/package.html
  47. 2
    2
      src/main/javassist/util/HotSwapper.java
  48. 5
    0
      src/main/javassist/util/package.html
  49. 182
    0
      src/main/javassist/util/proxy/FactoryHelper.java
  50. 30
    0
      src/main/javassist/util/proxy/MethodFilter.java
  51. 48
    0
      src/main/javassist/util/proxy/MethodHandler.java
  52. 699
    0
      src/main/javassist/util/proxy/ProxyFactory.java
  53. 29
    0
      src/main/javassist/util/proxy/ProxyObject.java
  54. 157
    0
      src/main/javassist/util/proxy/RuntimeSupport.java
  55. 5
    0
      src/main/javassist/util/proxy/package.html

+ 14
- 10
Readme.html View File



<ul><pre> <ul><pre>
% javac sample/reflect/*.java % javac sample/reflect/*.java
% java javassist.reflect.Loader sample.reflect.Main Joe
% java javassist.tools.reflect.Loader sample.reflect.Main Joe
</pre></ul> </pre></ul>


<p>Compare this result with that of the regular execution without reflection: <p>Compare this result with that of the regular execution without reflection:
To do this, type the commands: To do this, type the commands:


<ul><pre> <ul><pre>
% java javassist.reflect.Compiler sample.reflect.Person -m sample.reflect.VerboseMetaobj
% java javassist.tools.reflect.Compiler sample.reflect.Person -m sample.reflect.VerboseMetaobj
</pre></ul> </pre></ul>


<p> Then, <p> Then,
<li>The return type of CtClass.stopPruning() was changed from void <li>The return type of CtClass.stopPruning() was changed from void
to boolean. to boolean.
<li>toMethod() in javassist.CtConstructor has been implemented. <li>toMethod() in javassist.CtConstructor has been implemented.
<li>javassist.preproc package was elminated and the source was
moved to the sample directory.
</ul>

<p>- version 3.1

<ul>
<li>javassist.tool package was renamed to javassist.tools.
<li>It includes new javassist.util.proxy package
similar to Enhancer of CGLIB.

<p>
<li>The subpackages of Javassist were restructured.
<ul>
<li>javassist.tool package was renamed to javassist.tools.
<li>HotSwapper was moved to javassist.util.
<li>Several subpackages were moved to javassist.tools.
<li>javassist.preproc package was elminated and the source was
moved to the sample directory.
</ul>
</ul> </ul>


<p>- version 3.1 RC2 in September 7, 2005 <p>- version 3.1 RC2 in September 7, 2005

+ 9
- 6
build.xml View File

excludepackagenames="javassist.compiler.*,javassist.convert.*" excludepackagenames="javassist.compiler.*,javassist.convert.*"
sourcepath="src/main" sourcepath="src/main"
defaultexcludes="yes" defaultexcludes="yes"
locale="en_US"
charset="iso-8859-1"
destdir="html" destdir="html"
author="true" author="true"
version="true" version="true"
use="true" use="true"
Locale="en_US"
charset="iso-8859-1"
Public="true"
public="true"
nohelp="true" nohelp="true"
windowtitle="Javassist API"> windowtitle="Javassist API">
<doctitle><![CDATA[<h1>Javassist</h1>]]></doctitle> <doctitle><![CDATA[<h1>Javassist</h1>]]></doctitle>
<bottom><![CDATA[<i>Javassist, a Java-bytecode translator toolkit. <bottom><![CDATA[<i>Javassist, a Java-bytecode translator toolkit.
Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.</i>]]></bottom>
Copyright (C) 1999-2006 Shigeru Chiba. All Rights Reserved.</i>]]></bottom>
</javadoc> </javadoc>
</target> </target>




<target name = "sample-all" <target name = "sample-all"
depends="sample-test,sample-reflect,sample-duplicate,sample-vector"> depends="sample-test,sample-reflect,sample-duplicate,sample-vector">
<echo>** please run sample-rmi and sample-evolve separately **</echo>
<echo>** please run sample-rmi, sample-evolve, and</echo>
<echo> sample-hotswap (or -hotswap5) separately **</echo>
</target> </target>


<target name = "sample-test" depends="sample" > <target name = "sample-test" depends="sample" >
</target> </target>


<target name = "sample-reflect" depends="sample" > <target name = "sample-reflect" depends="sample" >
<java fork="true" dir="${run.dir}" classname="javassist.reflect.Loader">
<java fork="true" dir="${run.dir}" classname="javassist.tools.reflect.Loader">
<classpath refid="classpath"/> <classpath refid="classpath"/>
<arg line="sample.reflect.Main Joe" /> <arg line="sample.reflect.Main Joe" />
</java> </java>
<!-- for JDK 1.4 --> <!-- for JDK 1.4 -->
<target name = "sample-hotswap" depends="sample"> <target name = "sample-hotswap" depends="sample">
<echo>** JAVA_HOME/lib/tools.jar must be included in CLASS_PATH</echo> <echo>** JAVA_HOME/lib/tools.jar must be included in CLASS_PATH</echo>
<echo>** for JDK 1.4</echo>
<java fork="true" dir="${run.dir}" classname="Test"> <java fork="true" dir="${run.dir}" classname="Test">
<jvmarg line="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000" /> <jvmarg line="-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=8000" />
<classpath refid="classpath"/> <classpath refid="classpath"/>
<!-- for Java 5 --> <!-- for Java 5 -->
<target name = "sample-hotswap5" depends="sample"> <target name = "sample-hotswap5" depends="sample">
<echo>** JAVA_HOME/lib/tools.jar must be included in CLASS_PATH</echo> <echo>** JAVA_HOME/lib/tools.jar must be included in CLASS_PATH</echo>
<echo>** for JDK 1.5 or later</echo>
<java fork="true" dir="${run.dir}" classname="Test"> <java fork="true" dir="${run.dir}" classname="Test">
<jvmarg line="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000" /> <jvmarg line="-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=8000" />
<classpath refid="classpath"/> <classpath refid="classpath"/>

+ 1
- 1
sample/duplicate/DuplicatedObject.java View File

package sample.duplicate; package sample.duplicate;
import javassist.reflect.*;
import javassist.tools.reflect.*;
public class DuplicatedObject extends Metaobject { public class DuplicatedObject extends Metaobject {
private DuplicatedObject backup; private DuplicatedObject backup;

+ 4
- 4
sample/duplicate/Main.java View File

/* /*
Runtime metaobject (JDK 1.2 or later only). Runtime metaobject (JDK 1.2 or later only).
With the javassist.reflect package, the users can attach a metaobject
With the javassist.tools.reflect package, the users can attach a metaobject
to an object. The metaobject can control the behavior of the object. to an object. The metaobject can control the behavior of the object.
For example, you can implement fault tolerancy with this ability. One For example, you can implement fault tolerancy with this ability. One
of the implementation techniques of fault tolernacy is to make a copy of the implementation techniques of fault tolernacy is to make a copy
% java sample.duplicate.Main % java sample.duplicate.Main
You would see two balls in a window. This is because You would see two balls in a window. This is because
sample.duplicate.Viewer is loaded by javassist.reflect.Loader so that
sample.duplicate.Viewer is loaded by javassist.tools.reflect.Loader so that
a metaobject would be attached. a metaobject would be attached.
*/ */
public class Main { public class Main {
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
javassist.reflect.Loader cl = new javassist.reflect.Loader();
javassist.tools.reflect.Loader cl = new javassist.tools.reflect.Loader();
cl.makeReflective("sample.duplicate.Ball", cl.makeReflective("sample.duplicate.Ball",
"sample.duplicate.DuplicatedObject", "sample.duplicate.DuplicatedObject",
"javassist.reflect.ClassMetaobject");
"javassist.tools.reflect.ClassMetaobject");
cl.run("sample.duplicate.Viewer", args); cl.run("sample.duplicate.Viewer", args);
} }
} }

+ 1
- 1
sample/evolve/DemoServer.java View File

package sample.evolve; package sample.evolve;
import javassist.web.*;
import javassist.tools.web.*;
import java.io.*; import java.io.*;
/** /**

+ 3
- 3
sample/evolve/Evolution.java View File

private void onLoadUpdatable(String classname) throws NotFoundException, private void onLoadUpdatable(String classname) throws NotFoundException,
CannotCompileException { CannotCompileException {
// if the class is a concrete class, // if the class is a concrete class,
// classname is <updatableClassName>$<version>.
// classname is <updatableClassName>$$<version>.
int i = classname.lastIndexOf('$');
int i = classname.lastIndexOf("$$");
if (i <= 0) if (i <= 0)
return; return;
int version; int version;
try { try {
version = Integer.parseInt(classname.substring(i + 1));
version = Integer.parseInt(classname.substring(i + 2));
} }
catch (NumberFormatException e) { catch (NumberFormatException e) {
throw new NotFoundException(classname, e); throw new NotFoundException(classname, e);

+ 1
- 1
sample/evolve/VersionManager.java View File

else else
version = ((Integer)found).intValue() + 1; version = ((Integer)found).intValue() + 1;
Class c = Class.forName(qualifiedClassname + '$' + version);
Class c = Class.forName(qualifiedClassname + "$$" + version);
versionNo.put(qualifiedClassname, new Integer(version)); versionNo.put(qualifiedClassname, new Integer(version));
return c; return c;
} }

+ 1
- 1
sample/hotswap/Test.java View File

import java.io.*; import java.io.*;
import javassist.tools.HotSwapper;
import javassist.util.HotSwapper;


public class Test { public class Test {
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {

+ 3
- 3
sample/reflect/Main.java View File

package sample.reflect; package sample.reflect;
import javassist.reflect.Loader;
import javassist.tools.reflect.Loader;
/* /*
The "verbose metaobject" example (JDK 1.2 or later only). The "verbose metaobject" example (JDK 1.2 or later only).
To run, To run,
% java javassist.reflect.Loader sample.reflect.Main Joe
% java javassist.tools.reflect.Loader sample.reflect.Main Joe
Compare this result with that of the regular execution without reflection: Compare this result with that of the regular execution without reflection:
Loader cl = (Loader)Main.class.getClassLoader(); Loader cl = (Loader)Main.class.getClassLoader();
cl.makeReflective("sample.reflect.Person", cl.makeReflective("sample.reflect.Person",
"sample.reflect.VerboseMetaobj", "sample.reflect.VerboseMetaobj",
"javassist.reflect.ClassMetaobject");
"javassist.tools.reflect.ClassMetaobject");
cl.run("sample.reflect.Person", args); cl.run("sample.reflect.Person", args);
} }

+ 2
- 2
sample/reflect/Person.java View File

package sample.reflect; package sample.reflect;
import javassist.reflect.Metalevel;
import javassist.reflect.Metaobject;
import javassist.tools.reflect.Metalevel;
import javassist.tools.reflect.Metaobject;
public class Person { public class Person {
public String name; public String name;

+ 1
- 1
sample/reflect/VerboseMetaobj.java View File

package sample.reflect; package sample.reflect;
import javassist.reflect.*;
import javassist.tools.reflect.*;
public class VerboseMetaobj extends Metaobject { public class VerboseMetaobj extends Metaobject {
public VerboseMetaobj(Object self, Object[] args) { public VerboseMetaobj(Object self, Object[] args) {

+ 3
- 3
sample/rmi/CountApplet.java View File

import java.applet.*; import java.applet.*;
import java.awt.*; import java.awt.*;
import java.awt.event.*; import java.awt.event.*;
import javassist.rmi.ObjectImporter;
import javassist.rmi.ObjectNotFoundException;
import javassist.web.Viewer;
import javassist.tools.rmi.ObjectImporter;
import javassist.tools.rmi.ObjectNotFoundException;
import javassist.tools.web.Viewer;
public class CountApplet extends Applet implements ActionListener { public class CountApplet extends Applet implements ActionListener {
private Font font; private Font font;

+ 1
- 1
sample/rmi/Counter.java View File

package sample.rmi; package sample.rmi;
import javassist.rmi.AppletServer;
import javassist.tools.rmi.AppletServer;
import java.io.IOException; import java.io.IOException;
import javassist.CannotCompileException; import javassist.CannotCompileException;
import javassist.NotFoundException; import javassist.NotFoundException;

+ 1
- 1
sample/rmi/start.html View File

<p>If you don't want to use a web browser, do as follows: <p>If you don't want to use a web browser, do as follows:
<ul><pre>% java javassist.web.Viewer localhost 5001 sample.rmi.CountApplet</pre></ul>
<ul><pre>% java javassist.tools.web.Viewer localhost 5001 sample.rmi.CountApplet</pre></ul>

+ 4
- 4
sample/rmi/webdemo.html View File

local object. The applet can communicate through a socket with the local object. The applet can communicate through a socket with the
host that executes the web server distributing that applet. However, host that executes the web server distributing that applet. However,
the applet cannot directly call a method on an object if the object is the applet cannot directly call a method on an object if the object is
on a remote host. The <code>javassist.rmi</code> package provides
on a remote host. The <code>javassist.tools.rmi</code> package provides
a mechanism for the applet to transparently access the remote object. a mechanism for the applet to transparently access the remote object.
The rules that the applet must be subject to are simpler than the The rules that the applet must be subject to are simpler than the
standard Java RMI. standard Java RMI.
<p><b>Figure 1: Applet</b> <p><b>Figure 1: Applet</b>
<pre> <pre>
<font color="red">import javassist.rmi.ObjectImporter;</font>
<font color="red">import javassist.tools.rmi.ObjectImporter;</font>
public class CountApplet extends Applet implements ActionListener { public class CountApplet extends Applet implements ActionListener {
private Font font; private Font font;
} }
</pre> </pre>
<p>Note that the <code>javassist.rmi</code> package does not require
<p>Note that the <code>javassist.tools.rmi</code> package does not require
the <code>Counter</code> class to be an interface unlike the Java RMI, the <code>Counter</code> class to be an interface unlike the Java RMI,
with which <code>Counter</code> must be an interface and it must be with which <code>Counter</code> must be an interface and it must be
implemented by another class. implemented by another class.
<p> With the Java RMI or Voyager, the applet programmer must define <p> With the Java RMI or Voyager, the applet programmer must define
an interface for every remote object class and access the remote object an interface for every remote object class and access the remote object
through that interface. through that interface.
On the other hand, the <code>javassist.rmi</code> package does not
On the other hand, the <code>javassist.tools.rmi</code> package does not
require the programmer to follow that programming convention. require the programmer to follow that programming convention.
It is suitable for writing simple distributed programs like applets. It is suitable for writing simple distributed programs like applets.

+ 1
- 1
src/main/javassist/CtClass.java View File

* *
* @param name method name * @param name method name
* @param desc method descriptor * @param desc method descriptor
* @see CtBehavior.getSignature()
* @see CtBehavior#getSignature()
* @see javassist.bytecode.Descriptor * @see javassist.bytecode.Descriptor
*/ */
public CtMethod getMethod(String name, String desc) public CtMethod getMethod(String name, String desc)

+ 1
- 1
src/main/javassist/CtMethod.java View File

* *
* @param src the source text. * @param src the source text.
* @param declaring the class to which the created method is added. * @param declaring the class to which the created method is added.
* @see CtNewMethod.make(String, CtClass)
* @see CtNewMethod#make(String, CtClass)
*/ */
public static CtMethod make(String src, CtClass declaring) public static CtMethod make(String src, CtClass declaring)
throws CannotCompileException throws CannotCompileException

+ 1
- 1
src/main/javassist/bytecode/Bytecode.java View File

* Appends PUTSTATIC. * Appends PUTSTATIC.
* *
* @param classname the fully-qualified name of the target class. * @param classname the fully-qualified name of the target class.
* @param filedName the field name.
* @param fieldName the field name.
* @param desc the descriptor of the field type. * @param desc the descriptor of the field type.
*/ */
public void addPutstatic(String classname, String fieldName, String desc) { public void addPutstatic(String classname, String fieldName, String desc) {

+ 0
- 1
src/main/javassist/bytecode/Descriptor.java View File



/** /**
* Returns the first character of the current element. * Returns the first character of the current element.
* @return
*/ */
public char currentChar() { return desc.charAt(curPos); } public char currentChar() { return desc.charAt(curPos); }



+ 1
- 1
src/main/javassist/bytecode/annotation/package.html View File

<html> <html>
<body> <body>
Annotations API.
Bytecode-level Annotations API.


<p>This package provides low-level API for editing annotations attributes. <p>This package provides low-level API for editing annotations attributes.



+ 1
- 1
src/main/javassist/expr/MethodCall.java View File

* The method signature is represented by a character string * The method signature is represented by a character string
* called method descriptor, which is defined in the JVM specification. * called method descriptor, which is defined in the JVM specification.
* *
* @see javassist.CtBehavior.getSignature()
* @see javassist.CtBehavior#getSignature()
* @see javassist.bytecode.Descriptor * @see javassist.bytecode.Descriptor
* @since 3.1 * @since 3.1
*/ */

+ 1
- 1
src/main/javassist/tools/package.html View File

<html> <html>
<body> <body>
Utility classes.
Covenient tools.


</body> </body>
</html> </html>

src/main/javassist/reflect/CannotCreateException.java → src/main/javassist/tools/reflect/CannotCreateException.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


/** /**
* Signals that <code>ClassMetaobject.newInstance()</code> fails. * Signals that <code>ClassMetaobject.newInstance()</code> fails.

src/main/javassist/reflect/CannotInvokeException.java → src/main/javassist/tools/reflect/CannotInvokeException.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.IllegalAccessException; import java.lang.IllegalAccessException;
* Thrown when method invocation using the reflection API has thrown * Thrown when method invocation using the reflection API has thrown
* an exception. * an exception.
* *
* @see javassist.reflect.Metaobject#trapMethodcall(int, Object[])
* @see javassist.reflect.ClassMetaobject#trapMethodcall(int, Object[])
* @see javassist.reflect.ClassMetaobject#invoke(Object, int, Object[])
* @see javassist.tools.reflect.Metaobject#trapMethodcall(int, Object[])
* @see javassist.tools.reflect.ClassMetaobject#trapMethodcall(int, Object[])
* @see javassist.tools.reflect.ClassMetaobject#invoke(Object, int, Object[])
*/ */
public class CannotInvokeException extends RuntimeException { public class CannotInvokeException extends RuntimeException {



src/main/javassist/reflect/CannotReflectException.java → src/main/javassist/tools/reflect/CannotReflectException.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


import javassist.CannotCompileException; import javassist.CannotCompileException;


* either ClassMetaobject or Metaobject. * either ClassMetaobject or Metaobject.
* *
* @author Brett Randall * @author Brett Randall
* @see javassist.reflect.Reflection#makeReflective(CtClass,CtClass,CtClass)
* @see javassist.tools.reflect.Reflection#makeReflective(CtClass,CtClass,CtClass)
* @see javassist.CannotCompileException * @see javassist.CannotCompileException
*/ */
public class CannotReflectException extends CannotCompileException { public class CannotReflectException extends CannotCompileException {

src/main/javassist/reflect/ClassMetaobject.java → src/main/javassist/tools/reflect/ClassMetaobject.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


import java.lang.reflect.*; import java.lang.reflect.*;
import java.util.Arrays; import java.util.Arrays;
* <ul><pre>ClassMetaobject cm = ((Metalevel)reflectiveObject)._getClass(); * <ul><pre>ClassMetaobject cm = ((Metalevel)reflectiveObject)._getClass();
* </pre></ul> * </pre></ul>
* *
* @see javassist.reflect.Metaobject
* @see javassist.reflect.Metalevel
* @see javassist.tools.reflect.Metaobject
* @see javassist.tools.reflect.Metalevel
*/ */
public class ClassMetaobject implements Serializable { public class ClassMetaobject implements Serializable {
/** /**

src/main/javassist/reflect/Compiler.java → src/main/javassist/tools/reflect/Compiler.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


import javassist.CtClass; import javassist.CtClass;
import javassist.ClassPool; import javassist.ClassPool;
* <p>This translator directly modifies class files on a local disk so that * <p>This translator directly modifies class files on a local disk so that
* the classes represented by those class files are reflective. * the classes represented by those class files are reflective.
* After the modification, the class files can be run with the standard JVM * After the modification, the class files can be run with the standard JVM
* without <code>javassist.reflect.Loader</code>
* without <code>javassist.tools.reflect.Loader</code>
* or any other user-defined class loader. * or any other user-defined class loader.
* *
* <p>The modified class files are given as the command-line parameters, * <p>The modified class files are given as the command-line parameters,
* <p>Note that if the super class is also made reflective, it must be done * <p>Note that if the super class is also made reflective, it must be done
* before the sub class. * before the sub class.
* *
* @see javassist.reflect.Metaobject
* @see javassist.reflect.ClassMetaobject
* @see javassist.reflect.Reflection
* @see javassist.tools.reflect.Metaobject
* @see javassist.tools.reflect.ClassMetaobject
* @see javassist.tools.reflect.Reflection
*/ */
public class Compiler { public class Compiler {


String metaobj, classobj; String metaobj, classobj;


if (entries[i].metaobject == null) if (entries[i].metaobject == null)
metaobj = "javassist.reflect.Metaobject";
metaobj = "javassist.tools.reflect.Metaobject";
else else
metaobj = entries[i].metaobject; metaobj = entries[i].metaobject;


if (entries[i].classobject == null) if (entries[i].classobject == null)
classobj = "javassist.reflect.ClassMetaobject";
classobj = "javassist.tools.reflect.ClassMetaobject";
else else
classobj = entries[i].classobject; classobj = entries[i].classobject;


} }


private static void help(PrintStream out) { private static void help(PrintStream out) {
out.println("Usage: java javassist.reflect.Compiler");
out.println("Usage: java javassist.tools.reflect.Compiler");
out.println(" (<class> [-m <metaobject>] [-c <class metaobject>])+"); out.println(" (<class> [-m <metaobject>] [-c <class metaobject>])+");
} }
} }

src/main/javassist/reflect/Loader.java → src/main/javassist/tools/reflect/Loader.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


import javassist.CannotCompileException; import javassist.CannotCompileException;
import javassist.NotFoundException; import javassist.NotFoundException;
* <ul><pre> * <ul><pre>
* public class Main { * public class Main {
* public static void main(String[] args) throws Throwable { * public static void main(String[] args) throws Throwable {
* javassist.reflect.Loader cl
* = (javassist.reflect.Loader)Main.class.getClassLoader();
* javassist.tools.reflect.Loader cl
* = (javassist.tools.reflect.Loader)Main.class.getClassLoader();
* cl.makeReflective("Person", "MyMetaobject", * cl.makeReflective("Person", "MyMetaobject",
* "javassist.reflect.ClassMetaobject");
* "javassist.tools.reflect.ClassMetaobject");
* cl.run("MyApp", args); * cl.run("MyApp", args);
* } * }
* } * }
* *
* <p>Then run this program as follows: * <p>Then run this program as follows:
* *
* <ul><pre>% java javassist.reflect.Loader Main arg1, ...</pre></ul>
* <ul><pre>% java javassist.tools.reflect.Loader Main arg1, ...</pre></ul>
* *
* <p>This command runs <code>Main.main()</code> with <code>arg1</code>, ... * <p>This command runs <code>Main.main()</code> with <code>arg1</code>, ...
* and <code>Main.main()</code> runs <code>MyApp.main()</code> with * and <code>Main.main()</code> runs <code>MyApp.main()</code> with
* <ul><pre> * <ul><pre>
* public class Main2 { * public class Main2 {
* public static void main(String[] args) throws Throwable { * public static void main(String[] args) throws Throwable {
* javassist.reflect.Loader cl = new javassist.reflect.Loader();
* javassist.tools.reflect.Loader cl = new javassist.tools.reflect.Loader();
* cl.makeReflective("Person", "MyMetaobject", * cl.makeReflective("Person", "MyMetaobject",
* "javassist.reflect.ClassMetaobject");
* "javassist.tools.reflect.ClassMetaobject");
* cl.run("MyApp", args); * cl.run("MyApp", args);
* } * }
* } * }
* <ul><pre>% java Main2 arg1, ...</pre></ul> * <ul><pre>% java Main2 arg1, ...</pre></ul>
* *
* <p>The difference from the former one is that the class <code>Main</code> * <p>The difference from the former one is that the class <code>Main</code>
* is loaded by <code>javassist.reflect.Loader</code> whereas the class
* is loaded by <code>javassist.tools.reflect.Loader</code> whereas the class
* <code>Main2</code> is not. Thus, <code>Main</code> belongs * <code>Main2</code> is not. Thus, <code>Main</code> belongs
* to the same name space (security domain) as <code>MyApp</code> * to the same name space (security domain) as <code>MyApp</code>
* whereas <code>Main2</code> does not; <code>Main2</code> belongs * whereas <code>Main2</code> does not; <code>Main2</code> belongs
* to the same name space as <code>javassist.reflect.Loader</code>.
* to the same name space as <code>javassist.tools.reflect.Loader</code>.
* For more details, * For more details,
* see the notes in the manual page of <code>javassist.Loader</code>. * see the notes in the manual page of <code>javassist.Loader</code>.
* *
* javassist.Loader cl * javassist.Loader cl
* = new javassist.Loader(ClassPool.getDefault(reflection)); * = new javassist.Loader(ClassPool.getDefault(reflection));
* reflection.makeReflective("Person", "MyMetaobject", * reflection.makeReflective("Person", "MyMetaobject",
* "javassist.reflect.ClassMetaobject");
* "javassist.tools.reflect.ClassMetaobject");
* cl.run("MyApp", args); * cl.run("MyApp", args);
* } * }
* } * }
* *
* <p><b>Note:</b> * <p><b>Note:</b>
* *
* <p><code>javassist.reflect.Loader</code> does not make a class reflective
* <p><code>javassist.tools.reflect.Loader</code> does not make a class reflective
* if that class is in a <code>java.*</code> or * if that class is in a <code>java.*</code> or
* <code>javax.*</code> pacakge because of the specifications * <code>javax.*</code> pacakge because of the specifications
* on the class loading algorithm of Java. The JVM does not allow to * on the class loading algorithm of Java. The JVM does not allow to
* load such a system class with a user class loader. * load such a system class with a user class loader.
* *
* <p>To avoid this limitation, those classes should be statically * <p>To avoid this limitation, those classes should be statically
* modified with <code>javassist.reflect.Compiler</code> and the original
* modified with <code>javassist.tools.reflect.Compiler</code> and the original
* class files should be replaced. * class files should be replaced.
* *
* @see javassist.reflect.Reflection
* @see javassist.reflect.Compiler
* @see javassist.tools.reflect.Reflection
* @see javassist.tools.reflect.Compiler
* @see javassist.Loader * @see javassist.Loader
*/ */
public class Loader extends javassist.Loader { public class Loader extends javassist.Loader {
*/ */
public Loader() throws CannotCompileException, NotFoundException { public Loader() throws CannotCompileException, NotFoundException {
super(); super();
delegateLoadingOf("javassist.reflect.Loader");
delegateLoadingOf("javassist.tools.reflect.Loader");


reflection = new Reflection(); reflection = new Reflection();
ClassPool pool = ClassPool.getDefault(); ClassPool pool = ClassPool.getDefault();
* <code>ClassMetaobject</code>. * <code>ClassMetaobject</code>.
* @return <code>false</code> if the class is already reflective. * @return <code>false</code> if the class is already reflective.
* *
* @see javassist.reflect.Metaobject
* @see javassist.reflect.ClassMetaobject
* @see javassist.tools.reflect.Metaobject
* @see javassist.tools.reflect.ClassMetaobject
*/ */
public boolean makeReflective(String clazz, public boolean makeReflective(String clazz,
String metaobject, String metaclass) String metaobject, String metaclass)

src/main/javassist/reflect/Metalevel.java → src/main/javassist/tools/reflect/Metalevel.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


/** /**
* An interface to access a metaobject and a class metaobject. * An interface to access a metaobject and a class metaobject.

src/main/javassist/reflect/Metaobject.java → src/main/javassist/tools/reflect/Metaobject.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.io.Serializable; import java.io.Serializable;
* <ul><pre>Metaobject m = ((Metalevel)reflectiveObject)._getMetaobject(); * <ul><pre>Metaobject m = ((Metalevel)reflectiveObject)._getMetaobject();
* </pre></ul> * </pre></ul>
* *
* @see javassist.reflect.ClassMetaobject
* @see javassist.reflect.Metalevel
* @see javassist.tools.reflect.ClassMetaobject
* @see javassist.tools.reflect.Metalevel
*/ */
public class Metaobject implements Serializable { public class Metaobject implements Serializable {
protected ClassMetaobject classmetaobject; protected ClassMetaobject classmetaobject;
/** /**
* Obtains the class metaobject associated with this metaobject. * Obtains the class metaobject associated with this metaobject.
* *
* @see javassist.reflect.ClassMetaobject
* @see javassist.tools.reflect.ClassMetaobject
*/ */
public final ClassMetaobject getClassMetaobject() { public final ClassMetaobject getClassMetaobject() {
return classmetaobject; return classmetaobject;

src/main/javassist/reflect/Reflection.java → src/main/javassist/tools/reflect/Reflection.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


import javassist.*; import javassist.*;
import javassist.CtMethod.ConstParameter; import javassist.CtMethod.ConstParameter;
* } * }
* </pre></ul> * </pre></ul>
* *
* @see javassist.reflect.ClassMetaobject
* @see javassist.reflect.Metaobject
* @see javassist.reflect.Loader
* @see javassist.reflect.Compiler
* @see javassist.tools.reflect.ClassMetaobject
* @see javassist.tools.reflect.Metaobject
* @see javassist.tools.reflect.Loader
* @see javassist.tools.reflect.Compiler
*/ */
public class Reflection implements Translator { public class Reflection implements Translator {


static final String readPrefix = "_r_"; static final String readPrefix = "_r_";
static final String writePrefix = "_w_"; static final String writePrefix = "_w_";


static final String metaobjectClassName = "javassist.reflect.Metaobject";
static final String metaobjectClassName = "javassist.tools.reflect.Metaobject";
static final String classMetaobjectClassName static final String classMetaobjectClassName
= "javassist.reflect.ClassMetaobject";
= "javassist.tools.reflect.ClassMetaobject";


protected CtMethod trapMethod, trapStaticMethod; protected CtMethod trapMethod, trapStaticMethod;
protected CtMethod trapRead, trapWrite; protected CtMethod trapRead, trapWrite;
public void start(ClassPool pool) throws NotFoundException { public void start(ClassPool pool) throws NotFoundException {
classPool = pool; classPool = pool;
final String msg final String msg
= "javassist.reflect.Sample is not found or broken.";
= "javassist.tools.reflect.Sample is not found or broken.";
try { try {
CtClass c = classPool.get("javassist.reflect.Sample");
CtClass c = classPool.get("javassist.tools.reflect.Sample");
trapMethod = c.getDeclaredMethod("trap"); trapMethod = c.getDeclaredMethod("trap");
trapStaticMethod = c.getDeclaredMethod("trapStatic"); trapStaticMethod = c.getDeclaredMethod("trapStatic");
trapRead = c.getDeclaredMethod("trapRead"); trapRead = c.getDeclaredMethod("trapRead");
* @param metaclass the class name of the class metaobject. * @param metaclass the class name of the class metaobject.
* @return <code>false</code> if the class is already reflective. * @return <code>false</code> if the class is already reflective.
* *
* @see javassist.reflect.Metaobject
* @see javassist.reflect.ClassMetaobject
* @see javassist.tools.reflect.Metaobject
* @see javassist.tools.reflect.ClassMetaobject
*/ */
public boolean makeReflective(String classname, public boolean makeReflective(String classname,
String metaobject, String metaclass) String metaobject, String metaclass)
* <code>ClassMetaobject</code>. * <code>ClassMetaobject</code>.
* @return <code>false</code> if the class is already reflective. * @return <code>false</code> if the class is already reflective.
* *
* @see javassist.reflect.Metaobject
* @see javassist.reflect.ClassMetaobject
* @see javassist.tools.reflect.Metaobject
* @see javassist.tools.reflect.ClassMetaobject
*/ */
public boolean makeReflective(Class clazz, public boolean makeReflective(Class clazz,
Class metaobject, Class metaclass) Class metaobject, Class metaclass)
* <code>ClassMetaobject</code>. * <code>ClassMetaobject</code>.
* @return <code>false</code> if the class is already reflective. * @return <code>false</code> if the class is already reflective.
* *
* @see javassist.reflect.Metaobject
* @see javassist.reflect.ClassMetaobject
* @see javassist.tools.reflect.Metaobject
* @see javassist.tools.reflect.ClassMetaobject
*/ */
public boolean makeReflective(CtClass clazz, public boolean makeReflective(CtClass clazz,
CtClass metaobject, CtClass metaclass) CtClass metaobject, CtClass metaclass)
else else
clazz.setAttribute("Reflective", new byte[0]); clazz.setAttribute("Reflective", new byte[0]);


CtClass mlevel = classPool.get("javassist.reflect.Metalevel");
CtClass mlevel = classPool.get("javassist.tools.reflect.Metalevel");
boolean addMeta = !clazz.subtypeOf(mlevel); boolean addMeta = !clazz.subtypeOf(mlevel);
if (addMeta) if (addMeta)
clazz.addInterface(mlevel); clazz.addInterface(mlevel);


CtField f; CtField f;
if (addMeta) { if (addMeta) {
f = new CtField(classPool.get("javassist.reflect.Metaobject"),
f = new CtField(classPool.get("javassist.tools.reflect.Metaobject"),
metaobjectField, clazz); metaobjectField, clazz);
f.setModifiers(Modifier.PROTECTED); f.setModifiers(Modifier.PROTECTED);
clazz.addField(f, CtField.Initializer.byNewWithParams(metaobject)); clazz.addField(f, CtField.Initializer.byNewWithParams(metaobject));
clazz.addMethod(CtNewMethod.setter(metaobjectSetter, f)); clazz.addMethod(CtNewMethod.setter(metaobjectSetter, f));
} }


f = new CtField(classPool.get("javassist.reflect.ClassMetaobject"),
f = new CtField(classPool.get("javassist.tools.reflect.ClassMetaobject"),
classobjectField, clazz); classobjectField, clazz);
f.setModifiers(Modifier.PRIVATE | Modifier.STATIC); f.setModifiers(Modifier.PRIVATE | Modifier.STATIC);
clazz.addField(f, CtField.Initializer.byNew(metaclass, clazz.addField(f, CtField.Initializer.byNew(metaclass,

src/main/javassist/reflect/Sample.java → src/main/javassist/tools/reflect/Sample.java View File

* License. * License.
*/ */


package javassist.reflect;
package javassist.tools.reflect;


/** /**
* A template used for defining a reflective class. * A template used for defining a reflective class.

src/main/javassist/reflect/package.html → src/main/javassist/tools/reflect/package.html View File


src/main/javassist/rmi/AppletServer.java → src/main/javassist/tools/rmi/AppletServer.java View File

* License. * License.
*/ */


package javassist.rmi;
package javassist.tools.rmi;


import java.io.*; import java.io.*;
import javassist.web.*;

import javassist.tools.web.*;
import javassist.CannotCompileException; import javassist.CannotCompileException;
import javassist.NotFoundException; import javassist.NotFoundException;
import javassist.ClassPool; import javassist.ClassPool;
* If the classes of the exported objects are requested by the client-side * If the classes of the exported objects are requested by the client-side
* JVM, this web server sends proxy classes for the requested classes. * JVM, this web server sends proxy classes for the requested classes.
* *
* @see javassist.rmi.ObjectImporter
* @see javassist.tools.rmi.ObjectImporter
*/ */
public class AppletServer extends Webserver { public class AppletServer extends Webserver {
private StubGenerator stubGen; private StubGenerator stubGen;
* @param obj the exported object. * @param obj the exported object.
* @return the object identifier * @return the object identifier
* *
* @see javassist.rmi.ObjectImporter#lookupObject(String)
* @see javassist.tools.rmi.ObjectImporter#lookupObject(String)
*/ */
public synchronized int exportObject(String name, Object obj) public synchronized int exportObject(String name, Object obj)
throws CannotCompileException throws CannotCompileException

src/main/javassist/rmi/ObjectImporter.java → src/main/javassist/tools/rmi/ObjectImporter.java View File

* License. * License.
*/ */


package javassist.rmi;
package javassist.tools.rmi;


import java.io.*; import java.io.*;
import java.net.*; import java.net.*;


/** /**
* The object importer enables applets to call a method on a remote * The object importer enables applets to call a method on a remote
* object running on the <code>Webserver</code>.
* object running on the <code>Webserver</code> (the <b>main</b> class of this
* package).
* *
* <p>To access the remote * <p>To access the remote
* object, the applet first calls <code>lookupObject()</code> and * object, the applet first calls <code>lookupObject()</code> and
* to catch the exception. However, good programs should catch * to catch the exception. However, good programs should catch
* the <code>RuntimeException</code>. * the <code>RuntimeException</code>.
* *
* @see javassist.rmi.AppletServer
* @see javassist.rmi.RemoteException
* @see javassist.web.Viewer
* @see javassist.tools.rmi.AppletServer
* @see javassist.tools.rmi.RemoteException
* @see javassist.tools.web.Viewer
*/ */
public class ObjectImporter implements java.io.Serializable { public class ObjectImporter implements java.io.Serializable {
private final byte[] endofline = { 0x0d, 0x0a }; private final byte[] endofline = { 0x0d, 0x0a };
/** /**
* Constructs an object importer. * Constructs an object importer.
* *
* <p>If you run a program with <code>javassist.web.Viewer</code>,
* <p>If you run a program with <code>javassist.tools.web.Viewer</code>,
* you can construct an object importer as follows: * you can construct an object importer as follows:
* *
* <ul><pre> * <ul><pre>
* ObjectImporter oi = new ObjectImporter(v.getServer(), v.getPort()); * ObjectImporter oi = new ObjectImporter(v.getServer(), v.getPort());
* </pre></ul> * </pre></ul>
* *
* @see javassist.web.Viewer
* @see javassist.tools.web.Viewer
*/ */
public ObjectImporter(String servername, int port) { public ObjectImporter(String servername, int port) {
this.orgServername = this.servername = servername; this.orgServername = this.servername = servername;

src/main/javassist/rmi/ObjectNotFoundException.java → src/main/javassist/tools/rmi/ObjectNotFoundException.java View File

* License. * License.
*/ */


package javassist.rmi;
package javassist.tools.rmi;


public class ObjectNotFoundException extends Exception { public class ObjectNotFoundException extends Exception {
public ObjectNotFoundException(String name) { public ObjectNotFoundException(String name) {

src/main/javassist/rmi/Proxy.java → src/main/javassist/tools/rmi/Proxy.java View File

* License. * License.
*/ */


package javassist.rmi;
package javassist.tools.rmi;


/** /**
* An interface implemented by proxy classes. * An interface implemented by proxy classes.
* *
* @see javassist.rmi.StubGenerator
* @see javassist.tools.rmi.StubGenerator
*/ */
public interface Proxy { public interface Proxy {
int _getObjectId(); int _getObjectId();

src/main/javassist/rmi/RemoteException.java → src/main/javassist/tools/rmi/RemoteException.java View File

* License. * License.
*/ */


package javassist.rmi;
package javassist.tools.rmi;


/** /**
* <code>RemoteException</code> represents any exception thrown * <code>RemoteException</code> represents any exception thrown

src/main/javassist/rmi/RemoteRef.java → src/main/javassist/tools/rmi/RemoteRef.java View File

* License. * License.
*/ */


package javassist.rmi;
package javassist.tools.rmi;


/** /**
* Remote reference. This class is internally used for sending a remote * Remote reference. This class is internally used for sending a remote

src/main/javassist/rmi/Sample.java → src/main/javassist/tools/rmi/Sample.java View File

* License. * License.
*/ */


package javassist.rmi;
package javassist.tools.rmi;


/** /**
* A template used for defining a proxy class. * A template used for defining a proxy class.

src/main/javassist/rmi/StubGenerator.java → src/main/javassist/tools/rmi/StubGenerator.java View File

* License. * License.
*/ */


package javassist.rmi;
package javassist.tools.rmi;


import javassist.*; import javassist.*;
import java.lang.reflect.Method; import java.lang.reflect.Method;
private static final String fieldImporter = "importer"; private static final String fieldImporter = "importer";
private static final String fieldObjectId = "objectId"; private static final String fieldObjectId = "objectId";
private static final String accessorObjectId = "_getObjectId"; private static final String accessorObjectId = "_getObjectId";
private static final String sampleClass = "javassist.rmi.Sample";
private static final String sampleClass = "javassist.tools.rmi.Sample";


private ClassPool classPool; private ClassPool classPool;
private Hashtable proxyClasses; private Hashtable proxyClasses;
forwardStaticMethod = c.getDeclaredMethod("forwardStatic"); forwardStaticMethod = c.getDeclaredMethod("forwardStatic");


proxyConstructorParamTypes proxyConstructorParamTypes
= pool.get(new String[] { "javassist.rmi.ObjectImporter",
= pool.get(new String[] { "javassist.tools.rmi.ObjectImporter",
"int" }); "int" });
interfacesForProxy interfacesForProxy
= pool.get(new String[] { "java.io.Serializable", = pool.get(new String[] { "java.io.Serializable",
"javassist.rmi.Proxy" });
"javassist.tools.rmi.Proxy" });
exceptionForProxy exceptionForProxy
= new CtClass[] { pool.get("javassist.rmi.RemoteException") };
= new CtClass[] { pool.get("javassist.tools.rmi.RemoteException") };
} }


/** /**
proxy.setInterfaces(interfacesForProxy); proxy.setInterfaces(interfacesForProxy);


CtField f CtField f
= new CtField(classPool.get("javassist.rmi.ObjectImporter"),
= new CtField(classPool.get("javassist.tools.rmi.ObjectImporter"),
fieldImporter, proxy); fieldImporter, proxy);
f.setModifiers(Modifier.PRIVATE); f.setModifiers(Modifier.PRIVATE);
proxy.addField(f, CtField.Initializer.byParameter(0)); proxy.addField(f, CtField.Initializer.byParameter(0));

src/main/javassist/rmi/package.html → src/main/javassist/tools/rmi/package.html View File


src/main/javassist/web/BadHttpRequest.java → src/main/javassist/tools/web/BadHttpRequest.java View File

* License. * License.
*/ */


package javassist.web;
package javassist.tools.web;


/** /**
* Thrown when receiving an invalid HTTP request. * Thrown when receiving an invalid HTTP request.

src/main/javassist/web/Viewer.java → src/main/javassist/tools/web/Viewer.java View File

* License. * License.
*/ */


package javassist.web;
package javassist.tools.web;


import java.io.*; import java.io.*;
import java.net.*; import java.net.*;
* *
* <p>To run, you should type: * <p>To run, you should type:
* *
* <ul><code>% java javassist.web.Viewer <i>host port</i> Main arg1, ...</code></ul>
* <ul><code>% java javassist.tools.web.Viewer <i>host port</i> Main arg1, ...</code></ul>
* *
* <p>This command calls <code>Main.main()</code> with <code>arg1,...</code> * <p>This command calls <code>Main.main()</code> with <code>arg1,...</code>
* All classes including <code>Main</code> are fetched from * All classes including <code>Main</code> are fetched from
} }
else else
System.err.println( System.err.println(
"Usage: java javassist.web.Viewer <host> <port> class [args ...]");
"Usage: java javassist.tools.web.Viewer <host> <port> class [args ...]");
} }


/** /**
protected Class findClass(String name) throws ClassNotFoundException { protected Class findClass(String name) throws ClassNotFoundException {
Class c = null; Class c = null;
if (name.startsWith("java.") || name.startsWith("javax.") if (name.startsWith("java.") || name.startsWith("javax.")
|| name.equals("javassist.web.Viewer"))
|| name.equals("javassist.tools.web.Viewer"))
c = findSystemClass(name); c = findSystemClass(name);


if (c == null) if (c == null)

src/main/javassist/web/Webserver.java → src/main/javassist/tools/web/Webserver.java View File

* License. * License.
*/ */


package javassist.web;
package javassist.tools.web;


import java.net.*; import java.net.*;
import java.io.*; import java.io.*;
} }
else else
System.err.println( System.err.println(
"Usage: java javassist.web.Webserver <port number>");
"Usage: java javassist.tools.web.Webserver <port number>");
} }


/** /**

src/main/javassist/web/package.html → src/main/javassist/tools/web/package.html View File


src/main/javassist/tools/HotSwapper.java → src/main/javassist/util/HotSwapper.java View File

* License. * License.
*/ */


package javassist.tools;
package javassist.util;


import com.sun.jdi.*; import com.sun.jdi.*;
import com.sun.jdi.connect.*; import com.sun.jdi.connect.*;
private Trigger trigger; private Trigger trigger;


private static final String HOST_NAME = "localhost"; private static final String HOST_NAME = "localhost";
private static final String TRIGGER_NAME = "javassist.tools.Trigger";
private static final String TRIGGER_NAME = Trigger.class.getName();


/** /**
* Connects to the JVM. * Connects to the JVM.

+ 5
- 0
src/main/javassist/util/package.html View File

<html>
<body>
Utility classes.
</body>
</html>

+ 182
- 0
src/main/javassist/util/proxy/FactoryHelper.java View File

/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/

package javassist.util.proxy;

import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import javassist.CannotCompileException;
import javassist.bytecode.ClassFile;

/**
* A helper class for implementing <code>ProxyFactory</code>.
* The users of <code>ProxyFactory</code> do not have to see this class.
*
* @see ProxyFactory
*/
public class FactoryHelper {
/**
* Returns an index for accessing arrays in this class.
*
* @throws RuntimeException if a given type is not a primitive type.
*/
public static final int typeIndex(Class type) {
Class[] list = primitiveTypes;
int n = list.length;
for (int i = 0; i < n; i++)
if (list[i] == type)
return i;

throw new RuntimeException("bad type:" + type.getName());
}

/**
* <code>Class</code> objects representing primitive types.
*/
public static final Class[] primitiveTypes = {
Boolean.TYPE, Byte.TYPE, Character.TYPE, Short.TYPE, Integer.TYPE,
Long.TYPE, Float.TYPE, Double.TYPE, Void.TYPE
};

/**
* The fully-qualified names of wrapper classes for primitive types.
*/
public static final String[] wrapperTypes = {
"java.lang.Boolean", "java.lang.Byte", "java.lang.Character",
"java.lang.Short", "java.lang.Integer", "java.lang.Long",
"java.lang.Float", "java.lang.Double", "java.lang.Void"
};

/**
* The descriptors of the constructors of wrapper classes.
*/
public static final String[] wrapperDesc = {
"(Z)V", "(B)V", "(C)V", "(S)V", "(I)V", "(J)V",
"(F)V", "(D)V"
};

/**
* The names of methods for obtaining a primitive value
* from a wrapper object. For example, <code>intValue()</code>
* is such a method for obtaining an integer value from a
* <code>java.lang.Integer</code> object.
*/
public static final String[] unwarpMethods = {
"booleanValue", "byteValue", "charValue", "shortValue",
"intValue", "longValue", "floatValue", "doubleValue"
};

/**
* The descriptors of the unwrapping methods contained
* in <code>unwrapMethods</code>.
*/
public static final String[] unwrapDesc = {
"()Z", "()B", "()C", "()S", "()I", "()J", "()F", "()D"
};

/**
* The data size of primitive types. <code>long</code>
* and <code>double</code> are 2; the others are 1.
*/
public static final int[] dataSize = {
1, 1, 1, 1, 1, 2, 1, 2
};

/**
* Loads a class file by a given class loader.
*/
public static Class toClass(ClassFile cf, ClassLoader loader)
throws CannotCompileException
{
try {
byte[] b = toBytecode(cf);
Class cl = Class.forName("java.lang.ClassLoader");
java.lang.reflect.Method method = cl.getDeclaredMethod(
"defineClass", new Class[] { String.class, byte[].class,
Integer.TYPE, Integer.TYPE });
method.setAccessible(true);
Object[] args = new Object[] { cf.getName(), b, new Integer(0),
new Integer(b.length) };
Class clazz = (Class)method.invoke(loader, args);
method.setAccessible(false);
return clazz;
}
catch (RuntimeException e) {
throw e;
}
catch (java.lang.reflect.InvocationTargetException e) {
throw new CannotCompileException(e.getTargetException());
}
catch (Exception e) {
throw new CannotCompileException(e);
}
}

private static byte[] toBytecode(ClassFile cf) throws IOException {
ByteArrayOutputStream barray = new ByteArrayOutputStream();
DataOutputStream out = new DataOutputStream(barray);
try {
cf.write(out);
}
finally {
out.close();
}

return barray.toByteArray();
}

/**
* Writes a class file.
*/
public static void writeFile(ClassFile cf, String directoryName)
throws CannotCompileException {
try {
writeFile0(cf, directoryName);
}
catch (IOException e) {
throw new CannotCompileException(e);
}
}

private static void writeFile0(ClassFile cf, String directoryName)
throws CannotCompileException, IOException {
String classname = cf.getName();
String filename = directoryName + File.separatorChar
+ classname.replace('.', File.separatorChar) + ".class";
int pos = filename.lastIndexOf(File.separatorChar);
if (pos > 0) {
String dir = filename.substring(0, pos);
if (!dir.equals("."))
new File(dir).mkdirs();
}

DataOutputStream out = new DataOutputStream(new BufferedOutputStream(
new FileOutputStream(filename)));
try {
cf.write(out);
}
catch (IOException e) {
throw e;
}
finally {
out.close();
}
}
}

+ 30
- 0
src/main/javassist/util/proxy/MethodFilter.java View File

/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist.util.proxy;
import java.lang.reflect.Method;
/**
* Selector of the methods implemented by a handler.
*
* @see ProxyFactory#setFilter(MethodFilter)
*/
public interface MethodFilter {
/**
* Returns true if the given method is implemented by a handler.
*/
boolean isHandled(Method m);
}

+ 48
- 0
src/main/javassist/util/proxy/MethodHandler.java View File

/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist.util.proxy;
import java.lang.reflect.Method;
/**
* The interface implemented by the invocation handler of a proxy
* instance.
*
* @see ProxyFactory#setHandler(MethodHandler)
*/
public interface MethodHandler {
/**
* Is called when a method is invoked on a proxy instance associated
* with this handler. This method must process that method invocation.
*
* @param self the proxy instance.
* @param thisMethod the overridden method declared in the super
* class or interface.
* @param proceed the forwarder method for invoking the overridden
* method. It is null if the overridden mehtod is
* abstract or declared in the interface.
* @param args an array of objects containing the values of
* the arguments passed in the method invocation
* on the proxy instance. If a parameter type is
* a primitive type, the type of the array element
* is a wrapper class.
* @return the resulting value of the method invocation.
*
* @throws Exception if the method invocation fails.
*/
Object invoke(Object self, Method thisMethod, Method proceed,
Object[] args) throws Exception;
}

+ 699
- 0
src/main/javassist/util/proxy/ProxyFactory.java View File

/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist.util.proxy;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Constructor;
import java.lang.reflect.Member;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javassist.CannotCompileException;
import javassist.bytecode.*;
/**
* Factory of dynamic proxy classes.
*
* <p>This factory generates a class that extends the given super class and implements
* the given interfaces. The calls of the methods inherited from the super class are
* forwarded and then <code>invoke()</code> is called on the method handler
* associated with the generated class. The calls of the methods from the interfaces
* are also forwarded to the method handler.
*
* <p>For example, if the following code is executed,
*
* <ul><pre>
* ProxyFactory f = new ProxyFactory();
* f.setSuperclass(Foo.class);
* MethodHandler mi = new MethodHandler() {
* public Object invoke(Object self, Method m, Method proceed,
* Object[] args) throws Exception {
* System.out.println("Name: " + m.getName());
* proceed.invoke(self, args); // execute the original method.
* }
* };
* f.setHandler(mi);
* Class c = f.createClass();
* Foo foo = (Foo)c.newInstance();
* </pre></ul>
*
* <p>Then, the following method call will be forwarded to MethodHandler
* <code>mi</code> and prints a message before executing the originally called method
* <code>bar()</code> in <code>Foo</code>.
*
* <ul><pre>
* foo.bar();
* </pre></ul>
*
* <p>To change the method handler during runtime,
* execute the following code:
*
* <ul><pre>
* MethodHandler mi2 = ... ; // another handler
* ((ProxyObject)foo).setHandler(mi2);
* </pre></ul>
*
* <p>Here is an example of method handler. It does not execute
* anything except invoking the original method:
*
* <ul><pre>
* class SimpleHandler implements MethodHandler {
* public Object invoke(Object self, Method m,
* Method proceed, Object[] args) throws Exception {
* return proceed.invoke(self, args);
* }
* }
* </pre></ul>
*
* @see MethodHandler
* @since 3.1
*/
public class ProxyFactory {
private Class superClass;
private Class[] interfaces;
private MethodFilter methodFilter;
private MethodHandler handler;
private Class thisClass;
/**
* If the value of this variable is not null, the class file of
* the generated proxy class is written under the directory specified
* by this variable. For example, if the value is
* <code>"."</code>, then the class file is written under the current
* directory. This method is for debugging.
*
* <p>The default value is null.
*/
public String writeDirectory;
private static final Class OBJECT_TYPE = Object.class;
private static final String HOLDER = "_methods_";
private static final String HOLDER_TYPE = "[Ljava/lang/reflect/Method;";
private static final String HANDLER = "handler";
private static final String DEFAULT_INTERCEPTOR = "default_interceptor";
private static final String HANDLER_TYPE
= 'L' + MethodHandler.class.getName().replace('.', '/') + ';';
private static final String HANDLER_SETTER = "setHandler";
private static final String HANDLER_SETTER_TYPE = "(" + HANDLER_TYPE + ")V";
/**
* Constructs a factory of proxy class.
*/
public ProxyFactory() {
superClass = null;
interfaces = null;
methodFilter = null;
handler = new MethodHandler() {
public Object invoke(Object self, Method m,
Method proceed, Object[] args)
throws Exception
{
return proceed.invoke(self, args);
}
};
thisClass = null;
writeDirectory = null;
}
/**
* Sets the super class of a proxy class.
*/
public void setSuperclass(Class clazz) {
superClass = clazz;
}
/**
* Sets the interfaces of a proxy class.
*/
public void setInterfaces(Class[] ifs) {
interfaces = ifs;
}
/**
* Sets a filter that selects the methods that will be controlled by a handler.
*/
public void setFilter(MethodFilter mf) {
methodFilter = mf;
}
/**
* Generates a proxy class.
*/
public Class createClass() {
if (thisClass == null)
try {
ClassFile cf = make();
ClassLoader cl = getClassLoader();
if (writeDirectory != null)
FactoryHelper.writeFile(cf, writeDirectory);
thisClass = FactoryHelper.toClass(cf, cl);
setHandler();
}
catch (CannotCompileException e) {
throw new RuntimeException(e.getMessage(), e);
}
return thisClass;
}
protected ClassLoader getClassLoader() {
if (superClass != null && !superClass.getName().equals("java.lang.Object"))
return superClass.getClassLoader();
else if (interfaces != null && interfaces.length > 0)
return interfaces[0].getClassLoader();
else
return this.getClass().getClassLoader();
// return Thread.currentThread().getContextClassLoader();
}
/**
* Sets the default invocation handler. This invocation handler is shared
* among all the instances of a proxy class unless another is explicitly
* specified.
*/
public void setHandler(MethodHandler mi) {
handler = mi;
setHandler();
}
private void setHandler() {
if (thisClass != null && handler != null)
try {
Field f = thisClass.getField(DEFAULT_INTERCEPTOR);
f.setAccessible(true);
f.set(null, handler);
f.setAccessible(false);
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
private static int counter = 0;
private ClassFile make() throws CannotCompileException {
String superName, classname;
if (interfaces == null)
interfaces = new Class[0];
if (superClass == null) {
superClass = OBJECT_TYPE;
superName = superClass.getName();
classname = interfaces.length == 0 ? superName
: interfaces[0].getName();
}
else {
superName = superClass.getName();
classname = superName;
}
if (Modifier.isFinal(superClass.getModifiers()))
throw new CannotCompileException(superName + " is final");
// generate a proxy name.
classname = classname + "_$$_javassist_" + counter++;
if (classname.startsWith("java."))
classname = "org.javassist.tmp." + classname;
ClassFile cf = new ClassFile(false, classname, superName);
cf.setAccessFlags(AccessFlag.PUBLIC);
setInterfaces(cf, interfaces);
ConstPool pool = cf.getConstPool();
FieldInfo finfo = new FieldInfo(pool, DEFAULT_INTERCEPTOR, HANDLER_TYPE);
finfo.setAccessFlags(AccessFlag.PUBLIC | AccessFlag.STATIC);
cf.addField(finfo);
FieldInfo finfo2 = new FieldInfo(pool, HANDLER, HANDLER_TYPE);
finfo2.setAccessFlags(AccessFlag.PRIVATE);
cf.addField(finfo2);
HashMap allMethods = getMethods(superClass, interfaces);
int size = allMethods.size();
makeConstructors(classname, cf, pool, classname);
int s = overrideMethods(cf, pool, classname, allMethods);
addMethodsHolder(cf, pool, classname, s);
addSetter(classname, cf, pool);
thisClass = null;
return cf;
}
private static void setInterfaces(ClassFile cf, Class[] interfaces) {
String setterIntf = ProxyObject.class.getName();
String[] list;
if (interfaces == null || interfaces.length == 0)
list = new String[] { setterIntf };
else {
list = new String[interfaces.length + 1];
for (int i = 0; i < interfaces.length; i++)
list[i] = interfaces[i].getName();
list[interfaces.length] = setterIntf;
}
cf.setInterfaces(list);
}
private static void addMethodsHolder(ClassFile cf, ConstPool cp,
String classname, int size)
throws CannotCompileException
{
FieldInfo finfo = new FieldInfo(cp, HOLDER, HOLDER_TYPE);
finfo.setAccessFlags(AccessFlag.PRIVATE | AccessFlag.STATIC);
cf.addField(finfo);
MethodInfo minfo = new MethodInfo(cp, "<clinit>", "()V");
Bytecode code = new Bytecode(cp, 0, 0);
code.addIconst(size * 2);
code.addAnewarray("java.lang.reflect.Method");
code.addPutstatic(classname, HOLDER, HOLDER_TYPE);
code.addOpcode(Bytecode.RETURN);
minfo.setCodeAttribute(code.toCodeAttribute());
cf.addMethod(minfo);
}
private static void addSetter(String classname, ClassFile cf, ConstPool cp)
throws CannotCompileException
{
MethodInfo minfo = new MethodInfo(cp, HANDLER_SETTER,
HANDLER_SETTER_TYPE);
minfo.setAccessFlags(AccessFlag.PUBLIC);
Bytecode code = new Bytecode(cp, 2, 2);
code.addAload(0);
code.addAload(1);
code.addPutfield(classname, HANDLER, HANDLER_TYPE);
code.addOpcode(Bytecode.RETURN);
minfo.setCodeAttribute(code.toCodeAttribute());
cf.addMethod(minfo);
}
private int overrideMethods(ClassFile cf, ConstPool cp, String className,
HashMap allMethods)
throws CannotCompileException
{
String prefix = makeUniqueName("_d", allMethods);
Set entries = allMethods.entrySet();
Iterator it = entries.iterator();
int index = 0;
while (it.hasNext()) {
Map.Entry e = (Map.Entry)it.next();
String key = (String)e.getKey();
Method meth = (Method)e.getValue();
int mod = meth.getModifiers();
if (!Modifier.isFinal(mod) && !Modifier.isStatic(mod)
&& isVisible(mod, className, meth))
if (methodFilter == null || methodFilter.isHandled(meth))
override(className, meth, prefix, index++,
keyToDesc(key), cf, cp);
}
return index;
}
private void override(String thisClassname, Method meth, String prefix,
int index, String desc, ClassFile cf, ConstPool cp)
throws CannotCompileException
{
Class declClass = meth.getDeclaringClass();
String delegatorName = prefix + index + meth.getName();
if (Modifier.isAbstract(meth.getModifiers()))
delegatorName = null;
else {
MethodInfo delegator
= makeDelegator(meth, desc, cp, declClass, delegatorName);
cf.addMethod(delegator);
}
MethodInfo forwarder
= makeForwarder(thisClassname, meth, desc, cp, declClass,
delegatorName, index);
cf.addMethod(forwarder);
}
private void makeConstructors(String thisClassName, ClassFile cf,
ConstPool cp, String classname) throws CannotCompileException
{
Constructor[] cons = superClass.getDeclaredConstructors();
for (int i = 0; i < cons.length; i++) {
Constructor c = cons[i];
int mod = c.getModifiers();
if (!Modifier.isFinal(mod) && !Modifier.isPrivate(mod)
&& isVisible(mod, classname, c)) {
MethodInfo m = makeConstructor(thisClassName, c, cp, superClass);
cf.addMethod(m);
}
}
}
private static String makeUniqueName(String name, HashMap hash) {
Set keys = hash.keySet();
if (makeUniqueName0(name, keys.iterator()))
return name;
for (int i = 100; i < 999; i++) {
String s = name + i;
if (makeUniqueName0(s, keys.iterator()))
return s;
}
throw new RuntimeException("cannot make a unique method name");
}
private static boolean makeUniqueName0(String name, Iterator it) {
while (it.hasNext()) {
String key = (String)it.next();
if (key.startsWith(name))
return false;
}
return true;
}
/**
* Returns true if the method is visible from the class.
*
* @param mod the modifiers of the method.
*/
private static boolean isVisible(int mod, String from, Member meth) {
if ((mod & Modifier.PRIVATE) != 0)
return false;
else if ((mod & (Modifier.PUBLIC | Modifier.PROTECTED)) != 0)
return true;
else {
String p = getPackageName(from);
String q = getPackageName(meth.getDeclaringClass().getName());
if (p == null)
return q == null;
else
return p.equals(q);
}
}
private static String getPackageName(String name) {
int i = name.lastIndexOf('.');
if (i < 0)
return null;
else
return name.substring(0, i);
}
private static HashMap getMethods(Class superClass, Class[] interfaceTypes) {
HashMap hash = new HashMap();
for (int i = 0; i < interfaceTypes.length; i++)
getMethods(hash, interfaceTypes[i]);
getMethods(hash, superClass);
return hash;
}
private static void getMethods(HashMap hash, Class clazz) {
Class[] ifs = clazz.getInterfaces();
for (int i = 0; i < ifs.length; i++)
getMethods(hash, ifs[i]);
Class parent = clazz.getSuperclass();
if (parent != null)
getMethods(hash, parent);
Method[] methods = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; i++)
if (!Modifier.isPrivate(methods[i].getModifiers())) {
Method m = methods[i];
String key = m.getName() + ':' + RuntimeSupport.makeDescriptor(m);
hash.put(key, methods[i]);
}
}
private static String keyToDesc(String key) {
return key.substring(key.indexOf(':') + 1);
}
private static MethodInfo makeConstructor(String thisClassName, Constructor cons,
ConstPool cp, Class superClass) {
String desc = RuntimeSupport.makeDescriptor(cons.getParameterTypes(),
Void.TYPE);
MethodInfo minfo = new MethodInfo(cp, "<init>", desc);
minfo.setAccessFlags(Modifier.PUBLIC); // cons.getModifiers() & ~Modifier.NATIVE
setThrows(minfo, cp, cons.getExceptionTypes());
Bytecode code = new Bytecode(cp, 0, 0);
code.addAload(0);
code.addGetstatic(thisClassName, DEFAULT_INTERCEPTOR, HANDLER_TYPE);
code.addPutfield(thisClassName, HANDLER, HANDLER_TYPE);
code.addAload(0);
int s = addLoadParameters(code, cons.getParameterTypes(), 1);
code.addInvokespecial(superClass.getName(), "<init>", desc);
code.addOpcode(Opcode.RETURN);
code.setMaxLocals(++s);
minfo.setCodeAttribute(code.toCodeAttribute());
return minfo;
}
private static MethodInfo makeDelegator(Method meth, String desc,
ConstPool cp, Class declClass, String delegatorName) {
MethodInfo delegator = new MethodInfo(cp, delegatorName, desc);
delegator.setAccessFlags(Modifier.FINAL | Modifier.PUBLIC
| (meth.getModifiers() & ~(Modifier.PRIVATE
| Modifier.PROTECTED
| Modifier.ABSTRACT
| Modifier.NATIVE
| Modifier.SYNCHRONIZED)));
setThrows(delegator, cp, meth);
Bytecode code = new Bytecode(cp, 0, 0);
code.addAload(0);
int s = addLoadParameters(code, meth.getParameterTypes(), 1);
code.addInvokespecial(declClass.getName(), meth.getName(), desc);
addReturn(code, meth.getReturnType());
code.setMaxLocals(++s);
delegator.setCodeAttribute(code.toCodeAttribute());
return delegator;
}
/**
* @param delegatorName null if the original method is abstract.
*/
private static MethodInfo makeForwarder(String thisClassName,
Method meth, String desc, ConstPool cp,
Class declClass, String delegatorName, int index) {
MethodInfo forwarder = new MethodInfo(cp, meth.getName(), desc);
forwarder.setAccessFlags(Modifier.FINAL
| (meth.getModifiers() & ~(Modifier.ABSTRACT
| Modifier.NATIVE
| Modifier.SYNCHRONIZED)));
setThrows(forwarder, cp, meth);
int args = Descriptor.paramSize(desc);
Bytecode code = new Bytecode(cp, 0, args + 2);
/*
* if (methods[index * 2] == null) {
* methods[index * 2]
* = RuntimeSupport.findMethod(this, <overridden name>, <desc>);
* methods[index * 2 + 1]
* = RuntimeSupport.findMethod(this, <delegator name>, <desc>);
* or = null // the original method is abstract.
* }
* return ($r)handler.invoke(this, methods[index * 2],
* methods[index * 2 + 1], $args);
*/
int origIndex = index * 2;
int delIndex = index * 2 + 1;
int arrayVar = args + 1;
code.addGetstatic(thisClassName, HOLDER, HOLDER_TYPE);
code.addAstore(arrayVar);
code.addAload(arrayVar);
code.addIconst(origIndex);
code.addOpcode(Opcode.AALOAD);
code.addOpcode(Opcode.IFNONNULL);
int pc = code.currentPc();
code.addIndex(0);
callFindMethod(code, "findSuperMethod", arrayVar, origIndex, meth.getName(), desc);
callFindMethod(code, "findMethod", arrayVar, delIndex, delegatorName, desc);
code.write16bit(pc, code.currentPc() - pc + 1);
code.addAload(0);
code.addGetfield(thisClassName, HANDLER, HANDLER_TYPE);
code.addAload(0);
code.addAload(arrayVar);
code.addIconst(origIndex);
code.addOpcode(Opcode.AALOAD);
code.addAload(arrayVar);
code.addIconst(delIndex);
code.addOpcode(Opcode.AALOAD);
makeParameterList(code, meth.getParameterTypes());
code.addInvokeinterface(MethodHandler.class.getName(), "invoke",
"(Ljava/lang/Object;Ljava/lang/reflect/Method;Ljava/lang/reflect/Method;[Ljava/lang/Object;)Ljava/lang/Object;",
5);
Class retType = meth.getReturnType();
addUnwrapper(code, retType);
addReturn(code, retType);
forwarder.setCodeAttribute(code.toCodeAttribute());
return forwarder;
}
private static void setThrows(MethodInfo minfo, ConstPool cp, Method orig) {
Class[] exceptions = orig.getExceptionTypes();
setThrows(minfo, cp, exceptions);
}
private static void setThrows(MethodInfo minfo, ConstPool cp,
Class[] exceptions) {
if (exceptions.length == 0)
return;
String[] list = new String[exceptions.length];
for (int i = 0; i < exceptions.length; i++)
list[i] = exceptions[i].getName();
ExceptionsAttribute ea = new ExceptionsAttribute(cp);
ea.setExceptions(list);
minfo.setExceptionsAttribute(ea);
}
private static int addLoadParameters(Bytecode code, Class[] params,
int offset) {
int stacksize = 0;
int n = params.length;
for (int i = 0; i < n; ++i)
stacksize += addLoad(code, stacksize + offset, params[i]);
return stacksize;
}
private static int addLoad(Bytecode code, int n, Class type) {
if (type.isPrimitive()) {
if (type == Long.TYPE) {
code.addLload(n);
return 2;
}
else if (type == Float.TYPE)
code.addFload(n);
else if (type == Double.TYPE) {
code.addDload(n);
return 2;
}
else
code.addIload(n);
}
else
code.addAload(n);
return 1;
}
private static int addReturn(Bytecode code, Class type) {
if (type.isPrimitive()) {
if (type == Long.TYPE) {
code.addOpcode(Opcode.LRETURN);
return 2;
}
else if (type == Float.TYPE)
code.addOpcode(Opcode.FRETURN);
else if (type == Double.TYPE) {
code.addOpcode(Opcode.DRETURN);
return 2;
}
else if (type == Void.TYPE) {
code.addOpcode(Opcode.RETURN);
return 0;
}
else
code.addOpcode(Opcode.IRETURN);
}
else
code.addOpcode(Opcode.ARETURN);
return 1;
}
private static void makeParameterList(Bytecode code, Class[] params) {
int regno = 1;
int n = params.length;
code.addIconst(n);
code.addAnewarray("java/lang/Object");
for (int i = 0; i < n; i++) {
code.addOpcode(Opcode.DUP);
code.addIconst(i);
Class type = params[i];
if (type.isPrimitive())
regno = makeWrapper(code, type, regno);
else {
code.addAload(regno);
regno++;
}
code.addOpcode(Opcode.AASTORE);
}
}
private static int makeWrapper(Bytecode code, Class type, int regno) {
int index = FactoryHelper.typeIndex(type);
String wrapper = FactoryHelper.wrapperTypes[index];
code.addNew(wrapper);
code.addOpcode(Opcode.DUP);
addLoad(code, regno, type);
code.addInvokespecial(wrapper, "<init>",
FactoryHelper.wrapperDesc[index]);
return regno + FactoryHelper.dataSize[index];
}
/**
* @param methodName might be null.
*/
private static void callFindMethod(Bytecode code, String findMethod,
int arrayVar, int index, String methodName, String desc) {
String findClass = RuntimeSupport.class.getName();
String findDesc
= "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)Ljava/lang/reflect/Method;";
code.addAload(arrayVar);
code.addIconst(index);
if (methodName == null)
code.addOpcode(Opcode.ACONST_NULL);
else {
code.addAload(0);
code.addLdc(methodName);
code.addLdc(desc);
code.addInvokestatic(findClass, findMethod, findDesc);
}
code.addOpcode(Opcode.AASTORE);
}
private static void addUnwrapper(Bytecode code, Class type) {
if (type.isPrimitive()) {
if (type == Void.TYPE)
code.addOpcode(Opcode.POP);
else {
int index = FactoryHelper.typeIndex(type);
String wrapper = FactoryHelper.wrapperTypes[index];
code.addCheckcast(wrapper);
code.addInvokevirtual(wrapper,
FactoryHelper.unwarpMethods[index],
FactoryHelper.unwrapDesc[index]);
}
}
else
code.addCheckcast(type.getName());
}
}

+ 29
- 0
src/main/javassist/util/proxy/ProxyObject.java View File

/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/

package javassist.util.proxy;

/**
* The interface implemented by proxy classes.
*
* @see ProxyFactory
*/
public interface ProxyObject {
/**
* Sets a handler. It can be used for changing handlers
* during runtime.
*/
void setHandler(MethodHandler mi);
}

+ 157
- 0
src/main/javassist/util/proxy/RuntimeSupport.java View File

/*
* Javassist, a Java-bytecode translator toolkit.
* Copyright (C) 1999-2005 Shigeru Chiba. All Rights Reserved.
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. Alternatively, the contents of this file may be used under
* the terms of the GNU Lesser General Public License Version 2.1 or later.
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*/
package javassist.util.proxy;
import java.lang.reflect.Method;
/**
* Runtime support routines that the classes generated by ProxyFactory use.
*
* @see ProxyFactory
*/
public class RuntimeSupport {
/**
* Finds a method with the given name and descriptor.
* It searches only the class of self.
*
* @throws RuntimeException if the method is not found.
*/
public static Method findMethod(Object self, String name, String desc) {
Method m = findMethod2(self.getClass(), name, desc);
if (m == null)
error(self, name, desc);
return m;
}
/**
* Finds a method that has the given name and descriptor and is declared
* in the super class.
*
* @throws RuntimeException if the method is not found.
*/
public static Method findSuperMethod(Object self, String name, String desc) {
Class clazz = self.getClass();
Method m = findSuperMethod2(clazz.getSuperclass(), name, desc);
if (m == null)
m = searchInterfaces(clazz, name, desc);
if (m == null)
error(self, name, desc);
return m;
}
private static void error(Object self, String name, String desc) {
throw new RuntimeException("not found " + name + ":" + desc
+ " in " + self.getClass().getName());
}
private static Method findSuperMethod2(Class clazz, String name, String desc) {
Method m = findMethod2(clazz, name, desc);
if (m != null)
return m;
Class superClass = clazz.getSuperclass();
if (superClass != null) {
m = findSuperMethod2(superClass, name, desc);
if (m != null)
return m;
}
return searchInterfaces(clazz, name, desc);
}
private static Method searchInterfaces(Class clazz, String name, String desc) {
Method m = null;
Class[] interfaces = clazz.getInterfaces();
for (int i = 0; i < interfaces.length; i++) {
m = findSuperMethod2(interfaces[i], name, desc);
if (m != null)
return m;
}
return m;
}
private static Method findMethod2(Class clazz, String name, String desc) {
Method[] methods = clazz.getDeclaredMethods();
int n = methods.length;
for (int i = 0; i < n; i++)
if (methods[i].getName().equals(name)
&& makeDescriptor(methods[i]).equals(desc))
return methods[i];
return null;
}
/**
* Makes a descriptor for a given method.
*/
public static String makeDescriptor(Method m) {
Class[] params = m.getParameterTypes();
return makeDescriptor(params, m.getReturnType());
}
/**
* Makes a descriptor for a given method.
*
* @param params parameter types.
* @param retType return type.
*/
public static String makeDescriptor(Class[] params, Class retType) {
StringBuffer sbuf = new StringBuffer();
sbuf.append('(');
for (int i = 0; i < params.length; i++)
makeDesc(sbuf, params[i]);
sbuf.append(')');
makeDesc(sbuf, retType);
return sbuf.toString();
}
private static void makeDesc(StringBuffer sbuf, Class type) {
if (type.isArray()) {
sbuf.append('[');
makeDesc(sbuf, type.getComponentType());
}
else if (type.isPrimitive()) {
if (type == Void.TYPE)
sbuf.append('V');
else if (type == Integer.TYPE)
sbuf.append('I');
else if (type == Byte.TYPE)
sbuf.append('B');
else if (type == Long.TYPE)
sbuf.append('J');
else if (type == Double.TYPE)
sbuf.append('D');
else if (type == Float.TYPE)
sbuf.append('F');
else if (type == Character.TYPE)
sbuf.append('C');
else if (type == Short.TYPE)
sbuf.append('S');
else if (type == Boolean.TYPE)
sbuf.append('Z');
else
throw new RuntimeException("bad type: " + type.getName());
}
else
sbuf.append('L').append(type.getName().replace('.', '/'))
.append(';');
}
}

+ 5
- 0
src/main/javassist/util/proxy/package.html View File

<html>
<body>
Dynamic proxy (similar to <code>Enhancer</code> of <a href="http://cglib.sourceforge.net/">cglib</a>).
</body>
</html>

Loading…
Cancel
Save