/[packages]/cauldron/asm/current/SOURCES/faq.html
ViewVC logotype

Contents of /cauldron/asm/current/SOURCES/faq.html

Parent Directory Parent Directory | Revision Log Revision Log


Revision 21094 - (show annotations) (download) (as text)
Mon Jan 17 11:14:31 2011 UTC (13 years, 3 months ago) by dmorgan
File MIME type: text/html
File size: 23713 byte(s)
imported package asm
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html>
3 <head>
4 <META http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
5 <meta content="text/html; charset=iso-8859-1" http-equiv="Content-Type">
6 <meta content="en" http-equiv="Content-Language">
7 <title>ASM - ASM FAQ</title>
8 <meta name="Description" content="ASM is a very small and very fast Java bytecode manipulation framework.">
9 <meta name="Keywords" content="ASM,bytecode,manipulation,Java,open,source,free,software,BSD">
10 <meta name="Reply-to" content="webmaster@objectweb.org">
11 <meta name="Owner" content="ObjectWeb">
12 <meta name="Robots" content="index, follow">
13 <meta content="asm-team" name="author">
14 <meta content="asm-team@objectweb.org" name="email">
15 <script src="../js/objectweb.js" type="text/javascript"></script>
16 <link type="text/css" href="../common.css" rel="stylesheet" id="stylesheet">
17 <link type="image/x-icon" href="../images/favicon.ico" rel="icon">
18 <link type="image/x-icon" href="../images/favicon.ico" rel="shortcut icon">
19 </head>
20 <body marginheight="0" marginwidth="0" topmargin="0" leftmargin="0" onload="MM_preloadImages('../images/menu/boutonok2.gif','../images/menu/boutonsearch2.gif','../images/menu/boutonprint2.gif','../images/menu/boutonsubscribe2.gif')" bgcolor="#FFFFFF" class="bodyproject">
21 <table cellpadding="0" cellspacing="0" width="100%" border="0">
22 <tr>
23 <td valign="top" width="245"><img alt=" " height="20" src="../images/pix.gif"></td><td width="100%" bgcolor="#E8EAF0" valign="bottom">&nbsp;<a class="barre" href="http://consortium.objectweb.org/">&nbsp;Consortium&nbsp;</a>&nbsp;&nbsp;<a class="barre" href="http://solutions.objectweb.org/">&nbsp;Solutions&nbsp;</a>&nbsp;&nbsp;<a class="barre" href="http://middleware.objectweb.org/">&nbsp;Middleware&nbsp;</a>&nbsp;&nbsp;<a class="barre" href="http://forge.objectweb.org/">&nbsp;Forge&nbsp;</a>&nbsp;&nbsp;<a class="barre" href="http://myobjectweb.objectweb.org/">&nbsp;MyObjectWeb&nbsp;</a></td>
24 </tr>
25 <tr>
26 <td valign="top" width="245"><a href="http://www.objectweb.org/"><img alt="ObjectWeb Consortium" border="0" height="80" width="245" src="../images/logoow.gif"></a></td><td valign="top">
27 <table cellpadding="0" cellspacing="0" width="100%" border="0">
28 <tr>
29 <td valign="top"><img alt=" " height="20" width="395" src="../images/pix.gif"></td><td valign="top" width="150"><img alt=" " height="20" width="150" src="../images/pix.gif"></td>
30 </tr>
31 <tr>
32 <td valign="top">
33 <table cellpadding="5" cellspacing="0" border="0">
34 <tr>
35 <td valign="top"></td><td valign="top"></td><td valign="top"></td><td valign="top"></td>
36 </tr>
37 </table>
38 </td><td style="line-height: 20px;" valign="top" width="150">
39 <form action="">
40 <table>
41 <tr>
42 <td><select onChange="MM_goToURL('parent',this.options[this.selectedIndex].value);return document.MM_returnValue" name="navigation"><option>Go to ObjectWeb...</option><option value="http://www.objectweb.org/">Home Page</option><option value="http://consortium.objectweb.org/">Consortium</option><option value="http://solutions.objectweb.org/">Solutions</option><option value="http://middleware.objectweb.org/">Middleware</option><option value="http://forge.objectweb.org/">Project Forge</option><option value="http://myobjectweb.objectweb.org/">My ObjectWeb</option></select></td><td><input alt="Submit" border="0" onmouseover="MM_swapImage('ok','','../images/menu/boutonok2.gif',1)" onmouseout="MM_swapImgRestore()" src="../images/menu/boutonok1.gif" id="ok" name="Ok" type="image"></td>
43 </tr>
44 </table>
45 </form>
46 <form target="_blank" action="http://www.google.com/custom" method="get">
47 <input value="S:http://www.objectweb.org/;GL:0;AH:center;LH:81;L:http://www.objectweb.org/media/owlogos/ObjectWeb-small.gif;LW:236;AWFID:48faba182d01f379;" name="cof" type="hidden"><input value="objectweb.org;mail-archive.objectweb.org;www.enhydra.org" name="domains" type="hidden"><input value="objectweb.org;www.enhydra.org" name="sitesearch" type="hidden">
48 <table rowspan="0" colspan="0">
49 <tr>
50 <td><input onblur="if (this.value=='') this.value='search'" onfocus="this.value=''" value="" maxlength="255" size="10" name="q" type="text"></td><td><input alt="Submit" onmouseover="MM_swapImage('search','','../images/menu/boutonsearch2.gif',1)" onmouseout="MM_swapImgRestore()" src="../images/menu/boutonsearch1.gif" id="search" name="sa" type="image"></td><td><a alt="Submit" onmouseover="MM_swapImage('print','','../images/menu/boutonprint2.gif',1)" onmouseout="MM_swapImgRestore()" target="_blank" href="faq_print.html"><img id="print" border="0" height="20" width="20" name="print" alt="Print" src="../images/menu/boutonprint1.gif"></a></td>
51 </tr>
52 </table>
53 <p class="glose">
54 <strong><a target="_blank" class="lienglose" href="http://www.objectweb.org/search.html">Advanced</a></strong> - Powered by Google</p>
55 </form>
56 </td>
57 </tr>
58 </table>
59 </td>
60 </tr>
61 </table>
62 <table cellpadding="0" cellspacing="0" border="0" width="100%" summary="">
63 <tr>
64 <td valign="top" width="20"><img alt=" " height="1" width="20" src="../images/pix.gif"></td><td valign="top" width="160"><img alt=" " height="1" width="160" src="../images/pix.gif"><br>
65 <br>
66 <br>
67 <br>
68 <br>
69 <p style="font-size: 16px; font-weight: bold; color: #433C7B;">ASM</p>
70 <p>
71 <span class="menutitre">Project Links</span>
72 <br>
73 &middot;&nbsp;<a class="menu" target="_self" href="../index.html">Home</a>
74 <br>
75 &middot;&nbsp;<a class="menu" target="_self" href="../download/index.html">Download</a>
76 <br>
77 &middot;&nbsp;<a class="menu" target="_self" href="../eclipse/index.html">Eclipse plugins</a>
78 <br>
79 &middot;&nbsp;<a class="menu" target="_self" href="http://www.objectweb.org/wws/lists/projects/asm">Mailing Lists</a>
80 <br>
81 &middot;&nbsp;<a class="menu" target="_self" href="../license.html">License</a>
82 <br>
83 &middot;&nbsp;<a class="menu" target="_self" href="../history.html">History</a>
84 <br>
85 </p>
86 <p>
87 <span class="menutitre">Developers' Corner</span>
88 <br>
89 &middot;&nbsp;<a class="menu" target="_self" href="http://forge.objectweb.org/cvs/?group_id=23">CVS Repository</a>
90 <br>
91 &middot;&nbsp;<a class="menu" target="_self" href="http://forge.objectweb.org/projects/asm/">ObjectWeb Forge Site</a>
92 <br>
93 </p>
94 <p>
95 <span class="menutitre">About</span>
96 <br>
97 &middot;&nbsp;<a class="menu" target="_self" href="../users.html">Users</a>
98 <br>
99 &middot;&nbsp;<a class="menu" target="_self" href="../team.html">Team</a>
100 <br>
101 &middot;&nbsp;<a class="menu" target="_self" href="mailto:asm-team@objectweb.org">Contacts</a>
102 <br>
103 </p>
104 </td><td align="left" width="100%" valign="top">
105 <h1>Frequently Asked Questions</h1>
106
107 <p>Here are some frequently asked questions about ASM, gathered by
108 <a href="mailto:m.proctor@bigfoot.com">Mark Proctor</a>.</p>
109
110 <ul>
111
112 <li>
113 <a href="#Q0">0. How do I start using ASM?</a>
114 </li>
115
116 <li>
117 <a href="#Q1">1. How do I remove a method/field?</a>
118 </li>
119
120 <li>
121 <a href="#Q2">2. How do I replace a method/field? I end up with duplicated members!</a>
122 </li>
123
124 <li>
125 <a href="#Q3">3. How do I make ASM calculate visitMaxs for me?</a>
126 </li>
127
128 <li>
129 <a href="#Q4">4. Why do I get the [xxx] verifier error?"</a>
130 </li>
131
132 <li>
133 <a href="#Q5">5. How do I add my bytecode class to the system class loader?</a>
134 </li>
135
136 <li>
137 <a href="#Q6">6. How do I rename my class?</a>
138 </li>
139
140 <li>
141 <a href="#Q7">7. How do method descriptors work?</a>
142 </li>
143
144 <li>
145 <a href="#Q8">8. How can ASM help me create my descriptor types?</a>
146 </li>
147
148 <li>
149 <a href="#Q9">9. How do I generate Setters and Getters for my class?</a>
150 </li>
151
152 <li>
153 <a href="#Q10">10. How do I get the bytecode of an existing class?</a>
154 </li>
155
156 <li>
157 <a href="#Q11">11. How do I generate [some Java code] with ASM?</a>
158 </li>
159
160 <li>
161 <a href="#Q12">12. How does the [xxx] bytecode instruction work?</a>
162 </li>
163
164 <li>
165 <a href="#Q13">13. Is ASM thread safe?</a>
166 </li>
167
168 <li>
169 <a href="#Q14">14. What is the earliest JDK required to use ASM?</a>
170 </li>
171
172 </ul>
173
174
175 <h3>
176 <a name="Q0"></a>0. How do I start using ASM?</h3>
177
178
179 <p>If you want to use ASM to generate classes from scratch, write a Java source
180 file that is representative of the classes you want to generate, compile it(*), and
181 then run the <a href="#Q10">ASMifier</a> on the compiled class to see the Java source code that
182 generates this class with ASM. If you are using Eclipse it is even easier,
183 thanks to the <a href="../eclipse.html">Bytecode Outline</a> plugin.</p>
184
185
186 <p>If you want to use ASM to transform classes, write two Java source files -
187 first with and second without features that has to be added or removed and try
188 to keep other differences as minimal as you can, compile them(*), and then run the
189 <a href="#Q10">ASMifier</a> on both of them. Then compare the results with some visual diff tool.
190 If you are using Eclipse it is even easier, thanks to the compare tool of the
191 <a href="../eclipse.html">Bytecode Outline</a> plugin.</p>
192
193
194 <p>(*) Note that javac may produce different code for different -target,
195 so you'll have to compile for your target environment, repeat that
196 excercise for all required target's or use the earliest bytecode version
197 if possible.</p>
198
199
200 <h3>
201 <a name="Q1"></a>1. How do I remove a method/field?</h3>
202
203
204 <p>Use the ClassAdapter and return nothing:</p>
205
206 <pre> public FieldVisitor visitField (String name, ...) {
207 if (removeField(name)) {
208 // do nothing, in order to remove this field
209 return null;
210 } else {
211 // make the next visitor visit this field, in order to keep it
212 return super.visitField(name, ...);
213 }
214 }</pre>
215
216
217 <h3>
218 <a name="Q2"></a>2. How do I replace a method/field? I end up with duplicated members!</h3>
219
220
221 <p>You must either return the replacement method/field when you visit the original one using the
222 ClassAdapter, or you must first remove the original method/field in the ClassAdapter (see
223 <a href="#Q1">"1. How do I remove a method/field?"</a>), and then add the new method/field
224 by calling a visit method on the ClassWriter.</p>
225
226
227 <h3>
228 <a name="Q3"></a>3. How do I make ASM calculate visitMaxs for me?</h3>
229
230
231 <p>When calling the constructor for ClassWriter pass true. You must also
232 still include the visitMaxs instruction, but the values you give are
233 ignored, so visitMaxs(0,0) is fine.</p>
234
235
236 <h3>
237 <a name="Q4"></a>4. Why do I get the [xxx] verifier error?</h3>
238
239
240 <p>If the message given by the JVM class verifier does not help you, you can
241 use the verifier provided by ASM. For example, if you use a wrong constant when
242 making "return" on a method, or if you do not use the appropriate LOAD or STORE
243 instruction, depending on the local variable type, the JVM class verifier gives
244 a "Register x contains wrong type" or "Expecting to find x on stack" error which
245 does not say anything about the instruction that caused the error. In this case
246 you can use the class verifier provided by ASM:</p>
247
248
249 <p>
250 <code>java -cp "asm.jar;asm-tree.jar;asm-analysis.jar;asm-util.jar"
251 org.objectweb.asm.util.CheckClassAdapter org/domain/package/YourClass.class</code>
252 </p>
253
254
255 <p>For example, in the helloworld example in the ASM distribution, if you replace
256 visitLdc("Hello world!") with visitLdc(new Integer(1234)) you get the following
257 error message when the generated class is verified as above:</p>
258
259
260 <pre>org.objectweb.asm.tree.analysis.AnalyzerException: Error at instruction 2: Argument 1: expected Ljava/lang/String;, but found I
261 at org.objectweb.asm.tree.analysis.Analyzer.analyze(Unknown Source)
262 at org.objectweb.asm.util.CheckClassAdapter.main(Unknown Source)
263 main([Ljava/lang/String;)V
264 00000 [Ljava/lang/String;. : GETSTATIC java/lang/System out Ljava/io/PrintStream;
265 00001 [Ljava/lang/String;. Ljava/io/PrintStream; : LDC 1234
266 00002 [Ljava/lang/String;. Ljava/io/PrintStream;I : INVOKEVIRTUAL java/io/PrintStream println (Ljava/lang/String;)V
267 00003 null : RETURN</pre>
268
269
270 <p>This shows that the error comes from instruction 2 in method main. The instruction list
271 shows that this instruction is INVOKEVIRTUAL. It also shows the types of the local variables
272 and of the operand stack values just before this instruction will be executed (here local
273 variable 0 contains a String, local variable 1 is not initialized, and the stack contains
274 a PrintStream and an int). As explained in the error message, the println method called by
275 INVOKEVIRTUAL expects a String as first argument, but the stack value corresponding to this
276 argument is an int. Then either the INVOKEVIRTUAL instruction is wrong, or the instruction
277 that pushed the integer is wrong.</p>
278
279
280 <p>If your class is so "corrupted" that you cannot read it with a ClassReader,
281 try to generate it by using a CheckClassAdapter in front of a ClassWriter:</p>
282
283 <pre> ClassWriter cv = new ClassWriter(true);
284 cv = new CheckClassAdapter(cv);
285 // generate your class here:
286 cv.visit(...);
287 ...</pre>
288
289 <p>You will probably get an exception which will indicate why your generated class
290 is incorrect. For example, if you forget to call visit(...) (which can happen if you
291 forget to call super.visit(...) in a class adapter), the generated class
292 contains an invalid constant pool index, and ClassReader is unable to read it. If
293 you generate your class by using a CheckClassAdapter, as above, you get an
294 exception "Cannot visit member before visit has been called.", which shows that
295 you forgot to call the visit method.</p>
296
297
298 <h3>
299 <a name="Q5"></a>5. How do I add my bytecode class to the system class loader?</h3>
300
301
302 <p>You must first have the security to do this, as defined in the policy
303 file - there are no security restrictions as default for a standard java
304 install. Use ClassLoader.defineClass, this however is a "protected" method, so
305 you must use reflection to gain access to it:</p>
306
307 <pre> private Class loadClass (byte[] b) {
308 //override classDefine (as it is protected) and define the class.
309 Class clazz = null;
310 try {
311 ClassLoader loader = ClassLoader.getSystemClassLoader();
312 Class cls = Class.forName("java.lang.ClassLoader");
313 java.lang.reflect.Method method =
314 cls.getDeclaredMethod("defineClass", new Class[] { String.class, byte[].class, int.class, int.class });
315
316 // protected method invocaton
317 method.setAccessible(true);
318 try {
319 Object[] args = new Object[] { className, b, new Integer(0), new Integer(b.length)};
320 clazz = (Class) method.invoke(loader, args);
321 } finally {
322 method.setAccessible(false);
323 }
324 } catch (Exception e) {
325 e.printStackTrace();
326 System.exit(1);
327 }
328 return clazz;
329 }</pre>
330
331 <p>Alternatively you can create your own ClassLoader by extending the
332 existing class loader (example needed here).</p>
333
334
335
336 <h3>
337 <a name="Q6"></a>6. How do I rename my class?</h3>
338
339
340 <p>It is not enough to rename just the class, you must also rename all the
341 references to class members using the MethodAdapter.</p>
342
343 <pre>class ClassRenamer extends ClassAdapter implements Opcodes {
344
345 private Set oldNames;
346 private final String newName;
347
348 public ClassRenamer(ClassVisitor cv, Set oldNames, String newName) {
349 super(cv);
350 this.oldNames = oldNames;
351 this.newName = newName;
352 }
353
354 public void visit (int version, int access, String name, String signature, String superName, String[] interfaces) {
355 oldNames.add(name);
356 cv.visit(version, ACC_PUBLIC, newName, signature, superName, interfaces);
357 }
358
359 public MethodVisitor visitMethod (int access, String name, String desc, String signature, String[] exceptions) {
360 MethodVisitor mv = cv.visitMethod(access, name, fixDesc(desc), fix(signature), exceptions);
361 if (mv != null &amp;&amp; (access &amp; ACC_ABSTRACT) == 0) {
362 mv = new MethodRenamer(mv);
363 }
364 return mv;
365 }
366
367 class MethodRenamer extends MethodAdapter {
368
369 public MethodRenamer (final MethodVisitor mv) {
370 super(mv);
371 }
372
373 public void visitTypeInsn (int i, String s) {
374 if (oldNames.contains(s)) {
375 s = newName;
376 }
377 mv.visitTypeInsn(i, s);
378 }
379
380 public void visitFieldInsn (int opcode, String owner, String name, String desc) {
381 if (oldNames.contains(owner)) {
382 mv.visitFieldInsn(opcode, newName, name, fix(desc));
383 } else {
384 mv.visitFieldInsn(opcode, owner, name, fix(desc));
385 }
386 }
387
388 public void visitMethodInsn (int opcode, String owner, String name, String desc) {
389 if (oldNames.contains(owner)) {
390 mv.visitMethodInsn(opcode, newName, name, fix(desc));
391 } else {
392 mv.visitMethodInsn(opcode, owner, name, fix(desc));
393 }
394 }
395 }
396
397 private String fix (String s) {
398 if (s != null) {
399 Iterator it = oldNames.iterator();
400 String name;
401 while (it.hasNext()) {
402 name = (String) it.next();
403 if (s.indexOf(name) != -1) {
404 s = desc.replaceAll(name, newName);
405 }
406 }
407 }
408 return s;
409 }
410 }</pre>
411
412
413
414 <h3>
415 <a name="Q7"></a>7. How do method descriptors work?</h3>
416
417
418 <p>To understand this best it's good to read the source code of Type.java.
419 Here is a quick overview:</p>
420
421 <ul>
422
423 <li>Primitive representations:
424 <ul>
425
426 <li>'V' - void</li>
427
428 <li>'Z' - boolean</li>
429
430 <li>'C' - char</li>
431
432 <li>'B' - byte</li>
433
434 <li>'S' - short</li>
435
436 <li>'I' - int</li>
437
438 <li>'F' - float</li>
439
440 <li>'J' - long</li>
441
442 <li>'D' - double</li>
443
444 </ul>
445
446 </li>
447
448 <li>Class representations:
449 <ul>
450
451 <li>L&lt;class&gt;;</li>
452
453 <li>Ljava/io/ObjectOutput;</li>
454
455 <li>Ljava/lang/String;</li>
456
457 </ul>
458
459 </li>
460
461 </ul>
462
463 <p>Examples:</p>
464
465 <ul>
466
467 <li>public void method()
468 <ul>
469 <li>
470 <code>cw.visitMethod(ACC_PUBLIC, methodName, "()V", null, null);</code>
471 </li>
472 </ul>
473 </li>
474
475 <li>public void method(String s, int i)
476 <ul>
477 <li>
478 <code>cw.visitMethod(ACC_PUBLIC, methodName, "(Ljava/lang/String;I)V", null, null);</code>
479 </li>
480 </ul>
481 </li>
482
483 <li>public String method(String s, int i, boolan flag)
484 <ul>
485 <li>
486 <code>cw.visitMethod(ACC_PUBLIC, methodName, "(Ljava/lang/String;IZ)Ljava/lang/String;", null, null);</code>
487 </li>
488 </ul>
489 </li>
490
491 </ul>
492
493
494
495 <h3>
496 <a name="Q8"></a>8. How can ASM help me create my descriptor types?</h3>
497
498
499 <p>Types.java provides the static method Type.getDescriptor, which takes a
500 Class as a parameter.</p>
501
502 <p>Examples:</p>
503 <ul>
504
505 <li>
506 <code>String desc = Type.getDescriptor(String.class);</code>
507 </li>
508
509 <li>
510 <code>String desc = Type.getDescriptor(int.class);</code>
511 </li>
512
513 <li>
514 <code>String desc = Type.getDescriptor(java.io.ObjectOutput.class);</code>
515 </li>
516
517 </ul>
518
519
520
521 <h3>
522 <a name="Q9"></a>9. How do I generate Setters and Getters for my class?</h3>
523
524
525 <p>Use the following code (this assumes that visitMaxs are computed by ASM - see
526 <a href="#Q3">"3. How do I make ASM calculate visitMaxs for me?"</a>):</p>
527
528 <pre>void createSetter (String propertyName, String type, Class c) {
529 String methodName = "set" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
530 MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "(" + type + ")V", null, null);
531 mv.visitVarInsn(ALOAD, 0);
532 mv.visitVarInsn(Type.getType(c).getOpcode(ILOAD, 1));
533 mv.visitFieldInsn(PUTFIELD, className, propertyName, type);
534 mv.visitInsn(RETURN);
535 mv.visitMaxs(0, 0);
536 }
537
538 void createGetter (String propertyName, String returnType, Class c) {
539 String methodName = "get" + propertyName.substring(0, 1).toUpperCase() + propertyName.substring(1);
540 MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, methodName, "()" + returnType, null, null);
541 mv.visitVarInsn(ALOAD, 0);
542 mv.visitFieldInsn(GETFIELD, internalClassName, propertyName, returnType);
543 mv.visitInsn(Type.getType(c).getOpcode(IRETURN));
544 mv.visitMaxs(0, 0);
545 }</pre>
546
547
548
549 <h3>
550 <a name="Q10"></a>10. How do I get the bytecode of an existing class?</h3>
551
552
553 <p>If you want the bytecode instructions themselves, use TraceClassVisitor. If you
554 want the ASM code to generate these bytecode instructions, use ASMifierClassVisitor.
555 Both classes provide a "main" method to allow them to be
556 called from the command line, passing your fully qualified class name as a
557 parameter.
558 Example:</p>
559
560 <p>
561 <code>java -classpath "asm.jar;asm-util.jar;yourjar.jar"
562 org.objectweb.asm.util.ASMifierClassVisitor org.domain.package.YourClass</code>
563 </p>
564
565 <p>or</p>
566
567 <p>
568 <code>java -classpath "asm.jar;asm-util.jar"
569 org.objectweb.asm.util.ASMifierClassVisitor org/domain/package/YourClass.class</code>
570 </p>
571
572 <p>Another, much easier method, if you are using Eclipse, is to use the
573 <a href="../eclipse.html">Bytecode Outline</a> plugin.</p>
574
575
576 <h3>
577 <a name="Q11"></a>11. How do I generate [some Java code] with ASM?</h3>
578
579
580 <p>If you want to know how to generate a synchronized block, a try catch
581 block, a finally statement, or any other Java construct, write the Java code
582 you want to generate in a temporary class, compile it with javac, and then
583 use the ASMifierClassVisitor to get the ASM code that will generate this class (see
584 <a href="#Q10">"10. How do I get the bytecode of an existing class?"</a>).
585 </p>
586
587
588
589 <h3>
590 <a name="Q12"></a>12. How does the [xxx] bytecode instruction work?</h3>
591
592
593 <p>See <a href="http://java.sun.com/docs/books/vmspec/2nd-edition/html/Instructions.doc.html">chapter
594 6</a> of the Java Virtual Machine Specification.
595 </p>
596
597
598
599 <h3>
600 <a name="Q13"></a>13. Is ASM thread safe?</h3>
601
602
603 <p>The Type and ClassReader classes are thread safe, i.e. several threads can
604 use a single Type object or a single ClassReader object concurrently without
605 problems. The ClassWriter and MethodWriter classes are <em>not</em> thread safe,
606 i.e. a single class cannot be generated by several concurrent threads (but,
607 of course, several threads can generate distinct classes concurrently, if each
608 thread uses its own ClassWriter instance). In order to generate a single class
609 by using several concurrent threads, one should use ClassAdapter and
610 MethodAdapter instances that delegate to normal ClassWriter and MethodWriter
611 instances, and whose methods are all synchronized.</p>
612
613 <p>More generally, ClassVisitor and MethodVisitor implementations, such as
614 ClassWriter and ClassAdapter, do not have to be thread safe. However, non thread
615 safe visitors can be made thread safe just by using a synchronizing class
616 adapter in front of them.</p>
617
618
619
620 <h3>
621 <a name="Q14"></a>14. What is the earliest JDK required to use ASM?</h3>
622
623
624 <p>The org.objectweb.asm package should work with JDK 1.1, or even with JDK 1.0
625 if Type is not used. Indeed, this package only requires the following JDK classes
626 and methods:</p>
627
628 <ul>
629
630 <li>in java.io: InputStream, IOException (only in two constructors of
631 ClassReader)</li>
632
633 <li>in java.lang.reflect: Method (only in Type)</li>
634
635 <li>in java.lang:
636 <ul>
637
638 <li>Object, String, StringBuffer</li>
639
640 <li>Long, Double, Float, Void, Byte, Boolean ...</li>
641
642 <li>System.arraycopy</li>
643
644 <li>ClassLoader.getSystemClassLoader,
645 ClassLoader.getSystemResourceAsStream (only in one constructor of
646 ClassReader)</li>
647
648 </ul>
649
650 </li>
651
652 </ul>
653
654 <p>The asm.util and asm.tree packages require JDK 1.2, since they use the
655 List interface and the ArrayList class.
656 </p>
657
658
659
660 </td><td valign="top" width="10"><img alt=" " height="1" width="10" src="../images/pix.gif"></td>
661 </tr>
662 <tr>
663 <td valign="top" width="20"><img alt=" " height="1" width="20" src="../images/pix.gif"></td><td valign="top" width="160"><img alt=" " height="1" width="160" src="../images/pix.gif"></td><td valign="top"><img alt=" " height="1" width="465" src="../images/pix.gif"><br>
664 <address>Copyright &copy; 1999-2005, <a href="http://www.objectweb.org/">ObjectWeb Consortium</a> | <a href="http://consortium.objectweb.org/contact.html">contact</a> | <a href="mailto:webmaster@objectweb.org">webmaster</a> | Last modified at 2005-02-22 05:27 PM</address>
665 </td><td valign="top" width="10"><img alt=" " height="1" width="10" src="../images/pix.gif"></td>
666 </tr>
667 </table>
668 <br>
669 </body>
670 </html>

  ViewVC Help
Powered by ViewVC 1.1.30