JRebel运行时挂载提示_Agent_OnAttach@12缺失如何解决?
问题原因
报错核心是JRebel的原生库jrebel64.dll没有暴露动态attach所需的标准导出函数_Agent_OnAttach@12。JRebel默认仅支持JVM启动时通过-javaagent参数加载,原生侧没有适配运行时动态挂载的场景,所以直接用attach API挂载会失败。
可行绕过方案
方案1:启动时预加载JRebel并设为禁用状态,初始化完成后手动启用
该方案兼容性最高,也是官方支持的延迟启用方式。JVM启动时添加以下参数:-javaagent:C:\JRebel\lib\jrebel.jar -Drebel.env.disabled=true等你的程序特定初始化步骤全部执行完成后,通过反射调用JRebel内部API启用即可:
// 初始化完成后执行 Class<?> rebelFactoryClazz = Class.forName("org.zeroturnaround.javarebel.RebelFactory"); Object rebelInstance = rebelFactoryClazz.getMethod("getInstance").invoke(null); rebelInstance.getClass().getMethod("enable").invoke(rebelInstance);方案2:自定义中间代理桥接加载
先用ByteBuddy挂载你自己开发的自定义代理,在自定义代理的agentmain方法中直接调用JRebel的Java侧初始化入口,跳过原生attach的步骤:// 自定义代理agentmain方法内的逻辑 Class<?> jrebelMainClazz = Class.forName("org.zeroturnaround.javarebel.Main"); jrebelMainClazz.getMethod("premain", String.class, java.lang.instrument.Instrumentation.class) .invoke(null, "JRebel启动参数(无则填null)", instrumentation);注意需要提前将JRebel的jar包放入目标进程的类路径,或者打包进自定义代理的类路径中。
方案3:使用JRebel远程模式实现等效效果
JVM启动时添加参数-javaagent:C:\JRebel\lib\jrebel.jar -Drebel.remote=true,初始化完成后通过JRebel的远程通信接口触发全量类重加载,即可达到和延迟挂载一致的效果。
注意事项
- 不同版本JRebel的内部API可能存在差异,若反射调用失败可对应你使用的版本调整API路径
- JDK9及以上版本需要提前为JRebel开放
java.instrument等必要模块的访问权限,避免模块隔离导致类加载失败
内容的提问来源于stack exchange,提问作者Jire
相关产品推荐
相关产品推荐

