ClassLoader Leak Prevention library version 1.13.0 released

Version 1.13.0 of ClassLoader Leak Prevention library has just been released, and should propagate to Maven Central shortly.

This version changes the treatment of threads that uses the web apps ClassLoader as its contextClassLoader, while neither the Thread nor its Runnable are loaded by that ClassLoader. Previously the library would kill such Threads, assuming the ClassLoaderLeakPreventor.stopThreads setting was not explicitly disabled, which caused issues with Tomcat 7 executors.

Grab the new version via Maven central or download the jar manually.

<dependency>
  <groupId>se.jiderhamn</groupId>
  <artifactId>classloader-leak-prevention</artifactId>
  <version>1.13.0</version>
</dependency>

ClassLoader leaks at JavaForum Stockholm

Tonight I did a presentation on ClassLoader leaks at JavaForum Stockholm.

Video

Unfortunately there were some issues with the video feed, so I turned off the recording to rule out that interfering with things. Apparently the organizers recorded the event, so watch this space for updates when it has been made available online. Until then you may check out the recording of the same presentation from an earlier event:

Slides


References:
Slide 26: Heinz Kabutz Java Specialists’ Newsletter The Law Of The Blind Spot
Slide 41: Tomcat Bugzilla entries #48895 and #49159.

ClassLoader Leak Prevention library version 1.12.0 released

Version 1.12.0 of my ClassLoader Leak Prevention library has been released.

Apart from internal improvements (thanks to Jeremy Landis) it contains the following features:

  • Invoke org.springframework.web.util.IntrospectorCleanupListener in case it exists on the classpath. (Thanks to Craig Andrews)
  • Unregister ImageIO Service Provider loaded by the web application class loader. (Thanks to Thomas Scheffler)
  • Improve prevention of leaks caused by sun.awt.AppContext

Grab the new version via Maven central or download the jar here.

<dependency>
  <groupId>se.jiderhamn</groupId>
  <artifactId>classloader-leak-prevention</artifactId>
  <version>1.12.0</version>
</dependency>

ClassLoader Leak Prevention library version 1.11.0 released

Version 1.11.0 of my ClassLoader Leak Prevention library has been released.

Apart from minor tweaks it contains the following features:

Grab the new version via Maven central or download the jar here.

<dependency>
  <groupId>se.jiderhamn</groupId>
  <artifactId>classloader-leak-prevention</artifactId>
  <version>1.11.0</version>
</dependency>

ClassLoader Leak Prevention library version 1.10.0 released

Version 1.10.0 of my ClassLoader Leak Prevention library has been released.

Apart from minor improvements it contains protection against a leak caused by Caucho Resin version < 4.0.40. It is however recommended that you upgrade to Resin 4.0.40+.

Grab it via Maven central or download the jar here.

<dependency>
  <groupId>se.jiderhamn</groupId>
  <artifactId>classloader-leak-prevention</artifactId>
  <version>1.10.0</version>
</dependency>

ClassLoader leaks at JavaForum Gothenburg

Tonight I have talked about ClassLoader leaks at JavaForum Gothenburg. Below you will find the slides from the presentation, the link to the Leak prevention library on GitHub and links to all the parts of the blog series I made on the subject.

Video

Slides


Heinz Kabutz Java Specialists’ Newsletter The Law Of The Blind Spot referenced on slide 26.
Tomcat Bugzilla entries #48895 and #49159 referenced on slide 41.

Leak prevention library

GitHub project

Links to all parts in blog series

Part I – How to find classloader leaks with Eclipse Memory Analyser (MAT)

Part II – Find and work around unwanted references

Part III – “Die Thread, die!”

Part IV – ThreadLocal dangers and why ThreadGlobal may have been a more appropriate name

Part V – Common mistakes and Known offenders

Part VI – “This means war!” (leak prevention library)

Better compareTo() syntax

I’ve never really been a big fan of the syntax of java.lang.Comparable.compareTo(). For some reason I find myself constantly referring to the JavaDocs to remind me whether < 0 or > 0 means the argument is less vs more than the callee.

So I decided to do something about it, and created a minimal API with the sole purpose of improving readability of compareTo().

The API supplies methods in two flavors, expressive or abbreviated. The expressive version looks like this:

import static se.jiderhamn.CompareTo.is;

...
  boolean oneIsZero = is(1).equalTo(0);
  boolean aIsNotZero = is(a).notEqualTo(0);
  boolean bIsZero = is(b).zero();
  boolean value1LessThanValue2 = is(value1).lessThan(value2);
    
  if(is(a).lessThanOrEqualTo(b)) {
    ...
  }

  boolean date1AfterDate2 = is(date1).greaterThan(date2);

  if(is(a).greaterThanOrEqualTo(b)) {
    ...
  }

 

The abbreviated syntax looks like this:

import static se.jiderhamn.CompareTo.is;

...
  boolean oneIsZero = is(1).eq(0);
  boolean aIsNotZero = is(a).ne(0);
  boolean value1LessThanValue2 = is(value1).lt(value2);

  if(is(a).le(b)) {
    ...
  }

  boolean date1AfterDate2 = is(date1).gt(date2);

  if(is(a).ge(b)) {
    ...
  }

 

