javassist

How do I get the method body using Javassist?

删除回忆录丶 提交于 2020-08-19 06:44:26
问题 It is possible to set the method body using CtMethod.setBody("..") , but I do not find any API to get the method body in string format. 回答1: This is not possible. Javassist is not a decompiler. A method in a class file is represented in Java byte code. Javassist knows how to translate Java source code to byte code but not the other way round. Also, Java byte code might not even be expressable as Java source code, for example when written in a non-Java JVM language. 来源: https://stackoverflow

简单使用java instrument包

蹲街弑〆低调 提交于 2020-08-06 20:36:02
解释: ClassFileTransformer接口,定义一个类文件转换器。接口中的transform()方法会在类文件被加载时调用,而在transform方法里,我们可以利用上文中的ASM或Javassist对传入的字节码进行改写或替换,生成新的字节码数组后返回。 在jar包前加 java -javaagent:{agent路径}/agent.jar -jar xxx.jar 例如我们想获取akka.http.scaladsl.server.RequestContextImpl类的这个属性request的默认值 项目结构: 代码: maven3.5.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zxing</groupId>

java.lang.instrument使用

杀马特。学长 韩版系。学妹 提交于 2020-07-29 10:34:49
Java在1.5引入java.lang.instrument,你可以由此实现一个Java agent,通过此agent来修改类的字节码即改变一个类。 程序启动之时启动代理(pre-main) 通过java instrument 实现一个简单的profiler。当然instrument并不限于profiler,instrument可以做很多事情,它类似一种更低级,更松耦合的AOP,可以从底层来改变一个类的行为,你可以由此产生无限的遐想。 接下来要做的事情,就是计算一个方法所花的时间,通常我们会在代码这么写: 在方法开始开头加入long stime = System.nanoTime(); 在方法结尾通过System.nanoTime()-stime得出方法所花时间, 你不得不在你想监控的每个方法中写入重复的代码,好一点的情况,你可以用AOP来干这事,但总是感觉有点别扭,这种profiler的代码还是打包在你的项目中,java instrument使得这更干净。 写agent类 import java.lang.instrument.Instrumentation; import java.lang.instrument.ClassFileTransformer; public class PerfMonAgent { static private Instrumentation

Java高级特性之Instrumentation

≯℡__Kan透↙ 提交于 2020-07-29 02:20:57
不要说精通Java、Spring,能掌握70%就很不错了,其他的高级特性。。。 我们平常开发java程序时,总想开发一个代理程序监视记录类的运行情况,比如性能监控或运维人员很需要,比如调用业务方法时记录日志、计时等,除了AOP实现之外,还有一种实现,那就是基于java高级特性Instrumentation功能, 比如很多开源或商业公司也是基于此玩法, 用开源的技术赚钱是我们一生的梦想!!!!!!!!! Instrumentation简介 利用java.lang.instrument(容器类) 做动态 Instrumentation(执行容器) 是 Java SE 5 的新特性。 使用 Instrumentation,开发者可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在 JVM 上的程序,甚至能够替换和修改某些类的定义。 这个功能为虚拟机监控提供了支撑。 利用 Java 代码,即 java.lang.instrument 做动态 Instrumentation 是 Java SE 5 的新特性,它把 Java 的 instrument 功能从本地代码中解放出来,使之可以用 Java 代码的方式解决问题。使用 Instrumentation,开发者可以构建一个独立于应用程序的代理程序(Agent),用来监测和协助运行在 JVM 上的程序

dubbo升级到Apache的 2.7.7报错Caused by: java.io.IOException: invalid constant type: 18

邮差的信 提交于 2020-07-28 11:31:00
dubbo升级到Apache的 2.7.7报错Caused by: java.io.IOException: invalid constant type: 18 2020-05-29 16:57:10,013 [localhost-startStop-1] [org.springframework.web.context.ContextLoader]-[ERROR] Context initialization failed org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'ServiceBean:com.test.service.DemoService': Instantiation of bean failed; nested exception is java.lang.ExceptionInInitializerError at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1155) at org.springframework

spring Aop实现防止重复提交

纵然是瞬间 提交于 2020-07-28 11:03:47
1.先定义一个注解 import java.lang.annotation.* ; /** * @desc 定义一个不重复提交的注解 */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @ interface NoRepeatCommit { String name() default "name:" ; } 2.实现一个aop import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Pointcut; import org.aspectj.lang.reflect.MethodSignature; import org

Can I modify the byte code of a Java method in the runtime?

