Simple startup profiling of OSGi applications

October 18, 2013

Prompted by a colleague’s question about profiling the startup time of Apache Sling systems, I vaguely remembered writing something a while ago, but couldn’t find it immediately.

Funny how one’s memory works – it took me a while to find it again, but I did indeed write an OSGi events recorder + timeline utility in SLING-1109.

That utility has since moved to the Apache Felix webconsole events plugin bundle, which is included in the Sling launchpad and thus was right here under my eyes.

Here’s how you can use that webconsole plugin to get a simple timeline of an OSGi system’s startup:

  1. Install the org.apache.felix.webconsole.plugins.event bundle in an OSGi app where the Apache Felix Webconsole is active.
  2. Set that bundle to a low start level, say 1 or 2, so that it’s activated early and captures as much startup events as possible.
  3. Configure the events recorder at /system/console/configMgr/org.apache.felix.webconsole.plugins.event.internal.PluginServlet, setting the number of events to capture high enough to record your app’s startup.
  4. Start your app.
  5. Look at the startup timeline at /system/console/events

This provides a simple graphical timeline, as shown on the screenshot below, that’s especially useful in detecting outlier bundles or services that take a long time to start up.

Webconsole Events plugin screenshot


MANIFEST.MF must be the first resource in a jar file – here’s how to fix broken jars

November 15, 2011

Some tools, like the Sling OSGi Installer, require the MANIFEST.MF to be the first file in a jar file, or they won’t find it.

This happens when using the java.util.jar.JarInputStream class to read a jar’s manifest, for example.

The manifest is where OSGi bundle headers are found, for example, so not having it in the right place makes the jar unusuable as a bundle.

I won’t discuss here whether this requirement is part of the jar file spec (it would make sense, as this makes sure you can read it quickly even from a huge jar file), but anyway there are many cases where this is required.

To fix a jar where this is not the case, you need to unpack the jar and recreate it, as in this example, starting from a broken.jar in the current directory:

$ mkdir foo
$ cd foo
$ jar xvf ../broken.jar
$ mv META-INF/MANIFEST.MF /tmp/mymanifest
$ jar cvfm fixed.jar /tmp/mymanifest .

That’s it – creating the new jar with the jar utility puts the MANIFEST.MF in the right place.


Transforming Maven POM properties with Groovy

February 11, 2011

We’re moving to fragment bundles in Sling instead of using system properties, for example to export packages from the JVM’s classpath.

If you have no idea what I’m talking about, bear with me – this is just about a simple Maven trick to transform POM properties using bits of Groovy script.

Basically, an OSGi fragment bundle is a jar file that contains just metadata under META-INF, especially META-INF/MANIFEST.MF that contains the OSGi bundle headers.

One of these headers is Bundle-Version, which does not support values like 5.4.2-SNAPSHOT which are common in Maven. The dash is invalid in an OSGi bundle version number, that value needs to be converted to 5.4.2.SNAPSHOT

To avoid having a separate bundle.version property in your POM, which if you’re like me you’ll forget to update before a release, here’s how to transform the value using a bit of Groovy scripting:

<plugin>
  <groupId>org.codehaus.groovy.maven</groupId>
  <artifactId>gmaven-plugin</artifactId>
  <version>1.0</version>
  <executions>
    <execution>
      <phase>generate-resources</phase>
        <goals>
          <goal>execute</goal>
      </goals>
      <configuration>
      <properties>
        <rawVersion>${pom.version}</rawVersion>
      </properties>
      <source>
        // Convert POM version to valid OSGi version identifier
        project.properties['osgi.version'] = 
          (project.properties['rawVersion'] =~ /-/).replaceAll('.')
      </source>
    </configuration>
  </execution>
 </executions>
</plugin>  

As usual in Maven POMs (though I think Maven 3.x can improve on that, feedback welcome) that’s a bit verbose to write, the actual Groovy code is just

project.properties['osgi.version'] = 
  (project.properties['rawVersion'] =~ /-/).replaceAll('.')

But even with the verbosity it’s cool to be able to do that without having to write a plugin. You can then use the ${osgi.version} property for the Bundle-Version header.

For the sake of completeness, here’s the other interesting part of that pom, which sets the required OSGi headers to create a fragment bundle. com.example,whatever is the package that we need to be exported by the system bundle.

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <configuration>
    <archive>
      <index>true</index>
      <manifest>
        <addClasspath>false</addClasspath>
      </manifest>
      <manifestEntries>
        <Bundle-Version>${osgi.version}</Bundle-Version>
        <Bundle-Description>${project.description}</Bundle-Description>
        <Bundle-Name>${project.name}</Bundle-Name>
        <Bundle-DocURL>http://www.example.com/</Bundle-DocURL>
        <Bundle-ManifestVersion>2</Bundle-ManifestVersion>
        <Bundle-Vendor>YourCompanyAG</Bundle-Vendor>
        <Fragment-Host>system.bundle;extension:=framework</Fragment-Host>
        <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName>
        <Export-Package>
          com.example,whatever;version=1.0,
      </Export-Package>
    </manifestEntries>
  </archive>
 </configuration>
</plugin>

Update: a complete sample pom is available at http://svn.apache.org/repos/asf/sling/trunk/samples/framework-fragment/pom.xml


Tales from the OSGi trenches

March 25, 2009

My Tales from the OSGi trenches presentation today at ApacheCon went well, timing was surprisingly good given that I gave this talk for the first time.

