Tip: Profile an OSGi application with VisualVM
Join the DZone community and get the full member experience.
Join For FreeWhen you develop applications and you have performance problems, it’s really interesting to see what can cause this problems. And in that case, profilers are the most useful tool. For example, we can use VisualVM, which is packaged by default with the Java Virtual Machine. For more information, you can read this introduction to Java VisualVM.
But, when you are working with an OSGi application, it’s not as simple as a normal application. The profiler needs that the class can be found by the profiled classes. But with OSGi, the classloader is restricted by the framework and the classes of the profiler cannot be found.
But there is a workaround using the boot class path and boot delegation. You need to do two things.
1. Add the classes to the boot class-path
First of all, the classes of the profiler must be present in the application. For that, we use the boot class-path. You must add this library in the boot class-path : ${VISUALVM_HOME}/profiler3/lib/jfluid-server.jar. The boot class-path is configured using the -Xbootclasspath option, but if you just add this option :
-Xbootclasspath:${VISUALVM_HOME}/profiler3/lib/jfluid-server.jar
The classes of the JRE will not be found and you will get this kind of error :
Error occurred during initialization of VM java/lang/NoClassDefFoundError: java/lang/Object
So we need to keep the default boot class-path. To get this, just launch this program :
public class BootClassPath {
public static void main(String[] args) {
System.out.println(System.getProperty("sun.boot.class.path"));
}
}
And it will give you the default boot class-path. Then, you just have to append it to the jar of VisualVM with ‘:’. For example, on my computer, it’s the option I need :
-Xbootclasspath:/usr/lib/jvm/java-6-sun-1.6.0.20/lib/visualvm/profiler3/lib/jfluid-server.jar:
/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/resources.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/
lib/rt.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/sunrsasign.jar:/usr/lib/jvm/
java-6-sun-1.6.0.20/jre/lib/jsse.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/jce.jar
:/usr/lib/jvm/java-6-sun-1.6.0.20/jre/lib/charsets.jar:/usr/lib/jvm/java-6-sun-1.6.0.20/
jre/classes
2. Add boot delegation to the OSGi framework
This is easier. Here you just have to make the classes of the profiler available to all bundles in the OSGi container. For that, you need to add this property :
-Dorg.osgi.framework.bootdelegation=org.netbeans.lib.profiler,org.netbeans.lib.profiler.*
And normally, it’s enough. But some OSGi containers, like Felix, don’t take the command line properties into consideration depending on how you launch it. In my case, I embed the Felix Server in my application, so I need to explicitly add this property to the framework. For that, read the documentation of the container to know how to add properties to the framework.
I hope this will be useful to someone. Personally, I lost a lot of time trying several configurations before finding this successful one.
From http://www.baptiste-wicht.com/2010/07/tip-profile-osgi-application-visualvm
Opinions expressed by DZone contributors are their own.
Comments