Runtime profiling and monitoring Java apps with btrace

May 28th, 2008

A the latest Genova JUG meeting last week there was much discussion about performance tuning and optimization, particularly of web applications. My mention of the recently released BTrace profiling tool was met with significant interested and I was asked to provide more details and references…

BTrace (where the ‘B’ stands for bytecode) is an open source tool hosted on java.net, where you can find extensive documentation and samples. It is conceptually similar to the much-talked-about Solaris DTrace platform, but can be used on any Java platform/app.

The main BTrace concept is that of dynamically connecting to a running Java application (or server) to attach short “scripts” which log a range of events and infos such as

  • method calls;
  • execution times;
  • constructor invocation;
  • available memory;

Script execution is tied to several situations

  • reaching a specific line number;
  • invoking a given method;
  • returning from a method;
  • invoking system calls (e.g. exit);
  • recurring timer (period execution at fixed intervals);
  • and many more

In a way, BTrace scripts are very similar to AOP’s aspects, but can be attached to any existing Java code (or better, bytecode) at runtime and without any configuration or modification at development time.

The scripts are simply Java classes which take advantage of methods from the btrace API, and are configured by using simple but powerful annotations. Here you are an hello world script which traces session creation in hibernate:

// import BTrace annotations
import com.sun.btrace.annotations.*;
// import logging methods
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class HelloWorldTrace {

// probe the openSession() method of Hibernate SessionFactory
@OnMethod(
clazz=”org.hibernate.SessionFactory”,
method=”openSession”
)
public static void onOpenSessionTrace() {
// you can only log using the stati println method from BTraceUtils
println(”Hibernate: opening a new session…”);
}
}

Btrace scripts are attached to the running process using the JVM’s instrumentation interface.

If you are using JDK 1.6, you can attach to any running jvm by simply specifying its pid obtained through the new jps command:

jps

18037 Demo.JAR
19032 jps
19025 tomcat

btrace 19025 HelloWorldTrace 

Hibernate: opening a new session...
Hibernate: opening a new session...

The last command is simply an utility batch file which actually compiles and attaches the script.: On the other hand, on previous JDKs it is necessary to enable tracing in a similar way to how you enable remote debugging.

As an example of BTrace power and ease of use, the following script from BTrace samples intercepts all calls to methods in classes which are annotated with @WebService (e.g. all JAX-WS web service classes) and logs theri execution times:

@BTrace public class WebServiceTracker {
// store webservice entry time in this thread local
@TLS private static long startTime;

@OnMethod(
clazz="@javax.jws.WebService",
method="@javax.jws.WebMethod"
)
public static void onWebserviceEntry() {
print("entering webservice ");
println(strcat(strcat(name(probeClass()), "."), probeMethod()));
startTime = timeMillis();
}

@OnMethod(
clazz="@javax.jws.WebService",
method="@javax.jws.WebMethod",
location=@Location(Kind.RETURN)
)
public static void onWebserviceReturn() {
println(strcat("Time taken (msec) ", str(timeMillis() - startTime)));
println("==========================");
}

}

Note the use of BTrace built-in strcat function, which is needed to avoid the overhead of string concatenation. Obviously, the script code must be as lightweight as possible to avoid influencing tracing results with its own execution times, and thus the BTrace API provides efficient implementations of basic logging tasks.

Stay tuned for more tracing examples…

Java IDE day 2008: big success in Genova!

March 12th, 2008

Just a quick post while we recover from the organization effort… I will write a more detailed report as soon as possible. The IDE day was a success, with a participation level that definitely went beyond our best expectations, both in terms of attendance (about 130 people!) and in term of audience interaction (the speakers were overwhelmed with questions!).

Presentation slides will be loaded on the http://www.ideday.org website in the next few days.

In the meantime I publish this picture of the speakers with the organizing group for Genova, which give me the opportunity to say a huge THANK YOU to everyone who made this event possible.

ideday2008

Java IDE day 2008 is coming!

February 14th, 2008

Thanks to a fruitful collaboration between the Genova Java User Group and Rome Java User Group the first Italian Java IDE day is a reality…

If you are interested in Java development (but not just java, as these IDEs interestingly support a range of languages) you can’t miss the event that will take place

  • monday 10 march 2008 in Genova
  • wednesday 12 march 2008 in Rome

where  international experts including Roman Strobl (Sun), Paolo Ramasso (Oracle) and Vaclav Pech (Jetbrains) will discuss the most advanced features of Java IDEs and their future evolution.

The event is free and open to all! for more information (and to register) visit http://www.ideday.org

See you there!

How to programmatically define Spring beans

January 22nd, 2008

The Spring framework is well know both for its powerful architecture and its often barely tolerated XML configuration syntax.So there are cases where you would like to take advantage of Spring features (Dependency Injection, scope management, AOP, Transaction Management) in a set of beans without having to declare all of them in XML. This is particularly the case where you need to define a non-trivial number of similar beans (e.g. DAOs, backing beans in a JSF application, etc.).

In practice, we want to be able to write something like

