⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 manual.txt

📁 一个用于对.class文件进行插桩的开源工具
💻 TXT
📖 第 1 页 / 共 4 页
字号:
           Byte Code Engineering Library (BCEL)                    Description and usage manual                                            Version 1.0                                      Markus Dahm                               markus.dahm@berlin.de                                       October 31, 2001                                              Abstract          Extensions and improvements of the programming language Java and its re-       lated execution environment (Java Virtual Machine, JVM) are the subject of a large       number of research projects and proposals. There are projects, for instance, to add       parameterized types to Java, to implement "Aspect-Oriented Programming", to per-       form sophisticated static analysis, and to improve the run-time performance.          Since Java classes are compiled into portable binary class files (called byte code), it       is the most convenient and platform-independent way to implement these improve-       ments not by writing a new compiler or changing the JVM, but by transforming the       byte code. These transformations can either be performed after compile-time, or at       load-time. Many programmers are doing this by implementing their own special-       ized byte code manipulation tools, which are, however, restricted in the range of       their re-usability.          To deal with the necessary class file transformations, we introduce an API that       helps developers to conveniently implement their transformations.1     IntroductionThe Java language [GJS96  ] has become very popular and many research projects dealwith further improvements of the language or its run-time behavior. The possibility toextend a language with new concepts is surely a desirable feature, but implementationissues should be hidden from the user.  Fortunately, the concepts of the Java VirtualMachine permit the user-transparent implementation of such extensions with relativelylittle effort.    Because the target language of Java is an interpreted language with a small and easy-to-understand set of instructions (the byte code), developers can implement and test their                                                  1concepts in a very elegant way.  One can write a plug-in replacement for the system'sclass loader which is responsible for dynamically loading class files at run-time andpassing the byte code to the Virtual Machine (see section 4.1). Class loaders may thusbe used to intercept the loading process and transform classes before they get actuallyexecuted by the JVM [LB98  ]. While the original class files always remain unaltered, thebehavior of the class loader may be reconfigured for every execution or instrumenteddynamically.    The BCEL API (Byte Code Engineering Library), formerly known as JavaClass, isa toolkit for the static analysis and dynamic creation or transformation of Java classfiles.  It enables developers to implement the desired features on a high level of ab-straction without handling all the internal details of the Java class file format and thusre-inventing the wheel every time. BCEL is written entirely in Java and freely availableunder the terms of the Apache Software License. 1    This paper is structured as follows: We give a brief description of the Java VirtualMachine and the class file format in section 2.  Section 3 introduces the BCEL API.Section 4 describes some typical application areas and example projects. The appendixcontains code examples that are to long to be presented in the main part of this paper.All examples are included in the down-loadable distribution.1.1    Related workThere are a number of proposals and class libraries that have some similarities withBCEL: The JOIE [CCK98   ] toolkit can be used to instrument class loaders with dynamicbehavior.  Similarly, "Binary Component Adaptation" [KH98   ] allows components tobe adapted and evolved on-the-fly.  Han Lee's "Byte-code Instrumenting Tool" [LZ98  ]allows the user to insert calls to analysis methods anywhere in the byte code. The Jasminlanguage [MD97   ] can be used to hand-write or generate pseudo-assembler code. D-Java[Sil98 ] and JCF [You98  ] are class viewing tools.    In contrast to these projects, BCEL is intended to be a general purpose tool for "bytecode engineering".  It gives full control to the developer on a high level of abstractionand is not restricted to any particular application area.2     The Java Virtual MachineReaders already familiar with the Java Virtual Machine and the Java class file formatmay want to skip this section and proceed with section 3.    Programs written in the Java language are compiled into a portable binary formatcalled byte code. Every class is represented by a single class file containing class relateddata and byte code instructions. These files are loaded dynamically into an interpreter(Java Virtual Machine, JVM) and executed.________________________________________   1The distribution is available at http://jakarta.apache.org/bcel/, including several code ex-amples and javadoc manuals.                                                  2    Figure 1 illustrates the procedure of compiling and executing a Java class: The sourcefile (HelloWorld.java) is compiled into a Java class file (HelloWorld.class), loadedby the byte code interpreter and executed.  In order to implement additional features,researchers may want to transform class files (drawn with bold lines) before they getactually executed. This application area is one of the main issues of this article.                     Figure 1: Compilation and execution of Java classes    Note that the use of the general term "Java" implies two meanings: on the one hand,Java as a programming language is meant, on the other hand, the Java Virtual Machine,which is not necessarily targeted by the Java language exclusively, but may be used byother languages as well (e.g. Eiffel [CCZ97   ], or Ada [Taf96 ]). We assume the reader tobe familiar with the Java language and to have a general understanding of the VirtualMachine.2.1    Java class file formatGiving a full overview of the design issues of the Java class file format and the associ-ated byte code instructions is beyond the scope of this paper. We will just give a briefintroduction covering the details that are necessary for understanding the rest of thispaper. The format of class files and the byte code instruction set are described in moredetail in the "Java Virtual Machine Specification" [LY97  ] 2, and in [MD97   ].  Especially,we will not deal with the security constraints that the Java Virtual Machine has to checkat run-time, i.e. the byte code verifier.________________________________________   2Also available online at http://www.javasoft.com/docs/books/vmspec/index.html                                                  3    Figure 2 shows a simplified example of the contents of a Java class file:  It startswith a header containing a "magic number" (0xCAFEBABE) and the version number,followed by the constant pool, which can be roughly thought of as the text segment ofan executable, the access rights of the class encoded by a bit mask, a list of interfacesimplemented by the class, lists containing the fields and methods of the class, and finallythe class attributes, e.g.  the SourceFile attribute telling the name of the source file.Attributes are a way of putting additional, e.g. user-defined, information into class filedata structures. For example, a custom class loader may evaluate such attribute data inorder to perform its transformations. The JVM specification declares that unknown, i.e.user-defined attributes must be ignored by any Virtual Machine implementation.                                 Figure 2: Java class file format                                                  4    Because all of the information needed to dynamically resolve the symbolic referencesto classes, fields and methods at run-time is coded with string constants, the constantpool contains in fact the largest portion of an average class file, approximately 60%[AP98  ]. The byte code instructions themselves just make up 12%.    The right upper box shows a "zoomed" excerpt of the constant pool, while therounded box below depicts some instructions that are contained within a method ofthe example class.  These instructions represent the straightforward translation of thewell-known statement:     System.out.println("Hello,  world");    The first instruction loads the contents of the field out of class java.lang.Systemonto the operand stack. This is an instance of the class java.io.PrintStream. Theldc ("Load constant") pushes a reference to the string "Hello world" on the stack. Thenext instruction invokes the instance method println which takes both values as pa-rameters (Instance methods always implicitly take an instance reference as their firstargument).    Instructions, other data structures within the class file and constants themselves mayrefer to constants in the constant pool.  Such references are implemented via fixed in-dexes encoded directly into the instructions.  This is illustrated for some items of thefigure emphasized with a surrounding box.    For example, the invokevirtual instruction refers to a MethodRef constant thatcontains information about the name of the called method, the signature (i.e.  the en-coded argument and return types), and to which class the method belongs.  In fact,as emphasized by the boxed value, the MethodRef constant itself just refers to otherentries holding the real data, e.g. it refers to a ConstantClass entry containing a sym-bolic reference to the class java.io.PrintStream.  To keep the class file compact,such constants are typically shared by different instructions. Similarly, a field is repre-sented by a Fieldref constant that includes information about the name, the type andthe containing class of the field.    The constant pool basically holds the following types of constants:  References tomethods, fields and classes, strings, integers, floats, longs, and doubles.2.2    Byte code instruction setThe JVM is a stack-oriented interpreter that creates a local stack frame of fixed size forevery method invocation. The size of the local stack has to be computed by the compiler.Values may also be stored intermediately in a frame area containing local variables whichcan be used like a set of registers. These local variables are numbered from 0 to 65535,i.e.  you have a maximum of 65536 of local variables.  The stack frames of caller andcallee method are overlapping, i.e. the caller pushes arguments onto the operand stackand the called method receives them in local variables.                                                  5    The byte code instruction set currently consists of 212 instructions, 44 opcodes aremarked as reserved and may be used for future extensions or intermediate optimiza-tions within the Virtual Machine. The instruction set can be roughly grouped as follows:Stack operations:     Constants can be pushed onto the stack either by loading them from       the constant pool with the ldc instruction or with special "short-cut" instructions       where the operand is encoded into the instructions, e.g.  iconst_0 or bipush       (push byte value).Arithmetic operations:      The instruction set of the Java Virtual Machine distinguishes       its operand types using different instructions to operate on values of specific type.       Arithmetic operations starting with i, for example, denote an integer operation.       E.g., iadd that adds two integers and pushes the result back on the stack.  The       Java types boolean, byte, short, and char are handled as integers by the JVM.Control flow:    There are branch instructions like goto and if_icmpeq, which com-       pares two integers for equality.  There is also a jsr (jump sub-routine) and ret       pair of instructions that is used to implement the finally clause of try-catch       blocks. Exceptions may be thrown with the athrow instruction.       Branch targets are coded as offsets from the current byte code position, i.e. with       an integer number.Load and store operations       for local variables like iload and istore.  There are also       array operations like iastore which stores an integer value into an array.Field access:   The value of an instance field may be retrieved with getfield and writ-       ten with putfield. For static fields, there are getstatic and putstatic coun-       terparts.Method invocation:       Methods may either be called via static references with invokesta-       tic or be bound virtually with the invokevirtual instruction.  Super class       methods and private methods are invoked with invokespecial.Object allocation:    Class instances are allocated with the new instruction, arrays of ba-       sic type like int[] with newarray, arrays of references like String[][] with       anewarray or multianewarray.Conversion and type checking:         For stack operands of basic type there exist casting op-       erations like f2i which converts a float value into an integer.  The validity of a       type cast may be checked with checkcast and the instanceof operator can be       directly mapped to the equally named instruction.    Most instructions have a fixed length, but there are also some variable-length in-structions:  In particular, the lookupswitch and tableswitch instructions, which                                                  6are used to implement switch() statements. Since the number of case clauses mayvary, these instructions contain a variable number of statements.    We will not list all byte code instructions here, since these are explained in detail inthe JVM specification. The opcode names are mostly self-explaining, so understandingthe following code examples should be fairly intuitive.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -