- 浏览: 506566 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (422)
- 重要 (12)
- BUG解决备忘录 (32)
- 环境搭建 (17)
- 开源组件 (4)
- 数据库 (16)
- 设计模式 (4)
- 测试 (3)
- javascript (5)
- Android (14)
- jdk相关 (9)
- struts2 (10)
- freemark (3)
- 自定义扩展及工具类 (5)
- jdk5新特性及java基础 (13)
- ssh及其他框架 (15)
- linux (32)
- tcp-ip http协议 (8)
- 服务器集群与负载均衡 (34)
- 项目管理相关 (11)
- 实用小技术 (10)
- 架构相关 (14)
- firefox组件 (11)
- spider (6)
- 产品设计 (11)
- PHP (1)
- ws (4)
- lucene (10)
- 其他 (2)
- BI (1)
- NoSQL (3)
- gzip (1)
- ext (4)
- db (6)
- socket (1)
- 源码阅读 (2)
- NIO (2)
- 图片处理 (1)
- java 环境 (2)
- 项目管理 (4)
- 从程序员到项目经理(一):没有捷径 (1)
- bug (1)
- JAVA BASE (8)
- 技术原理 (0)
- 新框架新技术 (1)
- 量化与python (1)
- 系统编程 (0)
- C语言 (0)
- 汇编 (0)
- 算法 (0)
最新评论
-
hyspace:
别逗了,最后一个算法根本不是最优的,sort(function ...
数组去重——一道前端校招试题 -
washingtin:
楼主能把策略和路由的类代码贴出来吗
Spring + iBatis 的多库横向切分简易解决思路 -
sdyjmc:
初略看了一下,没有闹明白啊,均衡负载使用Nginx,sessi ...
J2EE集群原理 I -
shandeai520:
谢谢大神!请教大神一个问题:假如我有三台服务器,连接池的上限是 ...
集群和数据库负载均衡的研究 -
hekuilove:
给lz推荐一下apache commonsStringUtil ...
request 获取 ip
前段时间为了公司里的线上工程监控用到了这个小jar包,看起来挺有用,学习下,做个笔记。
Javassist 使您可以检查、编辑以及创建 Java 二进制类。检查方面基本上与通过 Reflection API 直接在 Java 中进行的一样,但是当想要修改类而不只是执行它们时,则另一种访问这些信息的方法就很有用了。这是因为 JVM 设计上并没有提供在类装载到 JVM 中后访问原始类数据的任何方法,这项工作需要在 JVM 之外完成。
Javassist 使用 javassist.ClassPool
类跟踪和控制所操作的类。这个类的工作方式与 JVM
类装载器非常相似,但是有一个重要的区别是它不是将装载的、要执行的类作为应用程序的一部分链接,类池使所装载的类可以通过 Javassist API
作为数据使用。可以使用默认的类池,它是从 JVM
搜索路径中装载的,也可以定义一个搜索您自己的路径列表的类池。甚至可以直接从字节数组或者流中装载二进制类,以及从头开始创建新类。
装载到类池中的类由 javassist.CtClass
实例表示。与标准的 Java java.lang.Class
类一样, CtClass
提供了检查类数据(如字段和方法)的方法。不过,这只是 CtClass
的部分内容,它还定义了在类中添加新字段、方法和构造函数、以及改变类、父类和接口的方法。奇怪的是,Javassist 没有提供删除一个类中字段、方法或者构造函数的任何方法。
字段、方法和构造函数分别由 javassist.CtField、
javassist.CtMethod
和 javassist.CtConstructor
的实例表示。这些类定义了修改由它们所表示的对象的所有方法的方法,包括方法或者构造函数中的实际字节码内容。
所有字节码的源代码
Javassist 让您可以完全替换一个方法或者构造函数的字节码正文,或者在现有正文的开始或者结束位置选择性地添加字节码(以及在构造函数中添加其他一些变量)。不管是哪种情况,新的字节码都作为类 Java 的源代码声明或者 String
中的块传递。Javassist 方法将您提供的源代码高效地编译为 Java 字节码,然后将它们插入到目标方法或者构造函数的正文中。
Javassist 接受的源代码与 Java 语言的并不完全一致,不过主要的区别只是增加了一些特殊的标识符,用于表示方法或者构造函数参数、方法返回值和其他在插入的代码中可能用到的内容。这些特殊标识符以符号 $
开头,所以它们不会干扰代码中的其他内容。
对于在传递给 Javassist 的源代码中可以做的事情有一些限制。第一项限制是使用的格式,它必须是单条语句或者块。在大多数情况下这算不上是限制,因为可以将所需要的任何语句序列放 到块中。下面是一个使用特殊 Javassist 标识符表示方法中前两个参数的例子,这个例子用来展示其使用方法:
{ System.out.println("Argument 1: " + $1); System.out.println("Argument 2: " + $2); } |
对于源代码的一项更实质性的限制是不能引用在所添加的声明或者块外声明的局部变量。这意味着如果在方法开始和结尾处都添加了代码,那么一般不能将在 开始处添加的代码中的信息传递给在结尾处添加的代码。有可能绕过这项限制,但是绕过是很复杂的 -- 通常需要设法将分别插入的代码合并为一个块。
======================================================================
写了个例子。
有一个类:
- package seeeyou.app.test;
- public class HelloWorld {
- public static void sayHello(String hh) {
- try {
- Thread.sleep(3000 );
- } catch (InterruptedException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- System.out.println("hello world" );
- }
- }
要知道这个方法执行了多久,一般可以直接在sayHello这个方法的前面加
javassist不只是这些功能,还有其他功能。后面再介绍点。
另外一种用javassist的方式也很简单,而且不用在这时改变源代码。
例子如下:
- package seeeyou.app.test;
- import javassist.CannotCompileException;
- import javassist.ClassPool;
- import javassist.CtClass;
- import javassist.CtMethod;
- import javassist.CtNewMethod;
- import javassist.NotFoundException;
- /**
- * 这个例子里用javassist在加载类的时候,给HelloWorld这个类的sayHello方法动态的加入统计方法时间的代码
- *
- * @author seeeyou
- *
- */
- public class TestHelloWorld {
- public static void main(String[] args) throws NotFoundException,
- InstantiationException, IllegalAccessException,
- CannotCompileException {
- // 用于取得字节码类,必须在当前的classpath中,使用全称
- CtClass ctClass = ClassPool.getDefault().getCtClass("seeeyou.app.test.HelloWorld" );
- // 需要修改的方法名称
- String mname = "sayHello" ;
- // 新定义一个方法叫做sayHello$impl
- String newMethodName = mname + "$impl" ;
- // 获取这个方法
- CtMethod cm = ctClass.getDeclaredMethod(mname);
- cm.setName(newMethodName);// 原来的方法改个名字
- //创建新的方法,复制原来的方法
- CtMethod newMethod = CtNewMethod.copy(cm, mname, ctClass, null );
- StringBuilder bodyStr = new StringBuilder();
- bodyStr.append("{\nlong start = System.currentTimeMillis();\n" );
- // 调用原有代码,类似于method();($$)表示所有的参数
- bodyStr.append(newMethodName + "($$);\n" );
- bodyStr.append("System.out.println(\"Call to method " + mname
- + " took \" +\n (System.currentTimeMillis()-start) + "
- + "\" ms.\");\n" );
- bodyStr.append("}" );
- // 替换新方法
- newMethod.setBody(bodyStr.toString());
- // 增加新方法
- ctClass.addMethod(newMethod);
- // 类已经更改,注意不能使用HelloWorld a=new
- // HelloWorld();,因为在同一个classloader中,不允许装载同一个类两次
- HelloWorld helloWorld = (HelloWorld) ctClass.toClass().newInstance();
- helloWorld.sayHello("add" );
- }
- }
运行结果如下:
- hello world
-
Call to method sayHello took 3000
ms.
上面这个例子,是可以直接运行的。
javassist不只是这些功能,还有一些其他很好的功能,后面有空再记录下。
====================================================================
这里举个简单的例子,来记录下如何用CtClass创建一个类,并且往这个类里面新加方法,
下面是代码,可以直接运行:
- package seeeyou.app.test;
- import java.io.IOException;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import javassist.CannotCompileException;
- import javassist.ClassPool;
- import javassist.CtClass;
- import javassist.CtMethod;
- import javassist.CtNewMethod;
- import javassist.NotFoundException;
- /**
- *
- * @author seeeyou
- *
- */
- public class TestHelloWorld2 {
- public static void main(String[] args) throws NotFoundException,
- IOException, CannotCompileException, InstantiationException,
- IllegalAccessException, SecurityException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
- // 用于取得字节码类,必须在当前的classpath中,使用全称
- ClassPool pool = ClassPool.getDefault();
- /**
- * makeClass() cannot create a new interface; makeInterface() in
- * ClassPool can do. Member methods in an interface can be created with
- * abstractMethod() in CtNewMethod. Note that an interface method is an
- * abstract method.
- */
- CtClass ccClass = pool.makeClass("Point" );
- String bodyString = "{System.out.println(\"Call to method \");}" ;
- //为新创建的类新加一个方法execute,无任何参数
- CtMethod n1 = CtNewMethod.make(CtClass.voidType, "execute" , null , null ,
- bodyString, ccClass);
- ccClass.addMethod(n1);
- /**
- * 这里无法用new的形式来创建一个对象,因为已经classloader中不能有两个相同的对象,否则会报异常如下:
- *Caused by: java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader):
- *attempted duplicate class definition for name: "Point"
- **/
- Object oo = ccClass.toClass().newInstance();
- Method mms = oo.getClass().getMethod("execute" , null );
- System.out.println("new class name is : " + oo.getClass().getName());
- System.out.println("new class's method is : " + mms.invoke(oo, null ));
- System.out.println("---------------------------------------------" );
- //这一行代码将class冻结了,下面无法再对类多编辑或者修改,下面的setName会报异常如:
- //Exception in thread "main" java.lang.RuntimeException: Point class is frozen
- ccClass.freeze();
- try {
- ccClass.setName("Point2" );
- }catch (Exception e) {
- System.out.println(e);
- }
- //对已经冻结的class解冻之后还可以继续编辑修改
- ccClass.defrost();
- <span style="color: #ff0000;" > System.out.println( "------------- 上面的代码是对的,下面的代码将会无法执行出结果,会报错------------------------" );</span>
- //第二个方法
- bodyString = "public int getNumber(Integer num){System.out.println(\"Point2 Call to method \");return 10+num;}" ;
- CtMethod n2 = CtNewMethod.make(bodyString, ccClass);//直接创建一个方法,带有一个int的参数和返回值
- ccClass.addMethod(n2);
- Class[] params = new Class[ 1 ];
- Integer num = new Integer( 15 );
- params[0 ] = num.getClass();
- mms = oo.getClass().getMethod("getNumber" , params);
- System.out.println("new class name is : " + oo.getClass().getName());
- System.out.println("new class's method is : " + mms.invoke(oo, 100 ));
- System.out.println("---------------------------------------------" );
- }
- }
- 上面的结果是: new class name is : Point
- Call to method
- new class 's method is : null
- ---------------------------------------------
- java.lang.RuntimeException: Point class is frozen
- ---------------------------------------------
- Exception in thread "main" java.lang.NoSuchMethodException: Point.getNumber(java.lang.Integer)
- at java.lang.Class.getMethod(Class.java:1605 )
- at seeeyou.app.test.TestHelloWorld2.main(TestHelloWorld2.java:66 )
错误的原因其实和简单,因为我第二次新加一个方法后,没有再次实例化一个对象,所以oo还是原来的对象,他的成员函数肯定没有新加的方法。
那我可以再次实例化下试试,代码和结果如下:
- package seeeyou.app.test;
- import java.io.IOException;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import javassist.CannotCompileException;
- import javassist.ClassPool;
- import javassist.CtClass;
- import javassist.CtMethod;
- import javassist.CtNewMethod;
- import javassist.NotFoundException;
- /**
- *
- * @author seeeyou
- *
- */
- public class TestHelloWorld2 {
- public static void main(String[] args) throws NotFoundException,
- IOException, CannotCompileException, InstantiationException,
- IllegalAccessException, SecurityException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
- // 用于取得字节码类,必须在当前的classpath中,使用全称
- ClassPool pool = ClassPool.getDefault();
- /**
- * makeClass() cannot create a new interface; makeInterface() in
- * ClassPool can do. Member methods in an interface can be created with
- * abstractMethod() in CtNewMethod. Note that an interface method is an
- * abstract method.
- */
- CtClass ccClass = pool.makeClass("Point" );
- String bodyString = "{System.out.println(\"Call to method \");}" ;
- //为新创建的类新加一个方法execute,无任何参数
- CtMethod n1 = CtNewMethod.make(CtClass.voidType, "execute" , null , null ,
- bodyString, ccClass);
- ccClass.addMethod(n1);
- /**
- * 这里无法用new的形式来创建一个对象,因为已经classloader中不能有两个相同的对象,否则会报异常如下:
- *Caused by: java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader):
- *attempted duplicate class definition for name: "Point"
- **/
- Object oo = ccClass.toClass().newInstance();
- Method mms = oo.getClass().getMethod("execute" , null );
- System.out.println("new class name is : " + oo.getClass().getName());
- System.out.println("new class's method is : " + mms.invoke(oo, null ));
- System.out.println("---------------------------------------------" );
- //这一行代码将class冻结了,下面无法再对类多编辑或者修改,下面的setName会报异常如:
- //Exception in thread "main" java.lang.RuntimeException: Point class is frozen
- ccClass.freeze();
- try {
- ccClass.setName("Point2" );
- }catch (Exception e) {
- System.out.println(e);
- }
- //对已经冻结的class解冻之后还可以继续编辑修改
- ccClass.defrost();
- System.out.println("------------- 上面的代码是对的,下面的代码将会无法执行出结果,会报错------------------------" );
- //第二个方法
- bodyString = "public int getNumber(Integer num){System.out.println(\"Point2 Call to method \");return 10+num;}" ;
- CtMethod n2 = CtNewMethod.make(bodyString, ccClass);//直接创建一个方法,带有一个int的参数和返回值
- ccClass.addMethod(n2);
- Class[] params = new Class[ 1 ];
- Integer num = new Integer( 15 );
- params[0 ] = num.getClass(); //就多了下面这个实例化,但是这样会导致一个错误
- oo = ccClass.toClass().newInstance();
- mms = oo.getClass().getMethod("getNumber" , params);
- System.out.println("new class name is : " + oo.getClass().getName());
- System.out.println("new class's method is : " + mms.invoke(oo, 100 ));
- System.out.println("---------------------------------------------" );
- }
- }
- 这也会导致一个错误: new class name is : Point
- Call to method
- new class 's method is : null
- ---------------------------------------------
- java.lang.RuntimeException: Point class is frozen
- ------------- 上面的代码是对的,下面的代码将会无法执行出结果,会报错------------------------
- Exception in thread "main" javassist.CannotCompileException: by java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader): attempted duplicate class definition for name: "Point"
- at javassist.ClassPool.toClass(ClassPool.java:1051 )
- at javassist.ClassPool.toClass(ClassPool.java:994 )
- at javassist.ClassPool.toClass(ClassPool.java:952 )
- at javassist.CtClass.toClass(CtClass.java:1079 )
- at seeeyou.app.test.TestHelloWorld2.main(TestHelloWorld2.java:66 )
- Caused by: java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader): attempted duplicate class definition for name: "Point"
- at java.lang.ClassLoader.defineClass1(Native Method)
- at java.lang.ClassLoader.defineClass(ClassLoader.java:621 )
- at java.lang.ClassLoader.defineClass(ClassLoader.java:466 )
- at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
- at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39 )
- at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25 )
- at java.lang.reflect.Method.invoke(Method.java:597 )
- at javassist.ClassPool.toClass2(ClassPool.java:1063 )
- at javassist.ClassPool.toClass(ClassPool.java:1045 )
- ... 4 more
对的方式是只实例化一次:如下:
- package seeeyou.app.test;
- import java.io.IOException;
- import java.lang.reflect.InvocationTargetException;
- import java.lang.reflect.Method;
- import javassist.CannotCompileException;
- import javassist.ClassPool;
- import javassist.CtClass;
- import javassist.CtMethod;
- import javassist.CtNewMethod;
- import javassist.NotFoundException;
- /**
- *
- * @author seeeyou
- *
- */
- public class TestHelloWorld3 {
- public static void main(String[] args) throws NotFoundException,
- IOException, CannotCompileException, InstantiationException,
- IllegalAccessException, SecurityException, NoSuchMethodException,
- IllegalArgumentException, InvocationTargetException {
- // 用于取得字节码类,必须在当前的classpath中,使用全称
- ClassPool pool = ClassPool.getDefault();
- /**
- * makeClass() cannot create a new interface; makeInterface() in
- * ClassPool can do. Member methods in an interface can be created with
- * abstractMethod() in CtNewMethod. Note that an interface method is an
- * abstract method.
- */
- CtClass ccClass = pool.makeClass("Point" );
- String bodyString = "{System.out.println(\"Call to method \");}" ;
- //为新创建的类新加一个方法execute,无任何参数
- CtMethod n1 = CtNewMethod.make(CtClass.voidType, "execute" , null , null ,
- bodyString, ccClass);
- ccClass.addMethod(n1);
- //新加第二个方法
- bodyString = "public Integer getNumber(Integer num);" ;
- CtMethod n2 = CtNewMethod.make(bodyString, ccClass);//直接创建一个方法,带有一个int的参数和返回值
- n2.setBody("{System.out.println(\"Point Call to method \");return $1;}" );
- ccClass.addMethod(n2);
- /**
- * 这里无法用new的形式来创建一个对象,因为已经classloader中不能有两个相同的对象,否则会报异常如下:
- *Caused by: java.lang.LinkageError: loader (instance of sun/misc/Launcher$AppClassLoader):
- *attempted duplicate class definition for name: "Point"
- **/
- Object oo = ccClass.toClass().newInstance();
- Method mms = oo.getClass().getMethod("execute" , null );
- System.out.println("new class name is : " + oo.getClass().getName());
- System.out.println("new class's method is : " + mms.invoke(oo, null ));
- System.out.println("---------------------------------------------" );
- //这一行代码将class冻结了,下面无法再对类多编辑或者修改,下面的setName会报异常如:
- //Exception in thread "main" java.lang.RuntimeException: Point class is frozen
- ccClass.freeze();
- try {
- ccClass.setName("Point2" );
- }catch (Exception e) {
- System.out.println(e);
- }
- //对已经冻结的class解冻之后还可以继续编辑修改
- ccClass.defrost();
- System.out.println("------------- 上面的代码是对的,下面的代码将会无法执行出结果,会报错------------------------" );
- Class[] params = new Class[ 1 ];
- Integer num = new Integer( 0 );
- params[0 ] = num.getClass();
- mms = oo.getClass().getMethod("getNumber" ,params);
- System.out.println("new class name is : " + oo.getClass().getName());
- System.out.println("new class's method is : " + mms.invoke(oo, 100 ));
- System.out.println("---------------------------------------------" );
- }
- }
- 结果如下: new class name is : Point
- Call to method
- new class 's method is : null
- ---------------------------------------------
- java.lang.RuntimeException: Point class is frozen
- ------------- 上面的代码是对的,下面的代码将会无法执行出结果,会报错------------------------
- new class name is : Point
- Point2 Call to method
- new class 's method is : 100
-
---------------------------------------------
发表评论
-
Java获取当前路径
2013-03-08 10:27 6051、利用System.getProperty()函数获取当前路 ... -
javadoc时候乱码-编码 GBK 的不可映射字符
2012-02-13 11:18 9191,在项目列表中按 ... -
Windows客户端的JProfiler远程监控Linux上的Tomcat服务器
2011-11-21 18:25 9381.测试环境 服务器:Redhat Enterprise Li ... -
java性能监控工具JProfiler的使用
2011-11-21 18:16 1201最近公司的项目很不稳 ... -
java.lang.OutOfMemoryError异常解决方法
2011-11-11 10:05 789java.lang.OutOfMemoryError ... -
JVM Java HeapSpace到达临界值的高CPU问题
2011-11-10 19:27 1073本周有同事反馈,IDC环 ... -
jsp include 乱码问题的解决
2010-11-28 15:08 1507jsp include 乱码问题的解决 jsp includ ... -
java中 动态加载对象
2010-08-28 11:56 820jdk中动态加载对象 spring中动态加载对象方式 ...
相关推荐
Javassist学习手册,API,快速入门
赠送jar包:javassist-3.23.1-GA.jar; 赠送原API文档:javassist-3.23.1-GA-javadoc.jar; 赠送源代码:javassist-3.23.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.23.1-GA.pom; 包含翻译后的API文档...
开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发工具 javassist-3.21.0-GA开发...
赠送jar包:javassist-3.23.1-GA.jar; 赠送原API文档:javassist-3.23.1-GA-javadoc.jar; 赠送源代码:javassist-3.23.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.23.1-GA.pom; 包含翻译后的API文档...
赠送jar包:javassist-3.19.0-GA.jar; 赠送原API文档:javassist-3.19.0-GA-javadoc.jar; 赠送源代码:javassist-3.19.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.19.0-GA.pom; 包含翻译后的API文档...
赠送jar包:javassist-3.27.0-GA.jar; 赠送原API文档:javassist-3.27.0-GA-javadoc.jar; 赠送源代码:javassist-3.27.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.27.0-GA.pom; 包含翻译后的API文档...
赠送jar包:javassist-3.24.0-GA.jar; 赠送原API文档:javassist-3.24.0-GA-javadoc.jar; 赠送源代码:javassist-3.24.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.24.0-GA.pom; 包含翻译后的API文档...
Javassist是一个开源的分析、编辑和创建Java字节码的类库。是由东京工业大学的数学和计算机科学系的 Shigeru Chiba (千叶 滋)所创建的。它已加入了开放源代码JBoss 应用服务器项目,通过使用Javassist对字节码操作...
赠送jar包:javassist-3.24.0-GA.jar; 赠送原API文档:javassist-3.24.0-GA-javadoc.jar; 赠送源代码:javassist-3.24.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.24.0-GA.pom; 包含翻译后的API文档...
javassist包
赠送jar包:javassist-3.21.0-GA.jar; 赠送原API文档:javassist-3.21.0-GA-javadoc.jar; 赠送源代码:javassist-3.21.0-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.21.0-GA.pom; 包含翻译后的API文档...
javassist版本 javassist-3.15.0-GA
javassist-3.7.ga.jar反射类javassist.jar源码
javassist的使用,也可直接使用该demo修改自己的jar中的方法,demo中写了两种方法可供参考
赠送jar包:javassist-3.20.0-GA.jar; 赠送原API文档:javassist-3.20.0-GA-javadoc.jar; 赠送源代码:javassist-3.20.0-GA-sources.jar; 包含翻译后的API文档:javassist-3.20.0-GA-javadoc-API文档-中文...
javassist-3.11.0
赠送jar包:javassist-3.18.1-GA.jar; 赠送原API文档:javassist-3.18.1-GA-javadoc.jar; 赠送源代码:javassist-3.18.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.18.1-GA.pom; 包含翻译后的API文档...
javassist-3.27.0-GA.jar
环境JDK1.8 IDEA项目 javaagent+javassist 下载后导入即可
赠送jar包:javassist-3.18.1-GA.jar; 赠送原API文档:javassist-3.18.1-GA-javadoc.jar; 赠送源代码:javassist-3.18.1-GA-sources.jar; 赠送Maven依赖信息文件:javassist-3.18.1-GA.pom; 包含翻译后的API文档...