Introduction to Byteman

Now let's see how you can run a Byteman rule when JBoss As triggers the execution of some classes. At first you need to activate Byteman on the JVM startup options (for example on JBoss AS 7 just add this to standalone.conf.bat)


set "JAVA_OPTS=%JAVA_OPTS% -Dorg.jboss.byteman.transform.all -javaagent:C:\byteman\lib\byteman.jar=script:example.btm,boot:C:\byteman\lib\byteman.jar,listener:true"

Now let's write an example.btm rule file (as stated in the startup options) which will dump on the console the com.sample.ByteServlet's query String:

 RULE trace Servlet

CLASS com.sample.ByteServlet

METHOD doGet

AT ENTRY
BIND request = $request;

IF true

DO traceln ("Query String " + request.getQueryString())

ENDRULE

As you can see, this simple rule does one more step compared with the first rule: it binds the doGet request parameter into the Rule's request variable. In the rule action the request's query string is printed.

Define any com.sample.ByteServlet Servlet and invoke it by passing some parameters (/ByteServlet?param1=boo&param2=foo )
As you can see, as soon as the Servlet is invoked you should see the Query String printed on the Console.

Now, let's write a slightly more complex rule:

 RULE trace Servlet

CLASS com.sample.ByteServlet

METHOD doGet
HELPER com.sample.Utility
AT ENTRY
BIND request = $request;

IF true

DO trace ($request)

ENDRULE

This rule includes an HELPER class which means that all the rules in the script will use this class in the Rule actions.
A rule's helper class is used to resolve built-in calls like the trace() method of the com.sample.Utility class, which merely does some request snooping:

package com.sample;

import java.util.Enumeration;
import javax.servlet.http.HttpServletRequest;


public class Utility {
    public void trace(HttpServletRequest request) {
        System.out.println("Called trace!");

        Enumeration e = request.getSession().getAttributeNames();
        while (e.hasMoreElements()) {
            String name = (String) e.nextElement();
            System.out.println(name + ": " + request.getSession().getAttribute(name));
        }

        System.out.println("Protocol: " + request.getProtocol());
        System.out.println("Scheme: " + request.getScheme());

        System.out.println("Server Port: " + request.getServerPort());

        System.out.println("Remote Addr: " + request.getRemoteAddr());
        System.out.println("Remote Host: " + request.getRemoteHost());

        System.out.println("Content Length: " + request.getContentLength());
        System.out.close();
    }
}

In this example, as soon as the doGet of the ByteServlet is invoked, the Uility's trace method is invoked, which receives as parameter the HttpServletRerquest. All this, has been done without one single change into the ByteServlet (!). Cool isn't it ?

Follow us on Twitter