说明:
今天在研究使用javaAgent解决产品的缺陷问题时,在网上查询到的javassist的使用方法基本都是一样的,但是pom文件中设置的javaAgent打包方式存在异常,或者介绍的不够准确,导致编译出来的javaAgent的jar包存在异常,如下列所示:
pom编译jar包设置:
<build>
<plugins>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifestEntries>
<Premain-Class>FirstAgent</Premain-Class>
<Boot-Class-Path>firstAgent.jar</Boot-Class-Path>
<Can-Redefine-Classes>false</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
<Can-Set-Native-Method-Prefix>false</Can-Set-Native-Method-Prefix>
</manifestEntries>
</archive>
</configuration>
</plugin>
</plugins>
</build>
编译出的包导致的异常:
java.lang.NoClassDefFoundError: javassist/ClassPool
通过分析编译出的jar包的大小(8k),能够分析javaAgent的依赖包没有编译到jar中,导致程序运行的类都no found,通过解压jar,确认依赖jar确实没有编译到javaAgent包中;
由上可知,应该是springboot编译jar导致的问题,针对maven编译jar的方式做分析,常规的maven编译jar的方式由三种,分别为:
1)maven-jar-plugin,默认的打包插件,用来打普通的project JAR包;
2)maven-shade-plugin,用来打可执行JAR包,也就是所谓的fat JAR包;
3)maven-assembly-plugin,支持自定义的打包结构,也可以定制依赖项等
关于这三种的编译jar包的方式,这是不再赘述,后续文章会详细说明,这是只说明通过maven-jar-plugin和maven-assembly-plugin这两种方式解决javaAgent编译jar包的问题,如下:
1)maven-jar-plugin
编译出javaAgent程序包javaAgent-0.0.1.jar和依赖jar文件,存放到lib目录下,pom文件配置如下:
```xml
```yaml
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.1.2</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
<manifestEntries>
<Premain-Class>FirstAgent</Premain-Class>
<Boot-Class-Path>firstAgent.jar</Boot-Class-Path>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
<Can-Set-Native-Method-Prefix>true</Can-Set-Native-Method-Prefix>
</manifestEntries>
</archive>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy</id>
<phase>compile</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>
${project.build.directory}/lib
</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
编译结果:
执行命令:
java -jar -javaagent:../../lib/patchAgent-0.0.1.jar -jar testDemo.jar
2)maven-assembly-plugin
javaAgent程序jar和依赖jar都会编译到一个jar文件中,pom配置如下:
<build>
<plugins>
<plugin>
<!-- maven 打包插件 打原始jar包 第三方依赖打入jar包中-->
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<!-- <Class-Path>.</Class-Path>-->
<Premain-Class>FirstAgent</Premain-Class>
<Agent-Class>FirstAgent</Agent-Class>
<Can-Redefine-Classes>true</Can-Redefine-Classes>
<Can-Retransform-Classes>true</Can-Retransform-Classes>
</manifestEntries>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
<executions>
<execution>
<id>make-assembly</id> <!-- this is used for inheritance merges -->
<phase>package</phase> <!-- 指定在打包节点执行jar包合并操作 -->
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
编译结果:
执行命令:
java -jar -javaagent:../../patchAgent-0.0.1.jar -jar testDemo.jar
注:Java探针 - Java Agent 动态字节码增强技术的使用方式,可以参考一下这篇文章:https://mp.weixin.qq.com/s/j90XrN-U57QXhyeYgkvb-Q
=程序员的凛冬已至,希望大家能度过寒冬==========