grill2010
grill2010

Reputation: 614

Byte Buddy - HotSwap with ByteBuddyAgent

I'm trying to use the HotSwap feature of byte buddy. Unfortunately I receive some errors. I have read the documentation on the official website, and I'm aware that it only works when the program use a Java agent. I have tried to put -javaagent parameter on the startup of the Java virtual machine which looks like this:

-javaagent:C:\lib\byte-buddy-agent-0.5.6.jar

This produces the following error when starting my application:

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

Nevertheless I tried use the ByteBuddyAgent.installOnOpenJDK() method instead of the -javaagent parameter in hope that will solve the problem. But this throws following error, which relies on the same problem I think:

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

Does anyone know what is the problem or have I misunderstood something from the tutorial? Btw I tried it with jdk1.7.0_55 and jdk1.8.0_40 and use neatbeans as ide. Version of byte buddy which I am using is v0.5.6. Thanks for helping.

EDIT:

It seems that the error with the -javaagent parameter is a bug in the current version, thanks Rafael Winterhalter for the quick response.

I also figured out what was problem with the ByteBuddyAgent.installOnOpenJDK() method. It was a really stupid mistake from my side. It seems my netbeans use an older java version as jdk1.8.0_40, so I changed the netbeans_jdkhome variable in the netbeans.conf file in the etc folder of netbeans. Now that my netbeans use the same java version as my projects it seems that it works like a charm even with JavaFX applications. The only strange thing is that this error occurred only in JavaFX applications, in normal Java applications I never had this problems. FYI: Here is the code sample of my JavaFX application:

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");

    }

}

Upvotes: 2

Views: 1999

Answers (1)

Rafael Winterhalter
Rafael Winterhalter

Reputation: 44032

The problem with using the agent directly is a bug in Byte Buddy where I reference the agent's main class with net.bytebuddy.agent.ByteBuddyAgent.Installer and not with net.bytebuddy.agent.ByteBuddyAgent$Installer as it would be correct. This will be fixed for Byte Buddy 0.5.7 which should be released at the end of April / beginning of Mai.

For the second error, it seems like you used a bundled JDK that does not allow the programmatic attachment of the agent. It was difficult to see as this resultet in a similar error message. The programmatic attachment is however something that can go wrong, therefore it is difficult to provide more detailed information on the actual cause. Good you figured it out.

This answer was already solved in the comments, this should serve as an overview for potential future readers.

Upvotes: 2

Related Questions