Quantcast
Channel: Planet Eclipse – EclipseSource
Viewing all articles
Browse latest Browse all 24

Does your application have working brakes?

$
0
0

Suppose your friend got a new motorcycle. The first questions are probably like the following. What horsepower does it have? How fast can it go? How long does it take from 0 to 100km/h? How about 0 to 200km/h?
Rarely will you ask how fast it can stop. Does it have brakes at all?

motorcycle Does your application have working brakes?

Of course every motor vehicle is supposed to have working brakes. In software things are different.

In any application many thoughts are given to the when and how things start up. Not as often are thoughts given to application shutdown. Of course, there are always these stop() methods, i.e. in the IApplication in Eclipse RCP or RAP and in every OSGi bundles activator. But what are you supposed to do with it?  You’re supposed to shut down your connections, release your resources and stop your threads. Wait until this has happened, then exit stop(). Otherwise you risk ugly log entries in the best case, but also memory, UI handle or file handle leakages.

Cleaning up your resources is especially important in environments where the application lifecycle is not bound to a user interaction, i.e. on the server side or in RCP applications that just keep running.

In the following example, I present a small OSGi bundle with an activator and a class TimeIndicator. The Activator has the default start() and stop() methods, and at this moment the stop() method is implemented somewhat carelessly.

public void start(BundleContext bundleContext) throws Exception {
   Activator.context = bundleContext;
   clock = new TimeIndicator();
   clock.start();
}
public void stop(BundleContext bundleContext) throws Exception {
   // TODO free up resources
   Activator.context = null;
}

The TimeIndicator is a Thread that gets the OSGi LogService and logs a message “Tick” every second until it is shut down. For the purposes of this example the TimeIndicator assumes that it will always get the LogService via the activators bundle context.

@Override
public void run() {
  running = true;
  while (running) {
    BundleContext context = Activator.getContext();
    ServiceReference reference = context.getServiceReference(LogService.class);
    LogService logService = context.getService(reference);
    logService.log(LogService.LOG_ERROR, "Tick");
    waitASecond();
  }
}

Lets start this bundle. I’m starting this bundle as OSGi application.
In the OSGi console, I stop my bundle, and then inspect the status:

osgi> stop com.eclipsesource.examples.cleanup
osgi> ss

Framework is launched.

id State       Bundle
0 ACTIVE      org.eclipse.osgi_3.7.2.v20120110-1415
1 ACTIVE      org.eclipse.core.contenttype_3.4.100.v20110423-0524
2 RESOLVED com.eclipsesource.examples.cleanup_1.0.0.qualifier
3 ACTIVE      org.eclipse.equinox.app_1.3.100.v20110321
4 ACTIVE      org.eclipse.equinox.common_3.6.0.v20110523

!ENTRY com.eclipsesource.examples.cleanup 4 0 2012-06-05 09:25:52.036
!MESSAGE Tick

This is a dangerous state. The bundle stopped, but the thread is still running. It will soon fail because the context will be null in the next iteration, but in some bigger jobs it is not even sure that required classes would be loaded.

But the solution is straightforward. Here is what should be done in the stop() method:

public void stop(BundleContext bundleContext) throws Exception {
if( clock != null ) {
      clock.stopTicTac();
      clock.join();
    }
    Activator.context = null;
}

Checking your brakes is not hard, but just as a vehicle needs an inspection from time to time you should have a look now and then at cleaning up your resources properly.

Credit: Motorcycle photo by Richard Taylor via CC BY 2.0


TwitterGoogle+LinkedInFacebook

Comments are off for this post.

Viewing all articles
Browse latest Browse all 24

Latest Images

Trending Articles



Latest Images