tags:

views:

126

answers:

7

I have a Tomcat with some applications running. I cannot restart the Tomcat but I would like to monitor the usage of class files.

I would like to log if a specified class is used. Is this possible? How could I accomplish it?

Class Usage: If an object for this class is instantiated or methods are called etc.

Clarification: I cannot restart the application. Every solution with recompiling the running code are not acceptable. That makes the problem so hard.

Remote debugging/JMX is not enabled yet. It would be a similar effort like recompiling the application to activate it.

Platform is RHEL, 64 Bit.

+1  A: 

I think you need profiling for that. Profiler will allow you to see which classes are used. Or the programmers fav - System.out.println :)

Padmarag
I will try profiling, but I'm not sure if it works.
furtelwart
I think profiling requires settings on the JVM that require a restart to apply.
Tom Duckering
A: 

If you have access to the source files, you could simply put some log statements in the constructor of the class (assuming instantiation implies class use).

If object instantiation is not what you mean by "the usage of class files", then perhaps you mean that you'd like to know when a class is loaded by the JVM? If so, static initialization blocks may be able to help; you could put the log statements there.

Shakedown
if he cannot restart Tomcat, he probably cannot update the application code, either.
Thilo
You don't sound so sure. I seem to remember dropping in .jar's to your Tomcat directory for dynamic deployment.
Shakedown
I sound unsure, because the OP is not clear in his requirements. If restarting Tomcat is out, hot-redeployment is probably also forbidden (as is maybe updating the source in the first place).
Thilo
Hot redeployment won't work, too. Thanks Thilo for the clarification. Dropping .jars to the tomcat would restart the application.
furtelwart
A: 

If you want to know it programatically then I dont think it is trivially possible.

But you can do some reflection to get to know, by calling this method.

ClassLoader#findLoadedClass()

If the method returns null, that means the class is not loaded and hence not in use. The problem ofcourse, is that the mehtod is preotected, so you need to use relfection.

Suraj Chandran
A: 

You can define a static block in the class

class X {
 static {
  System.out.println("class X has been loaded");
 }
 ...
}

that will be called once when the class object is loaded.

If you cannot edit the code, and you have a JRE 6, you might try the jmap tool

jmap -histo <pid>

it will print a histogram of your heap, including all loaded classes.

Using jps you can find out the pid

mfx
Nice idea. For my problem, it won't work because I cannot recompile the application.
furtelwart
A: 

If you are on Solaris or OS X, then a DTrace probe might on option.

Other than that, if you cannot attach a debugger or profiler or other monitoring tool to the already running JVM (which depends on options you would have needed to specify on startup), you are out of luck.

Thilo
Solaris also has `pfiles` or `truss` too.
Tom Duckering
+1  A: 

I would like to log if a specified class is used; i.e. if an object for this class is instantiated or methods are called etc.

A memory profiler would tell you if a reachable instance of a class exists at the instant you run the profiler. An execution profiler could tell you that a method or constructor is called during some interval ... though it might also miss a call, due to the way that profilers work.

The webapp's classloader could in theory tell you if a class has been loaded, but I doubt there is a way to call the classloader's method that doesn't involve a restart. Also, there is no way to know if a method has EVER been called or an instance has EVER been created apart from adding monitoring hooks to the class. And adding those hooks would entail a restart.

And of course there are other ways that a class could be "used" that don't entail constructing instances or calling its methods.

So depending on what you are really trying to figure out, you may be out of luck.

Stephen C
A: 

With the JRockit JVM you can start your application with -Xverbose:class=info to get information about class loading.

Kire Haglin
Sun's JVM supports that flag too.
Thilo