-
Notifications
You must be signed in to change notification settings - Fork 18
动态注入案例:实时修复一个空指针异常
许杰 edited this page Aug 24, 2020
·
3 revisions
创建一个helloworld 空指针异常程序,该程序定时抛出NullPointerException,让我们来实时修复它
hellowrld代码:
package io.manbang.helloworld;
/**
* @author xujie
*/
public class HelloWorld {
public static void main(String[] args) throws InterruptedException {
new HelloWorld().loop(null);
}
void loop(UserModel userModel) throws InterruptedException {
while (true) {
runPrint(userModel);
}
}
void runPrint(UserModel userModel) throws InterruptedException {
try {
System.out.println(userModel.getName());
} catch (Throwable cause) {
cause.printStackTrace();
}
Thread.sleep(1000);
}
public static class UserModel {
String name;
int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
}
运行代码结果:
java.lang.NullPointerException
at io.manbang.helloworld.HelloWorld.runPrint(HelloWorld.java:22)
at io.manbang.helloworld.HelloWorld.loop(HelloWorld.java:16)
at io.manbang.helloworld.HelloWorld.main(HelloWorld.java:9)
java.lang.NullPointerException
at io.manbang.helloworld.HelloWorld.runPrint(HelloWorld.java:22)
at io.manbang.helloworld.HelloWorld.loop(HelloWorld.java:16)
at io.manbang.helloworld.HelloWorld.main(HelloWorld.java:9)
java.lang.NullPointerException
at io.manbang.helloworld.HelloWorld.runPrint(HelloWorld.java:22)
at io.manbang.helloworld.HelloWorld.loop(HelloWorld.java:16)
at io.manbang.helloworld.HelloWorld.main(HelloWorld.java:9)
在框架中找到client/plugins文件夹,创建自定义插件 simple-hotfix 如:(simplehotfix示例)
将工程引入框架pom依赖
<dependency>
<groupId>io.manbang</groupId>
<artifactId>helloworld</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>provided</scope>
</dependency>
Easy-byte-coder 提供注解帮您快速编写字节码注入代码
simplePlugin代码:
package io.manbang.easybytecoder.plugin.simplehotfix;
import com.google.auto.service.AutoService;
import io.manbang.easybytecoder.traffichandler.AttachTrafficHandler;
import io.manbang.easybytecoder.traffichandler.annotation.ModifyClassName;
import io.manbang.easybytecoder.traffichandler.annotation.ModifyMethod;
import io.manbang.easybytecoder.traffichandler.annotation.ResourceToImport;
import io.manbang.easybytecoder.traffichandler.annotation.constant.CodePatternEnum;
/**
* @author xujie
*/
@AutoService(AttachTrafficHandler.class)
@ResourceToImport({
"io.manbang.easybytecoder.runtimecommonapi.utils.EasyByteCoderResourceObjectPool",
"io.manbang.easybytecoder.plugin.simplehotfix.mock.runtime.FixHandle"
})
@ModifyClassName("io/manbang/helloworld/HelloWorld")
public class SimplePlugin implements AttachTrafficHandler {
@ModifyMethod(methodName = "runPrint", pattern = CodePatternEnum.Before)
public String modifyBefore() {
return "$1=FixHandle.fixModel($1);";
}
}
FixHandle代码:
package io.manbang.easybytecoder.plugin.simplehotfix.mock.runtime;
import io.manbang.helloworld.HelloWorld.UserModel;
/**
* @author xujie
*/
public class FixHandle {
public static UserModel fixModel(UserModel userModel) {
if (userModel == null) {
UserModel newUserModel = new UserModel();
newUserModel.setName("zhangsan");
newUserModel.setAge(18);
return newUserModel;
}
return userModel;
}
public static void test() {
System.out.println("111");
}
}
在框架顶级目录执行部署:
mvn clean install
sh copyfile.sh
切换至copyfile.sh文件中自定义的目录
执行:
java -Xbootclasspath/a:$JAVA_HOME/lib/tools.jar -jar bootstrap.jar
选择对应的jvm进程:
选择后命令行输出:
Attaching to target JVM with PID: 20971
Attached to target JVM and loaded Java agent successfully
被注入的java.lang.NullPointerException项目会在控制台打印:
easyByteCoder::[INFO ] 2020-08-24 10:55:26,599 method:io.manbang.easybytecoder.clientbootstrap.PluginClassLoaderFactory.createPluginClassLoader(PluginClassLoaderFactory.java:45)Adding 'file:/Users/xujie/work/ymm/doom-jar/simplecount.jar' to classloader
easyByteCoder::[INFO ] 2020-08-24 10:55:26,600 method:io.manbang.easybytecoder.clientbootstrap.PluginClassLoaderFactory.createPluginClassLoader(PluginClassLoaderFactory.java:45)Adding 'file:/Users/xujie/work/ymm/doom-jar/systemtime.jar' to classloader
easyByteCoder::[INFO ] 2020-08-24 10:55:26,600 method:io.manbang.easybytecoder.clientbootstrap.PluginClassLoaderFactory.createPluginClassLoader(PluginClassLoaderFactory.java:45)Adding 'file:/Users/xujie/work/ymm/doom-jar/bootstrap.jar' to classloader
easyByteCoder::[INFO ] 2020-08-24 10:55:26,600 method:io.manbang.easybytecoder.clientbootstrap.PluginClassLoaderFactory.createPluginClassLoader(PluginClassLoaderFactory.java:45)Adding 'file:/Users/xujie/work/ymm/doom-jar/doom-agent.jar' to classloader
easyByteCoder::[INFO ] 2020-08-24 10:55:26,600 method:io.manbang.easybytecoder.clientbootstrap.PluginClassLoaderFactory.createPluginClassLoader(PluginClassLoaderFactory.java:45)Adding 'file:/Users/xujie/work/ymm/doom-jar/acceleratepigeon.jar' to classloader
easyByteCoder::[INFO ] 2020-08-24 10:55:26,600 method:io.manbang.easybytecoder.clientbootstrap.PluginClassLoaderFactory.createPluginClassLoader(PluginClassLoaderFactory.java:45)Adding 'file:/Users/xujie/work/ymm/doom-jar/simpleattach.jar' to classloader
easyByteCoder::[INFO ] 2020-08-24 10:55:26,601 method:io.manbang.easybytecoder.clientbootstrap.PluginClassLoaderFactory.createPluginClassLoader(PluginClassLoaderFactory.java:45)Adding 'file:/Users/xujie/work/ymm/doom-jar/simplehotfix.jar' to classloader
easyByteCoder::[INFO ] 2020-08-24 10:55:26,601 method:io.manbang.easybytecoder.clientbootstrap.PluginClassLoaderFactory.createPluginClassLoader(PluginClassLoaderFactory.java:45)Adding 'file:/Users/xujie/work/ymm/doom-jar/common.jar' to classloader
easyByteCoder::[INFO ] 2020-08-24 10:55:26,601 method:io.manbang.easybytecoder.clientbootstrap.PluginClassLoaderFactory.createPluginClassLoader(PluginClassLoaderFactory.java:45)Adding 'file:/Users/xujie/work/ymm/doom-jar/start.sh' to classloader
easyByteCoder::[INFO ] 2020-08-24 10:55:26,623 method:io.manbang.easybytecoder.clientbootstrap.EasyByteCoderClientBootStrap.agentmain(EasyByteCoderClientBootStrap.java:122)initing plugin, name: io.manbang.easybytecoder.plugin.simplehotfix.SimplePlugin, jar path: /Users/xujie/work/ymm/doom-jar/simplehotfix.jar
easyByteCoder::[INFO ] 2020-08-24 10:55:26,642 method:io.manbang.easybytecoder.clientbootstrap.EasyByteCoderClientBootStrap.agentmain(EasyByteCoderClientBootStrap.java:129)adding transformer io.manbang.easybytecoder.traffichandler.annotation.process.AnnotationProcess$3
easyByteCoder::[INFO ] 2020-08-24 10:55:26,722 method:io.manbang.easybytecoder.traffichandler.DoTransformer.execute(DoTransformer.java:71)find transform method end [io/manbang/helloworld/HelloWorld#runPrint(io.manbang.helloworld.HelloWorld$UserModel)] .
easyByteCoder::[WARN ] 2020-08-24 10:55:26,723 method:io.manbang.easybytecoder.traffichandler.DoTransformer.execute(DoTransformer.java:52)skip method because methodModifier is null method:main
easyByteCoder::[WARN ] 2020-08-24 10:55:26,723 method:io.manbang.easybytecoder.traffichandler.DoTransformer.execute(DoTransformer.java:52)skip method because methodModifier is null method:loop
zhangsan
zhangsan
zhangsan
zhangsan
zhangsan
zhangsan
此时空指针异常被修复