Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Enabling Byteman Script With Red Hat JBoss Fuse and AMQ - Part 2

DZone's Guide to

Enabling Byteman Script With Red Hat JBoss Fuse and AMQ - Part 2

In this post, we look at how to use a Java helper class to integarte Byteman Script with the open source JBoss Fuse and JBoss AMQ tools.

Free Resource

Download Microservices for Java Developers: A hands-on introduction to frameworks and containers. Brought to you in partnership with Red Hat.

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 downloaded version 3.0.10.

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

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

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 the class,
org.apache.karaf.management.JaasAuthenticator, with the 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 I can modify or fetch details easily.

5. Below is the content of the BytemanHelper class. Here we have a helperMethod, which is invoked via tje 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 the location of the 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 the 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 the JAVA_OPTS JVM argument as below. This argument refers to the byteman jar and the byteman script script.btm. Replace /path/to with a path where the 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.

Download Building Reactive Microservices in Java: Asynchronous and Event-Based Application Design. Brought to you in partnership with Red Hat

Topics:
integration ,jboss ,byteman script

Published at DZone with permission of

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}