Which class called me?

R

Richard Maher

Hi,

Is there some class out there like a System.Trace or System.StackWalk that
will let my method in class X discover the name of the class, and the method
in that class, that invoked it?

Along the lines of what java.util,logging.logger does (with all provisos of
best-endeavour optimizer-challenged accuracy accepted)

Cheers Richard Maher
 
A

Arved Sandstrom

Richard said:
Hi,

Is there some class out there like a System.Trace or System.StackWalk that
will let my method in class X discover the name of the class, and the method
in that class, that invoked it?

Along the lines of what java.util,logging.logger does (with all provisos of
best-endeavour optimizer-challenged accuracy accepted)

Cheers Richard Maher

I typically create a Throwable, invoke getStackTrace() on it, and parse
out the StackTraceElement[] array as much as necessary.

AHS
 
R

Richard Maher

Hi Arved.

Arved Sandstrom said:
Richard said:
Hi,

Is there some class out there like a System.Trace or System.StackWalk that
will let my method in class X discover the name of the class, and the method
in that class, that invoked it?

Along the lines of what java.util,logging.logger does (with all provisos of
best-endeavour optimizer-challenged accuracy accepted)

Cheers Richard Maher

I typically create a Throwable, invoke getStackTrace() on it, and parse
out the StackTraceElement[] array as much as necessary.

Thanks for the reply and answer. A colleague mentioned a similar approach
(well actually throwing/catching rather than just instantiating).

Anyway, sounds good and in the grand scheme of things how expensive could it
be?

Also has it been your experience that the StackTraceElements have changed at
all across Java versions since you started doing this?

Cheers Richard Maher
 
J

Joshua Cranmer

Richard said:
Thanks for the reply and answer. A colleague mentioned a similar approach
(well actually throwing/catching rather than just instantiating).

Anyway, sounds good and in the grand scheme of things how expensive could it
be?

Exceptions are never exactly cheap, as the stack traces are not lazily
constructed. If you don't throw, just instantiate, you'll save some time.

Note that I truly accurate answer might be impossible--for example, the
optimizer may have optimized out the calling method, or the calling
method could be somewhere in JNI.
 
A

Arne Vajhøj

Richard said:
Is there some class out there like a System.Trace or System.StackWalk that
will let my method in class X discover the name of the class, and the method
in that class, that invoked it?

You can try with:

StackTraceElement ste = (new Exception()).getStackTrace()[1];
String clznam = ste.getClassName();
String mthnam = ste.getMethodName();

or:

StackTraceElement ste = Thread.currentThread().getStackTrace()[2];
String clznam = ste.getClassName();
String mthnam = ste.getMethodName();

Arne
 
A

Arne Vajhøj

Arne said:
Richard said:
Is there some class out there like a System.Trace or System.StackWalk
that
will let my method in class X discover the name of the class, and the
method
in that class, that invoked it?

You can try with:

StackTraceElement ste = (new Exception()).getStackTrace()[1];
String clznam = ste.getClassName();
String mthnam = ste.getMethodName();

or:

StackTraceElement ste = Thread.currentThread().getStackTrace()[2];
String clznam = ste.getClassName();
String mthnam = ste.getMethodName();

Best advice is probably to redesign so it is not needed.

Arne
 
A

Arved Sandstrom

Joshua said:
Exceptions are never exactly cheap, as the stack traces are not lazily
constructed. If you don't throw, just instantiate, you'll save some time.

Note that I truly accurate answer might be impossible--for example, the
optimizer may have optimized out the calling method, or the calling
method could be somewhere in JNI.

I'll add to this: I don't exactly do this much, and I do it during
debugging when I don't feel like using the actual debugger. I've got a
little utility class that I can make use of in my projects for this
purpose, just like I've got a DBUtils class and a PrintUtils class and
so forth. So I'm not exactly worried about the expense of it...it'll not
be in production code.

AHS
 
R

Richard Maher

Hi Arne, Roedy,

Thanks for the examples.

Arne Vajhøj said:
Arne said:
Richard said:
Is there some class out there like a System.Trace or System.StackWalk
that
will let my method in class X discover the name of the class, and the
method
in that class, that invoked it?

You can try with:

StackTraceElement ste = (new Exception()).getStackTrace()[1];
String clznam = ste.getClassName();
String mthnam = ste.getMethodName();

Best advice is probably to redesign so it is not needed.

Given the choice of passing the info into my logging routine versus
heuristic discovery, I'll opt for option 2. (depending on the
verbosity/level setting it probably won't be executed anyway) Did you have a
third way in mind?

I'm afraid that, just like Qu0ll, I've found that neither log4j or jul are
desirable in an Applet context.

Cheers Richard Maher

PS. Is there no -NOTRACE or -BYTECODEONLY javac switch that could render
this method a bit useless? Does Java really carry around all this baggage
with every "executable" (interpretable)? No wonder reverse-engineering is
touted as being so simple in Java; but more on that later.
 
R

Roedy Green

Is there no -NOTRACE or -BYTECODEONLY javac switch that could render
this method a bit useless? Does Java really carry around all this baggage
with every "executable" (interpretable)? No wonder reverse-engineering is
touted as being so simple in Java; but more on that later.

It would not really matter what baggage is carried around during
execution. You can still decompile from the ample information
available in the class file.

When you compile with Jet you explicitly choose if you want the run
time baggage for stack traces. Normally you turn it off.

See http://mindprod.com/jgloss/jet.html
 
J

Joshua Cranmer

Richard said:
PS. Is there no -NOTRACE or -BYTECODEONLY javac switch that could render
this method a bit useless? Does Java really carry around all this baggage
with every "executable" (interpretable)? No wonder reverse-engineering is
touted as being so simple in Java; but more on that later.

There do exist tools to rename Java classes and methods, but the
bytecode contains class and method information simple because of how it
needs to invoke methods. This is actually true of pretty much every
interpreted bytecode: I can say for certain that the CLR and python
bytecode contains this information, as does the internal bytecode for
the SpiderMonkey JS engine.
 
T

Tom Anderson

PS. Is there no -NOTRACE or -BYTECODEONLY javac switch that could render
this method a bit useless?
Nope.

Does Java really carry around all this baggage with every "executable"
(interpretable)?

Yup.

It's a consequence of java's linking model: linking happens at runtime,
not compile-time, so the symbols needed to do linking need to be preserved
until runtime, which means writing them in the class file.
No wonder reverse-engineering is touted as being so simple in Java; but
more on that later.

We await with breath bated and contrary opinions primed!

tom
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top