Byte Buddy - 带 ByteBuddyAgent 的 HotSwap
Byte Buddy - HotSwap with ByteBuddyAgent
我正在尝试使用字节好友的 HotSwap 功能。不幸的是我收到了一些错误。我已阅读有关 official website 的文档,我知道它仅在程序使用 Java 代理时有效。我尝试将 -javaagent 参数放在 Java 虚拟机的启动上,如下所示:
-javaagent:C:\lib\byte-buddy-agent-0.5.6.jar
这会在启动我的应用程序时产生以下错误:
java.lang.ClassNotFoundException:
net.bytebuddy.agent.ByteBuddyAgent.Installer
FATAL ERROR in native method: processing of -javaagent failed
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at
java.lang.ClassLoader.loadClass(ClassLoader.java:424) at
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at
java.lang.ClassLoader.loadClass(ClassLoader.java:357) at
sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
at
sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
Exception in thread "main" Java Result: 1
尽管如此,我尝试使用 ByteBuddyAgent.installOnOpenJDK()
方法而不是 -javaagent 参数,希望能解决问题。但这会引发以下错误,这取决于我认为的相同问题:
java.lang.ClassNotFoundException: net.bytebuddy.agent.ByteBuddyAgent$Installer
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:411)
Apr 09, 2015 1:35:01 PM net.bytebuddy.agent.ByteBuddyAgent doInstall
INFORMATION: Cannot delete temporary file: C:\Users\Flo\AppData\Local\Temp\byteBuddyAgent4745240427430305215.jar
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1770)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1653)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
...
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
...
Caused by: java.lang.IllegalStateException: The programmatic installation of the Byte Buddy agent is only possible on the OpenJDK and JDKs with a compatible 'tools.jar'
at net.bytebuddy.agent.ByteBuddyAgent.installOnOpenJDK(ByteBuddyAgent.java:176)
at hotswapping.FXMLDocumentController.handleByteBuddyButton(FXMLDocumentController.java:90)
... 60 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at net.bytebuddy.agent.ByteBuddyAgent.doInstall(ByteBuddyAgent.java:199)
at net.bytebuddy.agent.ByteBuddyAgent.installOnOpenJDK(ByteBuddyAgent.java:174)
... 61 more
Caused by: com.sun.tools.attach.AgentInitializationException: Agent JAR loaded but agent failed to initialize
at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:121)
... 67 more
有谁知道问题出在哪里,或者我是否误解了教程中的某些内容?顺便说一句,我用 jdk1.7.0_55 和 jdk1.8.0_40 尝试过,并使用 neatbeans 作为 ide。我使用的byte buddy版本是v0.5.6。
感谢您的帮助。
编辑:
看来-javaagent参数的错误是当前版本的bug,感谢Rafael Winterhalter的快速回复
我也弄清楚了 ByteBuddyAgent.installOnOpenJDK()
方法的问题所在。我的 side 犯了一个非常愚蠢的错误。似乎我的 netbeans 使用较旧的 java 版本作为 jdk1.8.0_40,所以我更改了 netbeans 等文件夹中 netbeans.conf
文件中的 netbeans_jdkhome
变量。既然我的 netbeans 使用与我的项目相同的 java 版本,它似乎非常适合 JavaFX 应用程序。唯一奇怪的是这个错误只发生在 JavaFX 应用程序中,在正常的 Java 应用程序中我从来没有遇到过这个问题。仅供参考:这是我的 JavaFX 应用程序的代码示例:
package testbytebuddy;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import net.bytebuddy.agent.ByteBuddyAgent;
public class TestByteBuddy extends Application {
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Start application");
ByteBuddyAgent.installOnOpenJDK();
launch(args);
System.out.println("End application");
}
}
直接使用代理的问题是 Byte Buddy 中的一个错误,我在其中引用代理的主要 class 和 net.bytebuddy.agent.ByteBuddyAgent.Installer
而不是 net.bytebuddy.agent.ByteBuddyAgent$Installer
,因为它是正确的。这将在 4 月底/5 月初发布的 Byte Buddy 0.5.7 中修复。
对于第二个错误,您似乎使用了不允许代理程序附件的捆绑 JDK。很难在类似的错误消息中看到此结果。然而,编程附件可能会出错,因此很难提供有关实际原因的更详细信息。很好,你明白了。
这个答案已经在评论中解决了,这应该作为未来潜在读者的概述。
我正在尝试使用字节好友的 HotSwap 功能。不幸的是我收到了一些错误。我已阅读有关 official website 的文档,我知道它仅在程序使用 Java 代理时有效。我尝试将 -javaagent 参数放在 Java 虚拟机的启动上,如下所示:
-javaagent:C:\lib\byte-buddy-agent-0.5.6.jar
这会在启动我的应用程序时产生以下错误:
java.lang.ClassNotFoundException:
net.bytebuddy.agent.ByteBuddyAgent.Installer
FATAL ERROR in native method: processing of -javaagent failed
at java.net.URLClassLoader.findClass(URLClassLoader.java:381) at
java.lang.ClassLoader.loadClass(ClassLoader.java:424) at
sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331) at
java.lang.ClassLoader.loadClass(ClassLoader.java:357) at
sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
at
sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:401)
Exception in thread "main" Java Result: 1
尽管如此,我尝试使用 ByteBuddyAgent.installOnOpenJDK()
方法而不是 -javaagent 参数,希望能解决问题。但这会引发以下错误,这取决于我认为的相同问题:
java.lang.ClassNotFoundException: net.bytebuddy.agent.ByteBuddyAgent$Installer
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:304)
at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:411)
Apr 09, 2015 1:35:01 PM net.bytebuddy.agent.ByteBuddyAgent doInstall
INFORMATION: Cannot delete temporary file: C:\Users\Flo\AppData\Local\Temp\byteBuddyAgent4745240427430305215.jar
Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException
at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1770)
at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1653)
at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238)
at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191)
...
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
...
Caused by: java.lang.IllegalStateException: The programmatic installation of the Byte Buddy agent is only possible on the OpenJDK and JDKs with a compatible 'tools.jar'
at net.bytebuddy.agent.ByteBuddyAgent.installOnOpenJDK(ByteBuddyAgent.java:176)
at hotswapping.FXMLDocumentController.handleByteBuddyButton(FXMLDocumentController.java:90)
... 60 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at net.bytebuddy.agent.ByteBuddyAgent.doInstall(ByteBuddyAgent.java:199)
at net.bytebuddy.agent.ByteBuddyAgent.installOnOpenJDK(ByteBuddyAgent.java:174)
... 61 more
Caused by: com.sun.tools.attach.AgentInitializationException: Agent JAR loaded but agent failed to initialize
at sun.tools.attach.HotSpotVirtualMachine.loadAgent(HotSpotVirtualMachine.java:121)
... 67 more
有谁知道问题出在哪里,或者我是否误解了教程中的某些内容?顺便说一句,我用 jdk1.7.0_55 和 jdk1.8.0_40 尝试过,并使用 neatbeans 作为 ide。我使用的byte buddy版本是v0.5.6。 感谢您的帮助。
编辑:
看来-javaagent参数的错误是当前版本的bug,感谢Rafael Winterhalter的快速回复
我也弄清楚了 ByteBuddyAgent.installOnOpenJDK()
方法的问题所在。我的 side 犯了一个非常愚蠢的错误。似乎我的 netbeans 使用较旧的 java 版本作为 jdk1.8.0_40,所以我更改了 netbeans 等文件夹中 netbeans.conf
文件中的 netbeans_jdkhome
变量。既然我的 netbeans 使用与我的项目相同的 java 版本,它似乎非常适合 JavaFX 应用程序。唯一奇怪的是这个错误只发生在 JavaFX 应用程序中,在正常的 Java 应用程序中我从来没有遇到过这个问题。仅供参考:这是我的 JavaFX 应用程序的代码示例:
package testbytebuddy;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.StackPane;
import javafx.stage.Stage;
import net.bytebuddy.agent.ByteBuddyAgent;
public class TestByteBuddy extends Application {
@Override
public void start(Stage primaryStage) {
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction(new EventHandler<ActionEvent>() {
@Override
public void handle(ActionEvent event) {
System.out.println("Hello World!");
}
});
StackPane root = new StackPane();
root.getChildren().add(btn);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
System.out.println("Start application");
ByteBuddyAgent.installOnOpenJDK();
launch(args);
System.out.println("End application");
}
}
直接使用代理的问题是 Byte Buddy 中的一个错误,我在其中引用代理的主要 class 和 net.bytebuddy.agent.ByteBuddyAgent.Installer
而不是 net.bytebuddy.agent.ByteBuddyAgent$Installer
,因为它是正确的。这将在 4 月底/5 月初发布的 Byte Buddy 0.5.7 中修复。
对于第二个错误,您似乎使用了不允许代理程序附件的捆绑 JDK。很难在类似的错误消息中看到此结果。然而,编程附件可能会出错,因此很难提供有关实际原因的更详细信息。很好,你明白了。
这个答案已经在评论中解决了,这应该作为未来潜在读者的概述。