From 785aa0c403ccfe2367417b1431f430961a2af067 Mon Sep 17 00:00:00 2001 From: chiba Date: Thu, 15 Jul 2004 13:49:20 +0000 Subject: [PATCH] Updated the tutorial to be more understandable. git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@113 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- Readme.html | 3 +- tutorial/tutorial.html | 151 ++++++++++++++++++++++++++++------------- 2 files changed, 104 insertions(+), 50 deletions(-) diff --git a/Readme.html b/Readme.html index 8ce4d36a..59b76998 100644 --- a/Readme.html +++ b/Readme.html @@ -555,7 +555,8 @@ Remy Sanlaville, Muga Nishizawa, Alexey Loubyansky, Saori Oki, Andreas Salathe, Dante Torres estrada, S. Pam, Nuno Santos, Denis Taye, Colin Sampaleanu, Robert Bialek, Asato Shimotaki, Howard Lewis Ship, Richard Jones, Marjan Sterjev, -Bruce McDonald, Mark Brennan, and Vlad Skarzhevskyy. +Bruce McDonald, Mark Brennan, Vlad Skarzhevskyy, +and Brett Randall for their contributions.


diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html index 6c9df81d..0598f60b 100644 --- a/tutorial/tutorial.html +++ b/tutorial/tutorial.html @@ -45,50 +45,38 @@ following program is a very simple example: ClassPool pool = ClassPool.getDefault(); CtClass cc = pool.get("test.Rectangle"); cc.setSuperclass(pool.get("test.Point")); -cc.writeFile("test.Rectangle"); +cc.writeFile(); -

This program first obtains a ClassPool object, -which controls bytecode modification with Javassist. -The ClassPool object is a container of CtClass -object representing a class file. -It reads a class file on demand for constructing a CtClass -object and contains the constructed object until it is written out -to a file or an output stream. - -

The ClassPool object is used to maintain one-to-one -mapping between classes and CtClass objects. Javassist -never allows two distinct CtClass objects to represent -the same class unless two independent ClassPool are created. -This is a significant feature for consistent program -transformation. To create multiple -instances of ClassPool, write the following code: - -

+

This program first obtains a ClassPool object, which +controls bytecode modification with Javassist. The +ClassPool object is a container of CtClass +object representing a class file. It reads a class file on demand for +constructing a CtClass object and records the +constructed object for responding later accesses. -

This creates a ClassPool object that behaves as the -default ClassPool returned by -ClassPool.getDefault() does. -ClassPool.getDefault() is a singleton factory method -provided for convenience. - -

If you have two ClassPool objects, then you can -obtain, from each ClassPool, a distinct -CtClass object representing the same class file. You can -differently modify these CtClass objects to generate -different versions of the class. - -

To modify the definition of a class, the users must first obtain a -reference to the CtClass object representing that class. +To modify the definition of a class, the users must first obtain +from a ClassPool object +a reference to a CtClass object representing that class. get() in ClassPool is used for this purpose. -In the case of the program shown at the beginning, the +In the case of the program shown above, the CtClass object representing a class test.Rectangle is obtained from the ClassPool object and it is assigned to a variable -cc. Then it is modified so that the superclass of +cc. + +

From the implementation viewpoint, ClassPool is a hash +table of CtClass objects, which uses the class names as +keys. get() in ClassPool searches this hash +table to find a CtClass object associated with the +specified key. If such a CtClass object is not found, +get() reads a class file to construct a new +CtClass object, which is recorded in the hash table and +then returned as the resulting value of get(). + +

The CtClass object obtained from a ClassPool +object can be modified. +In the example above, it is modified so that the superclass of test.Rectangle is changed into a class test.Point. This change is reflected on the original class file when writeFile() in CtClass() is @@ -103,6 +91,8 @@ modified bytecode. To obtain the bytecode, call toBytecode(): byte[] b = cc.toBytecode(); +

Class search path

+

The default ClassPool returned by a static method ClassPool.getDefault() searches the same path that the underlying JVM (Java virtual machine) has. @@ -124,7 +114,6 @@ You can use any Class object as an argument instead of this.getClass(). The class path used for loading the class represented by that Class object is registered. -

You can register a directory name as the class search path. For example, the following code adds a directory @@ -221,13 +210,32 @@ CtClass cc = pool.get("Point"); cc.setName("Pair"); -

This program first obtains the CtClass object -for class Point. Then it gives a new name Pair -to that CtClass object. -If get("Point") is later called on the ClassPool -object again, then a class file Point.class is read again and -a new CtClass object for class Point is constructed -again. See the followings: +

This program first obtains the CtClass object for +class Point. Then it calls setName() to +give a new name Pair to that CtClass object. +After this call, all occurrences of the class name in the class +definition represented by that CtClass object are changed +from Point to Pair. The other part of the +class definition does not change. + +

Note that setName() in CtClass changes a +record in the ClassPool object. From the implementation +viewpoint, a ClassPool object is a hash table of +CtClass objects. setName() changes +the key associated to the CtClass object in the hash +table. The key is changed from the original class name to the new +class name. + +

Therefore, if get("Point") is later called on the +ClassPool object again, then it never returns the +CtClass object that the variable cc refers to. +The ClassPool object reads +a class file +Point.class again and it constructs a new CtClass +object for class Point. +This is because the CtClass object associated with the name +Point does not exist any more. +See the followings:

+

cc1 and cc2 refer to the same instance of +CtClass that cc does whereas +cc3 does not. Note that, after +cc.setName("Pair") is executed, the CtClass +object that cc and cc1 refer to represents +the Pair class. + +

The ClassPool object is used to maintain one-to-one +mapping between classes and CtClass objects. Javassist +never allows two distinct CtClass objects to represent +the same class unless two independent ClassPool are created. +This is a significant feature for consistent program +transformation. To create multiple +instances of ClassPool, write the following code: + +

+ +

This creates a ClassPool object that behaves as the +default ClassPool returned by +ClassPool.getDefault() does. +ClassPool.getDefault() is a singleton factory method +provided for convenience. + +

If you have two ClassPool objects, then you can +obtain, from each ClassPool, a distinct +CtClass object representing the same class file. You can +differently modify these CtClass objects to generate +different versions of the class. +

Once a CtClass object is converted into a class file by writeFile() or toBytecode(), Javassist rejects further modifications of that CtClass object. @@ -245,20 +285,33 @@ Hence, after the CtClass object representing Point class is converted into a class file, you cannot define Pair class as a copy of Point since executing setName() on Point is rejected. +The following code snippet is wrong: + +

To avoid this restriction, you should call getAndRename() in ClassPool. For example,

If getAndRename() is called, the ClassPool -reads Point.class for creating a new CtClass -object representing Pair class. getAndRename() +first reads Point.class for creating a new CtClass +object representing Point class. However, it renames that +CtClass object from Point to Pair before +it records that CtClass object in a hash table. +Thus getAndRename() can be executed after writeFile() or toBytecode() -is called on the the ClassPool representing Point +is called on the the CtClass object representing Point class. -- 2.39.5