the_marcelo_r
the_marcelo_r

Reputation: 1856

How to identify which class is calling a specific method?

Let's assume that we have an abstract class with a method that prints a WARN log entry (WARNING: Cannot set header. Response already committed), this method is being called by class X lots of times (it is flooding the logs).

Based on the log entry that was generated from the Application Server, I have managed to identify the abstract class and found its jar (using jarscan), the JAR is an OOTB Component of the application server so it is not supposed to be modified in any sense. I have hacked the JAR and introduced a line within the method that generates the log entry:

new Exception().printStackTrace()

This approach should give me the stack trace to identify class X.

However, I don't know how to reproduce this error in my test environment, there are a lot of projects that I don't have in my workspace and I can't just check hundreds of classes to see which one is setting something into the response object, I have tried to find a match between the log entries timestamps and Selenium test reports that are running against the test environment but it is not showing up in the logs.

Question: What would be a good troubleshooting approach to identify Class X without any intrusive changes on the environment that presents the issue?

Upvotes: 1

Views: 182

Answers (2)

przemek hertel
przemek hertel

Reputation: 4024

If you cannot use debugger because of your environemnt specific, you can investigate classes loaded into your server's JVM and find classes that inherit from your abstract class.

Run jvisualvm and connect to your server's JVM, then go to OQL console in jvisualvm and run such query:

select heap.findClass("com.xyz.my.AbstractClass").subclasses()

This will find all subclasses of your abstract class currently loaded.

Upvotes: 3

Mister
Mister

Reputation: 497

public String getMethodName(final int depth) {
    final StackTraceElement[] ste = Thread.currentThread().getStackTrace();
    return ste[depth].getMethodName();
}

Usage:

public void doSysOutTest() {
    String getMetNameFunc = getMethodName(1);
    String callingMethod = getMethodName(2);

    System.out.println(getMetNameFunc);
    System.out.println(callingMethod);
}

Output:

getMethodName
doSysOutTest

To get more information out of the stack you could also use these methods:

ste[depth].getClassName()
ste[depth].getFileName()
ste[depth].getLineNumber()

Take a look here: http://docs.oracle.com/javase/7/docs/api/java/lang/StackTraceElement.html

Upvotes: 1

Related Questions