People can certainly relate to the issues that we’ve been facing with OSGi, and the realization is that the large majority of them can be linked to lack of developer education and lack of documentation and examples.

Things will get better, but my conclusions page already has a lot more smileys than monsters!


Does OSGi work for you?

February 25, 2009

apachecon-eu09.jpgI’m looking for additional input for my Tales from the OSGi trenches talk, at ApacheCon EU 2009 next month in Amsterdam.

My main angle for this talk is how the move to OSGi changes the way developers and customers work. Day‘s complete product line is based on OSGi (using Apache Felix and Apache Sling), and this has a tremendous impact on how our developers work. Users of our products, depending on the level at which they decide to interact with them, can also reap big benefits from OSGi’s modularity and service-oriented features.

However, while OSGi might look like a silver bullet on paper, rethinking modularity and services has an important impact of the way people work, and on how we test our systems.

For this talk, I intend to describe the impact that OSGi has on our ways of working, including the potential downsides, or misuses, of extreme modularity and extreme dynamic behavior of services and components.

I’d be very happy to include other people’s opinions (converging or not) in my talk, so let me know if you have similar experiences to share. Either in comments here, or by mail, bdelacretaz () apache.org. All contributions will be duly acknowledged, of course!


Good technology makes things easier than you think

October 3, 2008

Working on macosx, I often find that things are easier than I thought – just drop something where it makes sense, or do what you would naturally do, and things work as expected. Often, at least.

I had the same experience today playing with OSGi services – one of my services needs to be informed of all configuration changes. OSGi provides a ConfigurationListener interface for that, but how are those registered with the framework?

That’s actually much easier than I thought at first – here’s the complete source code:

import org.osgi.service.cm.ConfigurationEvent;
import org.osgi.service.cm.ConfigurationListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 *  @scr.component 
 *      immediate="true"
 *      metatype="no"
 *  @scr.service
 */
public class DebuggingConfigurationListener implements ConfigurationListener {

	private final Logger log = LoggerFactory.getLogger(getClass());	
	
	public void configurationEvent(ConfigurationEvent e) {
		log.info("Got ConfigurationEvent, pid={}, type={}", e.getPid(), e.getType());
	}

}

Not bad hey? The scr.service annotation causes the class to be registered as a ConfigurationListener service, and the framework uses a whiteboard pattern to send configuration events to all such services.

Note to self: make things easier than what people expect.


OSGi (#5) + JCR (#4) = Sling

January 31, 2008

Carlos Perez puts OSGI and JCR number 5 and 4 in his list of top Java-based technologies to learn in 2008.

While I’m not a big fan of “top five” lists (except in High Fidelity), I can’t help but note that Sling will help you grasp both #5 and #4, in a gentle way. See you there!


Last call for ApacheCon EU 08 papers!

October 26, 2007

apachecon-logo.pngThe deadline is today and the URL is http://www.eu.apachecon.com/.

I’m submitting a talk on microsling (together with my colleague Felix from the Felix project), my usual XSLT stuff (mostly a rerun), something new on Open Source collaboration tools, and a tentative OSGi services made easy talk to demonstrate the cool Maven plugins provided by Apache Felix.

Update: the deadline has been extended to November 2nd.


microsling – Yet Another (cool) Web Applications Framework

October 12, 2007

sling-logo.pngFrom the new and improved department: I spent part of this week writing a “reduced to the max” version of the Sling core that I’ve called microsling.

That’s been a lot of fun of course, and I think the results are fairly impressive in terms of power per line of code, thanks to the power of the JCR API. Using “modern” Java, with scripting in the right places, helps a lot as well, but that’s nothing new.

In its current state, microsling allows you to use SlingServlets to process HTTP requests in a RESTful way, acting on abstract Resources and using “pluggable” request processing scripts in various languages.

A few useful SlingServlets are provided to create content and to render it using either Velocity templates or server-side javascript.

All this in less than 1’200 lines of Java code, all inclusive.

I’m not sure yet if microsling matches the complete vision of the Sling request processing, but this is already powerful stuff – and very simple to use.

See SLING-47 and the sling-dev list for more info. The microsling homepage is attached to SLING-47 and contains an overview of the request processing mechanism, including links to the source code for a quick walkthrough.

Or get the code straight from the Sling whiteboard if you want to play with it. Fifteen minutes should be enough to build and run it if you have a JDK 1.5, Maven 2.0.7 and a WebDAV client.

The full Sling codebase can be overwhelming to start with, as there are lots of (useful) stuff in there: OSGi helpers and management console, a JSP compiler, JCR utilities, etc. This is an attempt to demonstrate the core Sling principles in a much simpler way, by getting rid of all the ancillary stuff (which deserves to be better organized in Sling, but that’s another story).

Let’s hope the current API redesign and the microsling effort help us communicate more clearly the Sling vision to the JCR community, in order to give it the audience that it deserves!

Update: the code has been moving around since I wrote this (and deleted from Sling’s svn as we incorporated its ideas into Sling later), to get it you need an svn client now:
svn export -r 584116 http://svn.apache.org/repos/asf/incubator/sling/whiteboard/microsling@584116


French OSGI user group meeting, Paris, October 10th

July 30, 2005

Didier Donsez sent me a note about this meeting, details can be found here.

The agenda mostly talks about administrative stuff, so it’s not going to be exciting technical or strategy discussions I guess. But it’s still good to know that such a group exists.


Follow

Get every new post delivered to your Inbox.

Join 26 other followers