The API is available on Maven Central:

    <dependency>
      <groupId>se.jiderhamn</groupId>
      <artifactId>compare-to</artifactId>
      <version>1.1.1</version>
    </dependency>

Source are on GitHub.

Manual download here.

Debugging third party libraries with AspectJ and Maven

Once in a while you may find yourself in a situation, where you need to debug a third party library on a production server or other environment where it is not possible or impractical to attach a debugger. It may also be the case that modifying the sources of that library and compiling a custom version is not an option (due to compilation dependencies, licenses, source not available or whatnot).

I found myself in such a situation a while back when I needed to understand memory leaks in OpenOffice JURT. I achieved this by injecting debug logging into the library with AspectJ, and in this post I will describe how.

In my situation the third party library was a transitive Maven dependency. In order to weave this library with my own aspects, I added this to the pom.xml:

  <build>
    <plugins>
      <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>aspectj-maven-plugin</artifactId>
        <version>1.4</version>
        <configuration>
          <!-- Weave third party dependency -->
          <weaveDependencies>
            <weaveDependency>
              <groupId>org.openoffice</groupId>
              <artifactId>jurt</artifactId>
            </weaveDependency>
          </weaveDependencies>
        </configuration>
        <!-- Weave on compile -->
        <executions>
          <execution>
            <id>compile</id>
            <goals>
              <goal>compile</goal>
            </goals>
          </execution>
        </executions>
      </plugin>
    </plugins>
  </build>

Note! In order for the weaved version of the library to be included in your .war, the above should be located in the web module if your Maven project has multiple modules. If your aspect is in another module you also need to add

          <aspectLibraries>
            <aspectLibrary>
              <groupId>your.project</groupId>
              <artifactId>module-with-aspect</artifactId>
            </aspectLibrary>
          </aspectLibraries>

to the configuration.

You’ll likely also want to add the AspectJ runtime dependency, for the aspect implementation.

    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjrt</artifactId>
      <version>1.6.12</version>
    </dependency>

Now lets move on with the actual aspect. If you need an introduction to AspectJ, you may find this post useful. First we have our aspect class:

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * AspectJ aspect used for debugging memory leaks caused by OpenOffice JURT
 * @author Mattias Jiderhamn
 */
@Aspect
public class JURTDebugAspect {
  
  private static final Logger LOG = LoggerFactory.getLogger(JURTDebugAspect.class);

  /** Utility method to get StackTraceElement of caller */
  private static StackTraceElement getCaller(int levels) {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    return stackTrace[levels + 1];
  }

}

Inside that aspect class, we can add different joinpoints and advice to inject logging.

  @Before("execution(* com.sun.star.lib.util.AsynchronousFinalizer.add(..))")
  public void addCalled() {
    LOG.warn("JURT: add() called by " + getCaller(3));
  }

This will log calls to the third party API add() method, including calls from other third party libraries. Note that “execution” pointcut is used rather than “call” pointcut, since we are weaving the callee, not the caller. The getCaller() utility method also allows us to see what code called the add() method.

  @Before("call(* java.lang.Thread.start(..)) && within(com.sun.star.lib.util.*) && target(thread)")
  public void threadStarted(Thread thread) {
    LOG.warn("JURT: Thread.start() called by " + getCaller(2) + " on thread named " + 
      thread.getName() + " of type " + thread.getClass().getName());
  }

Here we add some logging for when the third party library calls the start() method on java.lang.Thread, and include the name and type of the started thread.

  @Around("call(* com.sun.star.lib.util.AsynchronousFinalizer$Job.run(..)) && within(com.sun.star.lib.util.*) && target(job)")
  public Object jobRun(ProceedingJoinPoint proceedingJoinPoint, Object job) throws Throwable {
    LOG.info("JURT: Job.run() starting: " + job.getClass().getName() + " in thread " +
      Thread.currentThread().getName());
    final long start = System.currentTimeMillis();
    try {
      return proceedingJoinPoint.proceed();
    }
    finally {
      LOG.info("JURT: Job.run() done: " + job.getClass().getName() + " in thread " +
        Thread.currentThread().getName() + "; took " + 
        (System.currentTimeMillis() - start) + " ms");
    }
  }

Here we log internal calls to Job.run() inside the API, and measure the time that those calls take. The name of the Job subclass is included.

Good luck debugging third party libraries!

Agile code review at nForum – video

When I talked about agile code review on nForum the other day, I made a screencast recording, which is now online. (I admit sound quality could have been somewhat better.)

For better readability of the slides, I recommend viewing the video in HD on Vimeo

Note that the slides and links to code review tools and further reading are in my previous post.

If you want to share the video, please link to this post rather than directly to Vimeo.

Agile code review at nForum

Tonight I’ve given a talk at nForum Göteborg on code review and how it can be used by agile teams. It was pretty much the same talk I gave at JavaForum a while back. I tried to make a recording of it, and will post a video and update this post, if successful.

Here are the (Swedish) slides:


Here are links to some code review tools:

In addition to this list, code review is one of the features of GitHub. In my opinion it has the same problems as e-mail based review, where it is hard to track what has been fixed and not.

Some reading suggestions on code review:
Coding Horror blog entry
Free book from the authors of Code Collaborator
White paper from the authors of Klocwork