Enabling Byteman Script with Red Hat JBoss Fuse and AMQ – Part 2

In my previous article, Enabling Byteman Script with Red Hat JBoss Fuse and AMQ – Part 1, we found a basic use-case for Byteman scripts with Red Hat JBoss Fuse or Red Hat JBoss AMQ. However, the log file was generated separately and only limited operations were possible. In this article I will show you how to use a Java helper class. By using Java, we get advanced operations to view or modify the content. Also, using java.util.logging allows us to log the statements to fuse.log, avoiding the creation of any other log file.

Most of the steps are the same as my previous article, except for the Helper class. For completeness, I am including all the steps.

1. Download Byteman binary from downloads.jboss.org/byteman. I download version 3.0.10.

2. Extract it in the same machine where Red Hat JBoss Fuse exists.

3. Once extracted, create a text file (byteman script) script.btm file at location /path/to/byteman-download-3.0.10. Here byteman-download-3.0.10 is in the folder created after extracting binary. Content of this script:

HELPER com.myexample.helper.BytemanHelper
RULE check authpassword
CLASS org.apache.karaf.management.JaasAuthenticator
METHOD authenticate(java.lang.Object)
BIND msg = $1
AT ENTRY
IF TRUE
DO
helperMethod(msg);
ENDRULE

Points to note here.

  • We are using a helper class:
    com.myexample.helper.BytemanHelper.
  • This class is a simple java class which extends:
    org.jboss.byteman.rule.helper.Helper.
  • We have a method ‘helperMethod’ in this class, which we execute using this script.

4. What we want to do here is have class:
org.apache.karaf.management.JaasAuthenticator
with method:
public Subject authenticate(Object credentials).
This method extracts the username and password from the credentials argument which is an Object type. In this method, the credentials are fetched from the String type.

final String[] params = (String[]) credentials;

In my previous article, I didn’t find a way to achieve this using just the Byteman script.  Instead, I used a HELPER class so that using the Java provided utilities that I can modify or fetch details easily.

5. Below is the content of BytemanHelper class. Here we have a helperMethod, which is invoked via Byteman script ‘script.btm’, which we created above. This method gets a String array from the Java Object and logs it.

package com.myexample.helper;

import java.util.logging.Logger;
import org.jboss.byteman.rule.Rule;
import org.jboss.byteman.rule.helper.Helper;

public class BytemanHelper
extends Helper
{
Logger logger;

protected BytemanHelper(Rule rule)
{
super(rule);
this.logger = Logger.getLogger(rule.getTriggerClass() + ":" + rule.getTriggerMethod());
}

public void helperMethod(Object object)
{
String[] params = (String[])object;
this.logger.info("Byteman fetched username: " + params[0]);
this.logger.info("Byteman fetched Password: " + params[1]);
}
}

 

6. Now we have to create a Jar file with this class and the complete package structure. You can export the project as a Jar from your favorite IDE, I used Eclipse.  Or, you can easily create this from the terminal as well. Go to location of package in the project, I executed the following command within the src folder where my package com.myexample.helper exists.

[cpandey@cpandey src]$ jar cvf BytemanFuseHelper.jar .

 

7. Now edit ${karaf.home}/etc/config.properties and modify org.osgi.framework.bootdelegation property so that it also includes org.jboss.byteman package:

org.osgi.framework.bootdelegation=org.apache.karaf.jaas.boot,org.apache.karaf.management.boot,sun.*,com.sun.*,javax.transaction,javax.transaction.*,javax.xml.crypto,javax.xml.crypto.*,org.apache.xerces.*,org.bouncycastle.*,com.ibm.security.*,org.apache.xalan.processor, org.jboss.byteman.*

 

8. Now edit ${karaf.home}/bin/setenv (or setenv.bat for windows) and include JAVA_OPTS jvm argument as below. This argument refers to byteman jar and byteman script script.btm. Replace /path/to with path where byteman zip file is extracted.

export JAVA_OPTS="-javaagent:/path/to/byteman-download-3.0.10/lib/byteman.jar=script:/path/to/byteman-download-3.0.10/script.btm,boot:/path/to/byteman-download-3.0.10/lib/byteman.jar,sys:/path/to/BytemanFuseHelper.jar -Dorg.jboss.byteman.verbose"

Note: You have to add the path of the helper sys:/path/to/BytemanFuseHelper.jar jar as well with sys: prefix.

9. To test, first start Red Hat JBoss Fuse using the start script:

[cpandey@cpandey bin]$ pwd
/path/to/jboss-fuse-6.3.0.redhat-310/bin
[cpandey@cpandey bin]$ ./start

10. Now start or stop the child container, check fuse.log in the root container where our modifications were done.

11. Now check fuse.log. We should see the password entered in logs. We can now check that the user and password were updated.


2018-01-01 12:22:33,429 | INFO | on(12)-127.0.0.1 | JaasAuthenticator:authenticate | - - | Byteman fetched username: admin
2018-01-01 12:22:33,429 | INFO | on(12)-127.0.0.1 | JaasAuthenticator:authenticate | - - | Byteman fetched Password: cs1

 

That’s it, thank you for reading. I hope you now understand why we need a helper class and how it was different and better than the approach in my previous article.

Share