Jenkins : JNA is already loaded

If you see an error during the start up that says "another instance of JNA is already loaded in another classloader", this is what's going on.

Cause

Hudson depends on JNA for interfacing with native code. A part of JNA is written in JNI. While multiple Java classes of the same name can be loaded into the same JVM by using different classloaders (in fact that's what most servlet containers do to isolate each webapp), this doesn't hold for JNI — you can only load one copy to one JVM.

Because of this, if your servlet container has other applications that use JNA, Hudson will not be able to load it, and fail to start with this error.

Solution

  • It's possible for this to happen when you redeploy Hudson without terminating a servlet container, if the JNA loaded by the old classloader doesn't get garbage-collected in time for the new one to start. If you suspect this to be the case, simply restart your servlet container and see if that eliminates the problem.
  • If you are trying to have Hudson co-exist with other apps that use JNA in a single container (this includes deploying multiple copies of Hudson on different paths), you can put jna.jar into the container's shared library directory, so that all the webapps will see the same copy.
  • Another approach is to run each webapp in its own JVM, then use Apache to aggregate them all under a single HTTP server. See Running Jenkins behind Apache for more details.