Fixing BTrace on the Mac
BTrace and the issue
First... if you don't know what btrace is... you have to check it out. In the evolution of debugging tools for the jvm, it is the next big thing! Active in this space is A. Sundararajan, he has a couple of my favorite blogs, one on scripting btrace and another on jmx and btrace. Another great tutorial blog is by Igor Minar.
This blog isn't as much about btrace, as it is about fixing it on the mac. BTrace is new enough though, that it may require just a quick introduction. BTrace is a debugging tool, which injects "probes" (my term) into a running Java process. It is an open source option that has a high possibility of replacing Wily's Introscope. To be fair, Introscope provides a lot of extras which BTrace doesn't at this time... but Introscope is tens of thousands of dollars and BTrace is a free open source tool. I would be shaking in my boots if I was on the Wily team.
We will need to start a Java process in order to illustrate how it works (or in the case of the Mac... doesn't work). For the Java process look in the demo directory, there is a Java2D.jar. On the Mac it is located: /Developer/Examples/Java/JFC/Java2D. At the comand-line type: java -jar Java2D.jar. This will start up a Java process. To get it's pid at another command-line type: jps
If this is the only Java process running on your box, the pid with the jar notation is the pid you are interested in. If you want to be 100% certain type: jps -l . You'll get something like:
7897 sun.tools.jps.Jps
7838 Java2D.jar
Now in the btrace bin directory (I'm assuming you followed one of the referenced tutorials), for our example type: ./btrace 7838 ../samples/ThreadCounter.java . To which you will get:
Connection refused
In the terminal of the running Java process for the jar you would likely see:
btrace DEBUG: adding to boot classpath failed!
btrace DEBUG: java.util.zip.ZipException: error in opening zip file
java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.
at java.util.jar.JarFile.
at java.util.jar.JarFile.
at com.sun.btrace.agent.Main.main(Main.java:108)
at com.sun.btrace.agent.Main.agentmain(Main.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:348)
Yea... epic fail! That is BTrace failing on the mac. If you want more details, go to the btrace script and edit -Dcom.sun.btrace.debug=false to be true. This will indicate the following stacktrace:
btrace DEBUG: debugMode is true
btrace DEBUG: dumpClasses is true
btrace DEBUG: dumpDir is .
btrace DEBUG: probe descriptor path is .
btrace DEBUG: parsed command line arguments
btrace DEBUG: System ClassPath: /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/tools.jar
btrace DEBUG: adding to boot classpath failed!
btrace DEBUG: java.util.zip.ZipException: error in opening zip file
java.util.zip.ZipException: error in opening zip file
at java.util.zip.ZipFile.open(Native Method)
at java.util.zip.ZipFile.
at java.util.jar.JarFile.
at java.util.jar.JarFile.
at com.sun.btrace.agent.Main.main(Main.java:108)
at com.sun.btrace.agent.Main.agentmain(Main.java:66)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:323)
at sun.instrument.InstrumentationImpl.loadClassAndCallAgentmain(InstrumentationImpl.java:348)
The line just above the fail point... hmmm.... it is looking for a tools.jar in the $JAVA_HOME/lib directory. As already noted, Apple likes to slice and dice the JDK... In trying to understand the issue, I uncovered an article released by Apple which says there is no tools.jar file... no tools.jar file!!! It is a classes.jar file and to make it fun it isn't in the $JAVA_HOME/lib directory... no, it isn't even under a subdirectory of $JAVA_HOME... I can't even write that without frothing at the mouth. I could start a rant here... but I'm assuming I'm writing to the choir so to speak.
Fixing the Issue
I didn't spend a significant amount of time on it... but I didn't get this working by changing the btrace scripts... something is in the code. I have another recommendation towards the end that the script change wouldn't work for as well. So we are left currently with the following work around.
Take the classes.jar and copy it to the lib directory as tools.jar (argghhh!!!) but it works. To be more specific... /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Classes/classes.jar to /System/Library/Frameworks/JavaVM.framework/Versions/1.6/Home/lib/tools.jar. It is important to note that you have to be sudo to make this change and you will have to do this with each Java version you want this to work with. Let's hope that the next version of BTrace will be Mac friendly!
After you get that working... checkout visualvm with the BTrace plugin. It is great stuff and another reason that the script change alone is not a total solution.
Other Issues
OMG... I'm frick'n shaving the yak again... just as I'm getting ready to post this... I was about to trace a grails app. The changes described above, break Groovy and Grails. So pick one :) You can be Groovy or you can BTrace but you can't have both yet. I guess I'll begin digging through code and send a patch tonight...
About Ken Sipe
Ken has been a practitioner and instructor of RUP since the late 1990s, and an extreme programmer and coach since the middle 2000s. Ken has worked with Fortune 500 companies to small startups in the roles of developer, designer, application architect and enterprise architect. Ken's current focus is on enterprise system automation and continuous delivery systems.
Ken is an international speaker on the subject of software engineering speaking at conferences such as JavaOne, JavaZone, Jax-India, and The Strange Loop. He is a regular speaker with NFJS where he is best known for his architecture and security hacking talks. In 2009, Ken was honored by being awarded the JavaOne Rockstar Award at JavaOne in SF, California and the JavaZone Rockstar Award at JavaZone in Oslo, Norway as the top ranked speaker.
More About Ken »Why Attend the NFJS Tour?
- » Cutting-Edge Technologies
- » Agile Practices
- » Peer Exchange
Current Topics:
- Languages on the JVM: Scala, Groovy, Clojure
- Enterprise Java
- Core Java, Java 7
- Agility
- Testing: Geb, Spock, Easyb
- REST
- NoSQL: MongoDB, Cassandra
- Hadoop
- Spring 3
- Automation Tools: Git, Hudson, Sonar
- HTML5, Ajax, jQuery, Usability
- Mobile Applications - iPhone and Android
- More...
NFJS, the Magazine
May Issue Now AvailableClient-Side MVC with Spine.js, Part 1
by Craig WallsOn Prototypal Inheritance, Part 2
by Raju GandhiMaking use of Scala Lazy Collections
by Venkat SubramaniamIntegration Testing Web Applications Using Gradle
by Kenneth Kousen


