• Icon: Task Task
    • Resolution: Unresolved
    • Icon: Minor Minor
    • None
    • 5.1.1
    • Testing

      Byteman instrumentation does not work with the IBM J9 JVM:- it fails with errors like the following:

      *** java.lang.instrument ASSERTION FAILED ***: "jvmtierror == JVMTI_ERROR_NOT_AVAILABLE" at JPLISAgent.c line: 1009
      Exception in thread "Attachment 59984" Agent failed to start!
      JVMJ9TI064E Agent initialization function Agent_OnAttach failed for library instrument, return code 102
      

      I will implement a workaround by disabling byteman when testing with this JVM.

            [JBTM-2440] Byteman tests fail when running with the IBM JVM

            I asked rhn-engineering-adinn to provide an opinion about whether it could be the annotation rather than the agent loading functionality that is the root cause of the problem and he suspects that it is most likely a bug in the dynamic agent loading behaviour in the J9 compiler.

            He also gave a good analysis of the issue which I am including here:

            I downloaded IBM's Java 7 SDK and tried to use it to build Byteman.
            That's enough to thoroughly test the use of the agent.

            The tests on the Byteman agent maven module are configured to install
            the agent from the command line using the -javaagent option (I do that
            rather than use the BMUnitRunner to auto-load because I don't want
            failures in BMUnit to stop the agent jar being built). These tests all
            worked ok. So, the IBM JDK does support all the functionality of the
            Byteman agent when you load it from the command line.

            The maven tests in the BMUnit maven module rely the BMUnitRunner
            annotation to auto-install the agent into an already running test JVM
            and this is what failed. The error output is attached. As you can see
            from the first exception trace the IBM JVM does implement dynamic
            loading – the Attach operation is fielded and J9 tries to install the
            agent by executing

            com.ibm.tools.attach.javaSE.Attachment.loadAgentLibrary

            If you look at the cause of the exception you can see that this
            eventually calls into

            org.jboss.byteman.agent.Main.premain

            which is the Byteman entry point. This tries to register its
            ClassFileTransformer (InstrumentationImpl.addTransformer) and at this
            point J9 blows up. It is objecting to the agent's request for the
            ClassFileTransformer to be installed as a 'retransformable' transformer.
            That means it wants to be able to handle retransformations of existing
            classes as well as being given a chance to modify newly loaded classes.

            This seems a tad odd because when the Byteman agent is loaded on the
            command line it also asks its ClassFileTransformer to be installed as a
            retransformable transformer. So, the refusal by J9 must be some sort of
            policy decision on its part. I suspect that this may be a performance
            hack – J9 may be willing to not perform certain optimizations in order
            to allow for retransformers if you install them from the get go but
            otherwise may decide to switch on optimizations that mean subsequent use
            of retransformers won't work. Whatever the reason IBM have done this you
            are snookered until you can get them to remove this restriction. n.b. it
            is a legitimate (i.e. JVMTI agent spec-compliant) behaviour but it's not
            exactly very useful. I will make eqnuiries to see if I can talk to
            someone in IBM and get this removed or, at least, find a way to relax it
            but I am not sure I will have any traction.

            I think there is only one workaround which will fix this if you want to
            use BMUnit on both OpenJDK/Oracle and IBM. You will need to switch to
            loading the agent from the command line (whatever JVM you are using). To
            do this you need to:

            i) install the agent on the command line of the test JVM by
            configuring java command line argument
            -javaagent:/path/to/byteman.jar=listener:true

            ii) stop BMUnit from loading the agent by adding adding the property
            setting -Dorg.jboss.byteman.contrib.bmunit.agent.inhibit

            n.b. you will need to build the path to the byteman jar by referencing
            the relevant dependency in your maven repo dir. you should be able to do
            that using by substituting maven property values (repo dir + byteman
            dependency version) into the path

            n.b. if you don't do the load yourself then you may want to set some
            other -javaagent options and/or Byteman system properties. The auto load
            will do the equivalent of adding boot:/path/to/byteman.jar to the
            -javaagent line and adding -Dorg.jboss.byteman.allow.config.update as a
            system property setting. The former allows you to inject into JDK
            runtime classes. The latter allows BMUnit to pay heed to your any
            options specified using a BMUnitConfig annotation on your test class.

            regards,

            Andrew Dinn

            Michael Musgrove added a comment - I asked rhn-engineering-adinn to provide an opinion about whether it could be the annotation rather than the agent loading functionality that is the root cause of the problem and he suspects that it is most likely a bug in the dynamic agent loading behaviour in the J9 compiler. He also gave a good analysis of the issue which I am including here: I downloaded IBM's Java 7 SDK and tried to use it to build Byteman. That's enough to thoroughly test the use of the agent. The tests on the Byteman agent maven module are configured to install the agent from the command line using the -javaagent option (I do that rather than use the BMUnitRunner to auto-load because I don't want failures in BMUnit to stop the agent jar being built). These tests all worked ok. So, the IBM JDK does support all the functionality of the Byteman agent when you load it from the command line. The maven tests in the BMUnit maven module rely the BMUnitRunner annotation to auto-install the agent into an already running test JVM and this is what failed. The error output is attached. As you can see from the first exception trace the IBM JVM does implement dynamic loading – the Attach operation is fielded and J9 tries to install the agent by executing com.ibm.tools.attach.javaSE.Attachment.loadAgentLibrary If you look at the cause of the exception you can see that this eventually calls into org.jboss.byteman.agent.Main.premain which is the Byteman entry point. This tries to register its ClassFileTransformer (InstrumentationImpl.addTransformer) and at this point J9 blows up. It is objecting to the agent's request for the ClassFileTransformer to be installed as a 'retransformable' transformer. That means it wants to be able to handle retransformations of existing classes as well as being given a chance to modify newly loaded classes. This seems a tad odd because when the Byteman agent is loaded on the command line it also asks its ClassFileTransformer to be installed as a retransformable transformer. So, the refusal by J9 must be some sort of policy decision on its part. I suspect that this may be a performance hack – J9 may be willing to not perform certain optimizations in order to allow for retransformers if you install them from the get go but otherwise may decide to switch on optimizations that mean subsequent use of retransformers won't work. Whatever the reason IBM have done this you are snookered until you can get them to remove this restriction. n.b. it is a legitimate (i.e. JVMTI agent spec-compliant) behaviour but it's not exactly very useful. I will make eqnuiries to see if I can talk to someone in IBM and get this removed or, at least, find a way to relax it but I am not sure I will have any traction. I think there is only one workaround which will fix this if you want to use BMUnit on both OpenJDK/Oracle and IBM. You will need to switch to loading the agent from the command line (whatever JVM you are using). To do this you need to: i) install the agent on the command line of the test JVM by configuring java command line argument -javaagent:/path/to/byteman.jar=listener:true ii) stop BMUnit from loading the agent by adding adding the property setting -Dorg.jboss.byteman.contrib.bmunit.agent.inhibit n.b. you will need to build the path to the byteman jar by referencing the relevant dependency in your maven repo dir. you should be able to do that using by substituting maven property values (repo dir + byteman dependency version) into the path n.b. if you don't do the load yourself then you may want to set some other -javaagent options and/or Byteman system properties. The auto load will do the equivalent of adding boot:/path/to/byteman.jar to the -javaagent line and adding -Dorg.jboss.byteman.allow.config.update as a system property setting. The former allows you to inject into JDK runtime classes. The latter allows BMUnit to pay heed to your any options specified using a BMUnitConfig annotation on your test class. regards, Andrew Dinn

            Understood - works for me

            Tom Jenkinson added a comment - Understood - works for me

            Michael Musgrove added a comment - - edited

            This issue (JBTM-2440) is to capture the fact that the @BMUnitRunner annotation does not work with the IBM JVM. I don't know how to fix that so I have committed a workaround that adds a profile that disables byteman when running with the ibm JVM. Since I have provided a workaround my preference is to move "fix version" field to 5.later but leave the issue as unresolved.

            Whereas issue JBTM-2454 records the fact that the the localjunit-disabled-context-propagation-tests do not compile (at least on lancel) with the IBM compiler and is unrelated to the bug in the @BMUnitRunner annotation.

            Remark: the @BMUnitRunner annotation requires the ability to dynamically load an agent but it fails with the IBM JVM. The com.ibm.tools.attach.enable system property ought to allow that behaviour but it still fails and my personal feeling is that there is an issue with the annotation - but, as I say, it is a gut feeling since the annotation implementation seems to work with other JVMs

            Michael Musgrove added a comment - - edited This issue ( JBTM-2440 ) is to capture the fact that the @BMUnitRunner annotation does not work with the IBM JVM. I don't know how to fix that so I have committed a workaround that adds a profile that disables byteman when running with the ibm JVM. Since I have provided a workaround my preference is to move "fix version" field to 5.later but leave the issue as unresolved. Whereas issue JBTM-2454 records the fact that the the localjunit-disabled-context-propagation-tests do not compile (at least on lancel) with the IBM compiler and is unrelated to the bug in the @BMUnitRunner annotation. Remark: the @BMUnitRunner annotation requires the ability to dynamically load an agent but it fails with the IBM JVM. The com.ibm.tools.attach.enable system property ought to allow that behaviour but it still fails and my personal feeling is that there is an issue with the annotation - but, as I say, it is a gut feeling since the annotation implementation seems to work with other JVMs

            Hi Mike,

            Am I right in thinking that this should be fixed, but we still have JBTM-2454? If so it is worth closing this one.

            Thanks,
            Tom

            Tom Jenkinson added a comment - Hi Mike, Am I right in thinking that this should be fixed, but we still have JBTM-2454 ? If so it is worth closing this one. Thanks, Tom

            The IBM manual says

            The Attach API can be enabled by setting the com.ibm.tools.attach.enable system property to the value yes;

            I tried this but tests marked up with the @BMUnitRunner annotation still fail with the error JVMTI_ERROR_NOT_AVAILABLE

            I tried enabling it in the pom via:

            • systemPropertyVariables;
            • systemProperties; and
            • <argLine>-Dcom.ibm.tools.attach.enable=yes</argLine>

            none of which work.

            I am going to work around the issue using an ibm jdk profile that disables byteman tests.

            Michael Musgrove added a comment - The IBM manual says The Attach API can be enabled by setting the com.ibm.tools.attach.enable system property to the value yes; I tried this but tests marked up with the @BMUnitRunner annotation still fail with the error JVMTI_ERROR_NOT_AVAILABLE I tried enabling it in the pom via: systemPropertyVariables; systemProperties; and <argLine>-Dcom.ibm.tools.attach.enable=yes</argLine> none of which work. I am going to work around the issue using an ibm jdk profile that disables byteman tests.

            Hi Mike,

            I think you should raise a BYTEMAN issue and link it to this one to see if Andrew can add support for J9.

            Tom

            Tom Jenkinson added a comment - Hi Mike, I think you should raise a BYTEMAN issue and link it to this one to see if Andrew can add support for J9. Tom

            I am marking the jira as minor with the fix to add a new profile that disables all of the byteman tests.

            Michael Musgrove added a comment - I am marking the jira as minor with the fix to add a new profile that disables all of the byteman tests.

            I do recall - we disable the tests because byteman is known not to work with the IBM J9 compiler. So the fix is just to go back to not running the tests on J9 and figure out how to make byteman work with J9 as an optional task.

            Michael Musgrove added a comment - I do recall - we disable the tests because byteman is known not to work with the IBM J9 compiler. So the fix is just to go back to not running the tests on J9 and figure out how to make byteman work with J9 as an optional task.

            I not certain but diff'ing the config between now and the last successful build reveals that the tests were disabled NARAYANA_TESTS=0 on the sucessful build

            Michael Musgrove added a comment - I not certain but diff'ing the config between now and the last successful build reveals that the tests were disabled NARAYANA_TESTS=0 on the sucessful build

            Do you know why these only seemed to start failing when we upgraded to JDK8?

            Tom Jenkinson added a comment - Do you know why these only seemed to start failing when we upgraded to JDK8?

              Unassigned Unassigned
              rhn-engineering-mmusgrov Michael Musgrove
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

                Created:
                Updated: