aboutsummaryrefslogtreecommitdiffstats
path: root/tutorial/tutorial.html
diff options
context:
space:
mode:
Diffstat (limited to 'tutorial/tutorial.html')
-rw-r--r--tutorial/tutorial.html254
1 files changed, 167 insertions, 87 deletions
diff --git a/tutorial/tutorial.html b/tutorial/tutorial.html
index 064f8da8..84de35b4 100644
--- a/tutorial/tutorial.html
+++ b/tutorial/tutorial.html
@@ -18,19 +18,18 @@ Shigeru Chiba
<p><div align="right"><a href="tutorial2.html">Next page</a></div>
-<ul>1. <a href="#read">Reading bytecode</a>
-<br>2. <a href="#def">Defining a new class</a>
-<br>3. <a href="#pool">ClassPool</a>
-<br>4. <a href="#load">Class loader</a>
-<br>5. <a href="tutorial2.html#intro">Introspection and customization</a>
-<br>6. <a href="tutorial3.html#intro">Bytecode level API</a>
+<ul>1. <a href="#read">Reading and writing bytecode</a>
+<br>2. <a href="#pool">ClassPool</a>
+<br>3. <a href="#load">Class loader</a>
+<br>4. <a href="tutorial2.html#intro">Introspection and customization</a>
+<br>5. <a href="tutorial3.html#intro">Bytecode level API</a>
</ul>
<p><br>
<a name="read">
-<h2>1. Reading bytecode</h2>
+<h2>1. Reading and writing bytecode</h2>
<p>Javassist is a class library for dealing with Java bytecode.
Java bytecode is stored in a binary file called a class file.
@@ -91,6 +90,59 @@ modified bytecode. To obtain the bytecode, call <code>toBytecode()</code>:
byte[] b = cc.toBytecode();
</pre></ul>
+<a name="def">
+<h4>Defining a new class</h4>
+
+<p>To define a new class from scratch, <code>makeClass()</code>
+must be called on a <code>ClassPool</code>.
+
+<ul><pre>
+ClassPool pool = ClassPool.getDefault();
+CtClass cc = pool.makeClass("Point");
+</pre></ul>
+
+<p>This program defines a class <code>Point</code>
+including no members.
+
+<h4>Frozen classes</h4>
+
+<p>If a <code>CtClass</code> object is converted into a class file by
+<code>writeFile()</code>, <code>toClass()</code>, or
+<code>toBytecode()</code>, Javassist freezes that <code>CtClass</code>
+object. Further modifications of that <code>CtClass</code> object are
+not permitted.
+
+<p>When Javassist freezes a <code>CtClass</code> object, it also
+prunes the data structure contained in that object. To reduce memory
+consumption, Javassist discards some part of data structure, for
+example, the data of method bodies. Thus, after a
+<code>CtClass</code> object is pruned, the bytecode of a method is not
+accessible although method names and signatures are accessible.
+
+<p>To disallow pruning a <code>CtClass</code>, <code>stopPruning()</code>
+must be called in advance:
+
+<ul><pre>
+CtClasss cc = ...;
+cc.stopPruning(true);
+ :
+cc.writeFile(); // convert to a class file.
+// cc is not pruned.
+</pre></ul>
+
+<p>If a <code>CtClass</code> is not pruned, it can be defrost so that
+modifications of the class definition can be permitted. For example,
+
+<ul><pre>
+CtClasss cc = ...;
+cc.stopPruning(true);
+ :
+cc.writeFile();
+cc.defrost();
+cc.setSuperclass(...); // OK since the class is not frozen.
+</pre></ul>
+
+
<h4>Class search path</h4>
<p>The default <code>ClassPool</code> returned
@@ -187,21 +239,106 @@ included in the search path.
<p><br>
-<a name="def">
-<h2>2. Defining a new class</h2>
+<a name="pool">
+<h2>2. ClassPool</h2>
-<p>To define a new class from scratch, <code>makeClass()</code>
-must be called on a <code>ClassPool</code>.
+<p>
+A <code>ClassPool</code> object is a container of <code>CtClass</code>
+objects. Once a <code>CtClass</code> object is created, it is
+recorded in a <code>ClassPool</code> for ever. This is because a
+compiler may need to access the <code>CtClass</code> object later when
+it compiles source code that refers to the class represented by that
+<code>CtClass</code>.
+
+<p>
+For example, suppose that a new method <code>getter()</code> is added
+to a <code>CtClass</code> object representing <code>Point</code>
+class. Later, the program attempts to compile source code including a
+method call to <code>getter()</code> in <code>Point</code> and use the
+compiled code as the body of a method, which will be added to another
+class <code>Line</code>. If the <code>CtClass</code> object representing
+<code>Point</code> is lost, the compiler cannot compile the method call
+to <code>getter()</code>. Note that the original class definition does
+not include <code>getter()</code>. Therefore, to correctly compile
+such a method call, the <code>ClassPool</code>
+must contain all the instances of <code>CtClass</code> all the time of
+program execution.
+
+<h4>Avoid out of memory</h4>
+
+<p>
+This specification of <code>ClassPool</code> may cause huge memory
+consumption if the number of <code>CtClass</code> objects becomes
+amazingly large (this rarely happens since Javassist tries to reduce
+memory consumption in various ways). To avoid this problem, you
+can explicitly remove an unnecessary <code>CtClass</code> object from
+the <code>ClassPool</code>. If you call <code>detach()</code> on a
+<code>CtClass</code> object, then that <code>CtClass</code> object is
+removed from the <code>ClassPool</code>. For example,
<ul><pre>
-ClassPool pool = ClassPool.getDefault();
-CtClass cc = pool.makeClass("Point");
+CtClass cc = ... ;
+cc.writeFile();
+cc.detach();
</pre></ul>
-<p>This program defines a class <code>Point</code>
-including no members.
+<p>You must not call any method on that
+<code>CtClass</code> object after <code>detach()</code> is called.
+
+<p>
+Another idea is to occasionally replace a <code>ClassPool</code> with
+a new one and discard the old one. If an old <code>ClassPool</code>
+is garbage collected, the <code>CtClass</code> objects included in
+that <code>ClassPool</code> are also garbage collected.
+To create a new instance of <code>ClassPool</code>, execute the following
+code snippet:
-<p>A new class can be also defined as a copy of an existing class.
+<ul><pre>
+ClassPool cp = new ClassPool();
+cp.appendSystemPath(); // or append another path by appendClassPath()
+</pre></ul>
+
+<p>This creates a <code>ClassPool</code> object that behaves as the
+default <code>ClassPool</code> returned by
+<code>ClassPool.getDefault()</code> does.
+Note that <code>ClassPool.getDefault()</code> is a singleton factory method
+provided for convenience. Therefore, the default <code>ClassPool</code>
+is never garbage-collected.
+
+<h4>Cascaded ClassPools.</h4>
+
+<p>
+<code>ClassPool</code> objects can be cascaded like
+<code>java.lang.ClassLoader</code>. For example,
+
+<ul><pre>
+ClassPool parent = ClassPool.getDefault();
+ClassPool child = new ClassPool(parent);
+child.insertClassPath("./classes");
+</pre></ul>
+
+<p>
+If <code>child.get()</code> is called, the child <code>ClassPool</code>
+first delegates to the parent <code>ClassPool</code>. If the parent
+<code>ClassPool</code> fails to find a class file, then the child
+<code>ClassPool</code> attempts to find a class file
+under the <code>./classes</code> directory.
+
+<p>
+If <code>child.childFirstLookup</code> is true, the child
+<code>ClassPool</code> attempts to find a class file before delegating
+to the parent <code>ClassPool</code>. For example,
+
+<ul><pre>
+ClassPool parent = ClassPool.getDefault();
+ClassPool child = new ClassPool(parent);
+child.appendSystemPath(); // the same class path as the default one.
+child.childFirstLookup = true; // changes the behavior of the child.
+</pre></ul>
+
+<h4>Changing a class name for defining a new class</h4>
+
+<p>A new class can be defined as a copy of an existing class.
The program below does that:
<ul><pre>
@@ -258,26 +395,26 @@ mapping between classes and <code>CtClass</code> objects. Javassist
never allows two distinct <code>CtClass</code> objects to represent
the same class unless two independent <code>ClassPool</code> are created.
This is a significant feature for consistent program
-transformation. To create multiple
-instances of <code>ClassPool</code>, write the following code:
+transformation.
+
+<p>To create another copy of the default instance of
+<code>ClassPool</code>, which is returned by
+<code>ClassPool.getDefault()</code>, execute the following code
+snippet (this code was already shown above):
<ul><pre>
ClassPool cp = new ClassPool();
cp.appendSystemPath(); // or append another path by appendClassPath()
</pre></ul>
-<p>This creates a <code>ClassPool</code> object that behaves as the
-default <code>ClassPool</code> returned by
-<code>ClassPool.getDefault()</code> does.
-<code>ClassPool.getDefault()</code> is a singleton factory method
-provided for convenience.
-
<p>If you have two <code>ClassPool</code> objects, then you can
obtain, from each <code>ClassPool</code>, a distinct
<code>CtClass</code> object representing the same class file. You can
differently modify these <code>CtClass</code> objects to generate
different versions of the class.
+<h4>Renaming a frozen class for defining a new class</h4>
+
<p>Once a <code>CtClass</code> object is converted into a class file
by <code>writeFile()</code> or <code>toBytecode()</code>, Javassist
rejects further modifications of that <code>CtClass</code> object.
@@ -314,67 +451,10 @@ can be executed after <code>writeFile()</code> or <code>toBytecode()</code>
is called on the the <code>CtClass</code> object representing <code>Point</code>
class.
-
-<p><br>
-
-<a name="pool">
-<h2>3. ClassPool</h2>
-
-<p>
-A <code>ClassPool</code> object is a container of <code>CtClass</code>
-objects. Once a <code>CtClass</code> object is created, it is
-recorded in a <code>ClassPool</code> for ever. This is because a
-compiler may need to access the <code>CtClass</code> object later when
-it compiles source code that refers to the class represented by that
-<code>CtClass</code>. If the class definition represented by that
-<code>CtClass</code> object is different from that of the original class
-file, the compiler cannot correctly compile the source code without
-the <code>CtClass</code> object.
-
-<p>
-This specification of <code>ClassPool</code> may cause huge memory
-consumption if the number of <code>CtClass</code> objects becomes large.
-To avoid this problem, you can explicitly remove an unnecessary
-<code>CtClass</code> object from the <code>ClassPool</code>. If you
-call <code>detach()</code> on a <code>CtClass</code> object, then that
-<code>CtClass</code> object is removed from the <code>ClassPool</code>.
-For example,
-
-<ul><pre>
-CtClass cc = ... ;
-cc.writeFile();
-cc.detach();
-</pre></ul>
-
-<p>You must not call any method on that
-<code>CtClass</code> object after <code>detach()</code> is called.
-
-<p><code>ClassPool</code> objects can be cascaded like
-<code>java.lang.ClassLoader</code>. For example,
-
-<ul><pre>
-ClassPool parent = ClassPool.getDefault();
-ClassPool child = new ClassPool(parent);
-</pre></ul>
-
-<p>If <code>child.get()</code> is called, the child <code>ClassPool</code>
-first delegates to the parent <code>ClassPool</code>. If the parent
-<code>ClassPool</code> fails to find a class file, then the child
-<code>ClassPool</code> attempts to find a class file.
-If <code>child.childFirstLookup</code> is true, the child
-<code>ClassPool</code> attempts to find a class file before delegating
-to the parent <code>ClassPool</code>. For example,
-
-<ul><pre>
-ClassPool parent = ClassPool.getDefault();
-ClassPool child = new ClassPool(parent);
-child.childFirstLookup = true; // changes the behavior of the child.
-</pre></ul>
-
<p><br>
<a name="load">
-<h2>4. Class loader</h2>
+<h2>3. Class loader</h2>
<p>If what classes must be modified is known in advance,
the easiest way for modifying the classes is as follows:
@@ -396,7 +476,7 @@ by Javassist.
<p><br>
-<h3>4.1 The <code>toClass</code> method in <code>CtClass</code></h3>
+<h3>3.1 The <code>toClass</code> method in <code>CtClass</code></h3>
<p>The <code>CtClass</code> provides a convenience method
<code>toClass()</code>, which requests the context class loader for
@@ -475,7 +555,7 @@ more complex functionality, you should write your own class loader.
<p><br>
-<h3>4.2 Class loading in Java</h3>
+<h3>3.2 Class loading in Java</h3>
<p>In Java, multiple class loaders can coexist and
each class loader creates its own name space.
@@ -655,7 +735,7 @@ be helpful:
<p><br>
-<h3>4.3 Using <code>javassist.Loader</code></h3>
+<h3>3.3 Using <code>javassist.Loader</code></h3>
<p>Javassist provides a class loader
<code>javassist.Loader</code>. This class loader uses a
@@ -792,7 +872,7 @@ make sure whether all the classes using that class have been loaded by
<p><br>
-<h3>4.4 Writing a class loader</h3>
+<h3>3.4 Writing a class loader</h3>
<p>A simple class loader using Javassist is as follows:
@@ -863,7 +943,7 @@ Hence, the
<p><br>
-<h3>4.5 Modifying a system class</h3>
+<h3>3.5 Modifying a system class</h3>
<p>The system classes like <code>java.lang.String</code> cannot be
loaded by a class loader other than the system class loader.