Update February 2012
Use the following to easily use Byteman on AS7, using the HelloWorld quickstart:
-- Script to attach, check, and submit rule -----
#!/bin/bash
export JBOSS_HOME=/home/rick/Tools/JBoss_Org/jboss-as-7.0.2.Final
echo $JBOSS_HOME
export BYTEMAN_HOME=/home/rick/Tools/MISC_TOOLS/byteman-2.0/byteman-download-2.0.0
export BYTEMAN_BIN=$BYTEMAN_HOME/bin
# Only install once.....
# $BYTEMAN_BIN/bminstall.sh -b -Dorg.jboss.byteman.transform.all $JBOSS_HOME/jboss-modules.jar
export QS_HELLOWORLD_TGT=/home/rick/Tools/JBoss_Org/jboss-as-quickstarts-7.0.2.CR1/helloworld/target/classes
# check it
$BYTEMAN_BIN/bmcheck.sh -cp $QS_HELLOWORLD_TGT RicksScript.btm
# add the rule
$BYTEMAN_BIN/bmsubmit.sh RicksScript.btm
-------The Rule. Check the arbitrary Java code used! --------------
RULE trace main entry
CLASS org.jboss.as.quickstarts.helloworld.HelloService
METHOD createHelloMessage
AT ENTRY
IF true
#DO traceln("entering createHelloMessage")
#DO traceStack("found the caller!\n", 100)
DO System.out.println("Hey, I'm random java code!");
ENDRULE
-------------
Have you heard of Byteman? It's sort of like AOP-lite. With a small script and a lightly doctored startup command, you can have x-ray vision into your Java applications. You don't even have to alter your source code, and it's easy to use.
Here's a quick example. Let's say we have a Java application where some method is called at some point, and you want to know when that method is called and what's being passed to it.
So let's say we have an application that provides this output. (I'll show you the source code in a bit.)
-----------------------------------------------------------------
Suspects about to do stuff!
Thump! A murder happens!
Suspects done moving around!
-----------------------------------------------------------------
Well, we don't know much about who committed the crime, do we? (In fairness, we don't even know who the suspects are yet.) But how about if you had the source code? Then could you tell? I doubt it. Here's the source:
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class Clue {
private void makeMystery(){
List suspects = new ArrayList();
suspects.add("Colonel Mustard");
suspects.add("Mr. Green");
suspects.add("Miss Scarlet");
Random gen = new Random();
// determine the killer!
int theKiller = gen.nextInt(3);
System.out.println("Suspects about to do stuff!");
for (String suspect : suspects){
walkThroughKitchen(suspect);
// maybe commit the crime!
if (suspect.equals(suspects.get(theKiller))){
commitCrime(suspect);
}
walkThroughLibrary(suspect);
}
System.out.println("Suspects done moving around!");
}
private void walkThroughLibrary(String suspect) {
// walks through...
}
private void commitCrime(String suspect) {
System.out.println("Thump! A murder happens!");
}
private void walkThroughKitchen(String suspect) {
// walks through
}
public static void main(String[] args) {
Clue clue = new Clue();
clue.makeMystery();
}
}
I defy you to tell me who committed the crime! But with Byteman you can tell!
So let's set things up. Aside from downloading Byteman (found
here), you need to do a few things.
- Make your application into a jar (using jar -cvf someJar.jar *.class, perhaps). This is done as a convenience to make it easier to put on a classpath.
- Make a Byteman script, telling it what you want to see.
- Make a command-line script to invoke your application.
Step 1 should be familiar to most Java coders.
Step 2. For the above class, let's make a script like this:
# clue_script.txt - A simple script to intercept calls to a method
#
RULE Simple byteman example - watch a method
CLASS Clue
METHOD commitCrime(String)
AT EXIT
BIND THE_MURDERER = $1
IF TRUE
DO traceln("Caught the murderer! It was " + $1)
ENDRULE
Step 3. Add the necessary agent to your startup shell script.
java -javaagent:/home/rick/Tools/Examples/Byteman/byteman-1.3.0/lib/byteman.jar=script:clue_script.txt -classpath clue.jar Clue
Now when we run the script, we see this:
---------------------------------------------------------------
Suspects about to do stuff!
Thump! A murder happens!
Caught the murderer! It was Colonel Mustard
Suspects done moving around!
---------------------------------------------------------------
There we have it! Byteman has let us find out which arguments were being passed to that method, and we did it without altering the source for the application, without attaching a remote debugger, and without much trouble.
Byteman can do much more, though. It can provide stack traces on demand, it can inject faults for testing and other neat tricks. You can add an arbitrary Java helper .jar to help you do things-- just bind it with a "-b" option. Best of all, it doesn't cost anything. Check it out today,
here.
Happy Inspecting!