怎甘沉沦 提交于 2020-04-29 09:51:32
问题 I am writing a plugin of another large java program . I want to modify some byte code of some java method of the java program during runtime, so that I can intercept the method calls (namely, inject some hooking code into the method). Any way can achieve this? PS: I've checked the following approaches: 1.change the classloader of the java program. (we CANNOT change it) 2.use java proxy. (We CANNOT use java proxy, because java proxy would create a new proxy object. We DON'T use the proxy

为《 两周自制脚本语言 》添加中文测试代码

邮差的信 提交于 2020-04-28 21:57:18
源自 自制编译器+自制脚本语言+自制编程语言 三书比较? 两年多前只看了一本的前六章: 实践"两周自制脚本语言"一书【java吧】_百度贴吧 当时是希望一路添加测试用例, 并且最终把语言改为中文语法. 但看到Gluonj之后,似乎必须要Loader.run来执行解释器, 得不到返回值, 只能打印解释结果. 今天从此书官网( スクリプト言語の作り方 )找到了它的附带源码库: chibash/stone , 顺便研究了一下Gluonj源码, 找到了它的JUnit辅助功能: https://github.com/chibash/gluonj/blob/master/src/javassist/gluonj/util/UTester.java 据此写了第五到十四章的测试, 运行效果见开头. 下面以第九章的为例: 测试用"石头"语言源码: 位置类 class Position { x = y = 0 def move (nx, ny) { x = nx; y = ny; } } p = Position.new p.move(3, 4) p.x = 10 sum = p.x + p.y 测试代码: 面向对象解释器Test package chap9; import static org.junit.Assert.assertEquals; import java.io.IOException

自动生成getter setter

血红的双手。 提交于 2020-04-07 10:35:11
如何使用java黑魔法给一个entity生成getter,setter方法? 由于java是一门静态语言,要给一个类动态添加方法,看似是不可能的。但牛B的程序员会让任何事情发生。我只知道有两种方式可以做到,一种是字节码加强,借助asm包;另一种是运行期加强,借助javassist包。下面,尝试用第二种方法,完成一个简单的demo。 大致思路如下 :先在Filter类里 扫描工程得到所有实体类,通过 创建自定义类加载器加载实体类 ,在加载的过程中通过javassist给每个实体类添加getter setter。 为什么要自定义类加载器呢? 我们知道,所有的类都是通过类加载器 加载到内存中,类加载器的加载通过它父加载器完成。java类加载器包括: 1、启动加载器 (Bootstrap ClassLoader) ,祖宗辈的,由c++语言实现,是jvm一部分, 负责加载JAVA_HOME\lib目录中并且能被虚拟机识别的类库 。 2、 扩展类加载器(Extension ClassLoader),爷爷辈的, 负责加载JAVA_HOME\lib\ext目录中的类库 。 3、 应用程序类加载器(Application ClassLoader),dady辈的, 负责加载用户类路径(Classpath)上所指定的类库, 如果应用程序中没有自定义过自己的类加载器,一般情况下这个就是程序中默认的类加载器

JVM源码分析之堆外内存完全解读

萝らか妹 提交于 2020-03-19 12:44:28
3 月,跳不动了?>>> 本文来自 PerfMa社区,欢迎关注公众号 ;链接: https://club.perfma.com/article/150614 概述 广义的堆外内存 说到堆外内存,那大家肯定想到堆内内存,这也是我们大家接触最多的,我们在jvm参数里通常设置-Xmx来指定我们的堆的最大值,不过这还不是我们理解的Java堆,-Xmx的值是新生代和老生代的和的最大值,我们在jvm参数里通常还会加一个参数-XX:MaxPermSize来指定持久代的最大值,那么我们认识的Java堆的最大值其实是-Xmx和-XX:MaxPermSize的总和,在分代算法下,新生代,老生代和持久代是连续的虚拟地址,因为它们是一起分配的,那么剩下的都可以认为是堆外内存(广义的)了,这些包括了jvm本身在运行过程中分配的内存,codecache,jni里分配的内存,DirectByteBuffer分配的内存等等 狭义的堆外内存 而作为java开发者,我们常说的堆外内存溢出了,其实是狭义的堆外内存,这个主要是指java.nio.DirectByteBuffer在创建的时候分配内存,我们这篇文章里也主要是讲狭义的堆外内存,因为它和我们平时碰到的问题比较密切 JDK/JVM里DirectByteBuffer的实现 DirectByteBuffer通常用在通信过程中做缓冲池,在mina