Find my resource!

Hands up if you’ve seen this:

You deploy your application. Crash. Time to switch on more logging by editing log4j.properties. You change it and nothing happens. Was there another log4j.properties somewhere? Which one is being used?

or

You made your change and the build is still picking up old code. Where’s that being loaded?

Wouldn’t it be nice to get some more info from the classloader? I hereby introduce FindClass which, despite the name, can find any resource really, whether nested in a sub folder or buried inside a JAR file.

Here’s a quick example:

FindClass findClass = new FindClass();
System.out.println("Long class loaded from : "+findClass.getLoadOrigin(1L));
System.out.println("FindClass class has been loaded from : " + findClass.getLoadOrigin(FindClass.class));

This will print out:

Long class has been loaded from : D:\Java\jdk1.6.0_02\jre\lib\rt.jar
FindClass class has been loaded from : D:\Workspace\\findclass\target\classes\com\jolbox\utils\FindClass.class

Just for kicks, I’ve added helper methods on the same theme so that you can trace an existing object, a given class or a resource:

public String getLoadOriginClass(String fullyQualifiedClassName);
public String getLoadOrigin(Object obj);
public String getLoadOrigin(Class clazz);
public String findLoadOrigin(String resource);

This is nice but sometimes you need to find stuff without having to embed this inside your application. Using basically the same methods, the class itself can be made to search directly from the command line:

java -cp . com.jolbox.utils.FindClass startdir match extension

For example:

FindClass d:\\workspace FooBar .class

matches *FooClass*.class (case is not important)

What if you’re application is already running? Not to fear! So long as your application is Spring enabled (and you’ve scanned the class in), the more important methods are already JMX enabled.

Going back to our original question: Want to know all the locations of log4j.properties? Just call:

 
searchInClassPath("log4j", "properties")

at the beginning of your application to get a list of locations containing that file.

There are some other helper methods available but I’ll leave those for you to discover. Do remember however that these methods are slow and are therefore only to be used in a debugging context.

FAQ: Can you dump all the locations of all the classes in use?
Answer: No… and yes. The method is available but remember that the classloader will only load the classes you actually use so it’s really a dump of all the locations of the classes that have been used at least once.

Disclaimer: Not all the code in the class was written by me; some routines are a collection of snippets off the web.

Download code from here

JolBox hosts BoneCP – The fast Java JDBC Connection pool.

Tags: , ,

2 Responses to “Find my resource!”

  1. Nico says:

    For log4j specifically it is much easier to just specify -Dlog4j.debug at startup.

  2. Sorry for misusing blog comment for praise of BoneCP, but i didn’t want to register in the forum.

    We recently switched from c3p0 to BoneCP because we had some problems with C3p0 mainly some strange Exceptions we could not track down. So we just tried BoneCp. It works great! I can’t really see if it is faster but it seems to be much more reliable. We drive a very popular website in germany with peaks of 3000 page views per second. All of these page views are dynamic and needs a DB connection if the data is not in second level cache. We used the LazyDatasource Pattern. As you stated you don’t know who is using BoneCP, i can actually confirm: It is a joy, not a toy to run your app with BoneCP :-)

Leave a Reply