In a production or customer environment it is not always possible to identify issues by looking at logs, nor is it always possible to setup remote debugging using an integrated development environment (IDE) and remote debug port. Often the issues are specific to the environment and can't be reproduced. Having byteman scripts can help in these situations to identify issues without actual code changes. Whenever certain java class or logic is invoked, byteman scripts will also be invoked as per defined class and method in the byteman script.

Here are the steps to follow:

1.  Download Byteman binary here. I downloaded 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 the folder created after extracting binary.

4.  Content of this script would be:

RULE check authpassword
METHOD authenticate(java.lang.String, java.lang.String, org.apache.sshd.server.session.ServerSession)
IF true
traceOpen("file.out", "byteman.log");
traceln("file.out"," password: "+ $2);

Point to note here:

  • We want to analyse authenticate method of KarafJaasAuthenticator class. We want to check the value of the 2nd parameter, which is password.
  • We are using traceOpen so that traceln logs are finally written to byteman.log. If we don't use traceOpen, then traceln logs will be printed in Karaf's terminal, thus we might loose logs.

5.  In Red Hat JBoss Fuse, we have to edit file ${karaf.home}/etc/ and modify property org.osgi.framework.bootdelegation so that it include package 'org.jboss.byteman.*' as well, like below:


6.   Now edit ${karaf.home}/bin/setenv file and include JAVA_OPTS jvm argument as below. This argument refers to byteman jar and byteman script script.btm.

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"

7.  The purpose of this script is to check to see if the password entered for authentication is being passed correctly in code or not. Similarly, there may be other use-cases where one wants to check the code execution.

Actual java class which is invoked to login is:
Method invoked: public boolean authenticate(final String username, final String password, final ServerSession session)

These details we can get while troubleshooting issues. I found this class in DEBUG level logs. So troubleshooting always starts with logs.

8.  To test, first start Red Hat JBoss Fuse using start script.

[cpandey@cpandey bin]$ pwd
[cpandey@cpandey bin]$ ./start

9.  Now run the client script to access karaf terminal. Password we entered is 'wrongpassword'.

[cpandey@cpandey bin]$ ./client -u admin
Logging in as admin

10.  Now check byteman.log which we configured above in script file script.btm. We should get the password entered in logs.

[cpandey@cpandey jboss-fuse-6.3.0.redhat-310]$ pwd

[cpandey@cpandey jboss-fuse-6.3.0.redhat-310]$ tail -f byteman.log 
 password: wrongpassword

This example above was a real use-case. We can troubleshoot other issues if we want to get information from code where logs are not sufficient or not available. This has also been tested in Fabric environment.

That's it. Thanks for reading!

Take advantage of your Red Hat Developers membership and download RHEL today at no cost.


Last updated: January 12, 2018