ApplicationContext context = new ClassPathXmlApplicationContext("application.xml");
SampleService s = (SampleService) context.getBean("sampleService");

(or the equivalent code in a webapp or servlet with a WebApplicationContext) so that s get initialized by Spring in the right scope without actually declaring sampleService in application.xml.

Thanks to Spring modularity, there are several ways of achieving this:

  • define the bean through annotations;
  • define a custom BeanDefinitionReader that reads from a property/configuration file instead of XML;
  • define the bean programmatically.

I will now describe how to do it with the third approach. With most kinds of ApplicationContexts, it is possible to use the BeanDefinitionRegistry interface to dynamically and programmatically declare beans:

BeanDefinition definition = new RootBeanDefinition(SampleService.class);
//optionally configure all bean properties, like scope, prototype/singleton, etc
context.registerBeanDefinition("sampleService", definition);

This allows you to manually add a bean definition to the context.

In order to fully automatize the configuration, we can define a BeanFactoryPostProcessor that is automatically invoked after the standard xml file is read, being thus able to automatically add more bean definitions. The bean definitions can be for instance created by scanning classes for custom annotations, scanning custom configuration files, or any other custom criteria.

The following example will create a bean for each *.service file in the config directory

import java.io.IOException;
import org.springframework.beans.BeansException;
 import org.springframework.beans.factory.config.BeanDefinition;
 import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
 import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
 import org.springframework.beans.factory.support.BeanDefinitionRegistry;
 import org.springframework.beans.factory.support.RootBeanDefinition;
 import org.springframework.context.ApplicationContext;
 import org.springframework.context.ApplicationContextAware;
 import org.springframework.context.ResourceLoaderAware;
 import org.springframework.core.io.Resource;
 import org.springframework.core.io.ResourceLoader;
public class AutoBeanDeclarer implements BeanFactoryPostProcessor, ApplicationContextAware
 {
      private ApplicationContext mainContext;
public void postProcessBeanFactory(ConfigurableListableBeanFactory context)
        throws BeansException
{
BeanDefinitionRegistry registry = ((BeanDefinitionRegistry)context);
Resource[] fileList = null;

 fileList = mainContext.getResources("config/*.service");
for (Resource file : fileList)
{
System.out.println("File found: "+file.getFilename());
BeanDefinition definition = new RootBeanDefinition(SampleServiceImpl.class);
registry.registerBeanDefinition(file.getFilename(), definition);
}
public void setApplicationContext(ApplicationContext mainContext)
 {
      this.mainContext = mainContext;
}
}

The BeanFactoryPostProcessor can then be simply added to the main application.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans
 http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
 http://www.springframework.org/schema/aop
 http://www.springframework.org/schema/aop/spring-aop-2.0.xsd">
<!-- note: no definition of SampleService  -->
<bean id="autoConfigurer" class="AutoBeanDeclarer"/>
</beans>

Spring will then automatically activate the PostProcessor after reading all configuration files.

A possible use in a web application could be that of automatically defining a bean for each html page/component. More examples will appear in future posts…

Thank you for your time! I hope you enjoyed this post. You can find more materials on Spring on the JUG Genova website.

Slides from the JUG Meeting and next Meeting (22/01/2008)

November 23rd, 2007

The last meeting of the Genova JUG was a very interesting event… you can have a look at the presentations on Model Driven Engineering in Portofino and Nasa World Wind with Java on the JUG Website.

The next meeting will take place on the 22th January 2008 at DIST.  More details will be announced soon…

Struts 1.x with Eclipse WTP How-To

November 15th, 2007

Given that Struts syntax is as difficult to remember as the framework is widespread in enterprise applications, I am posting a short How-To that I wrote for the last course  I taught on the topic.

The How-To summarizes the main steps required to define a new Web Application based on Struts 1.3.x using Eclipse Europa with WTP.

You can find it on

http://www.carlobonamico.com/docs/pmwiki.php/Java/Struts13HowTo

JUG meeting @ NIS - 20 november 2007

November 7th, 2007

The next Genova JUG meeting will take place as planned on the 20th november 2007 at NIS s.r.l. (Corso Torino 14/3, Genova). Paolo will talk about Model Driven Architecture in Java; a second talk is being defined.

For more information see http://www.juggenova.net and http://www.jugevents.org/jugevents/event/show.html?id=354.

Continuous Integration with Hudson

October 19th, 2007

Here is the presentation that I will deliver tomorrow at the Javaday Torino 2007.

Speaking at Javaday Torino 2007 - 20/10/2007

October 10th, 2007

I will be presenting at Javaday 2007 in Torino in ten days time, talking about Continuous Integration with Hudson. More details (and the talk slides…) will follow…

Introduzione a Spring - slides from the Genova JUG meeting @ DIST - 18/09/2007

September 24th, 2007

Here you are the slides from my talk (in Italian) about the Spring framework, co-presented with Corrado Alesso at the last Genova Java User Group meeting.

By the way, the next meeting will take place on the 20th November 2007.