i used java reflections to get methods from a class(loaded those classes).Now i want to get the call hierarchy of those methods.How can i use call hierarchy option in eclipse IDE for that?any examples or links????
The solutions proposed is to use Thread.currentThread().getStackTrace() in order to obtain the current trace of callers.
However, you want to get this information not for the currently executing method, but for any method on any class. This can't be done easily. I think you have to inspect all classes on the classpath with a bytecode utility and match the calling instructions. Something you will spend too much time on, and I'm pretty sure it isn't needed, unless you are developing an IDE.
Anyway, you can get Eclipse or NetBeans sources and see how it is implemented there.
StackTraceElement[] stackTrace = new Throwable().getStackTrace();
You can use the StackTrace object.
But that looks very brittle to me as approach. Better avoid this kind of logic... Why not passing the caller as an argument to thé method?
Throw an exception in the method which is at the root of the hierarchy. Then you can catch the exception and printStackTrace().
I'm sure there would be cleaner solution than this. But this would work too.
Related
I was assigned a task to create a custom stacktrace like output to a log file for some specified functions, but instead of just using the class and method names I would also have to output the parameters and their values.
This is supposed to be a separate jar that could run on any java project, after.
I don't even know if such thing is possible, let alone where to start.
Any help would be appreciated.
EDIT: there is other library that does that by using native VM api: https://github.com/cretz/stackparam it also modifies Throwable class to always print that modified stacktrace.
The only possible way I can think of is using agents and instrumentalization, but agent needs to be added to startup command line.
Then I would register transformer to transform every class (remember that some basic java classes might be already loaded) using ASM library and add code to beginning of every method invocation to manually track each method class and pass it to my library that would track them:
// note that parameters names might not exist in runtime if code was compiled without a flag to include them.
public void doSomething(String name, int something) {
MyLib.enterMethod(ThisClass.class, new MethodSignature(void.class, String.class, int.class), new Argument("name", name), new Argument("something", something));
try {
// original code
} finally { // so we don't need to care about return in the middle of original code or exceptions
MyLib.exitMethod();
}
}
enterMethod would add invocation frame to some queue and exitMethod would remove last added frame. Note that you should have separate queue for each thread, use some Map<Thread, MyFrame> or ThreadLocal it might be good idea to use some weak references for threads.
And then you could use frames from that queue to create own stacktrace.
But doing something like that might decrease performance a lot - not even just because cost of this code, but adding that to every setter/getter might cause that methods to never be inlined and affect performance even more.
So it is possible but I really don't recommend doing something like that.
Also some other transformers added by other libraries might affect results, it might be good idea to also compare your stacktrace with original stacktrace to find any missing methods that you didn't transform - like native ones, and add them to your stacktrace but without that additional data.
If you really need to support native methods too - then you can create more advanced transformer that would add enterMethod/exitMethod before and after call to native method.
Also if this is only for debugging you could use debugging API so it would only work as a debugger.
So, given the following code:
public MyInterface getMyInterface() {
return new MyInterface() {
public SomethingElse getSomethingElse() {
// ....
}
}
}
...
MyInterface obj = getMyInterface();
Is there some way to instrument a call to getSomethingElse() on that obj? To go in and do some bytecode modification or something?
I have production code in there that in a different situation (call it "design time") I want to add some tracing/logging and such code for help in troubleshooting and analysis. Performance is critical for the production case so I want to leave it without the extra tracing/logging overhead. But in the design time situation, I want to have all the trace info.
Yes, it is possible to do what you're asking, although there are definitely better ways to accomplish it - the most obvious would be to create a default implementation of MyInterface, and then a "tracing" subclass of it that extends and logs before invoking the superclass version.
If instrumentation is your only option, then when running at design time, you can start your project with a java agent in Java 5 or add a java agent to the classpath at runtime in Java 6. See the instrumentation documentation.
To instrument the class, you will probably want to use a tool like ASM. The steps would be something like this:
In your Agent class, implement java.lang.instrument.ClassFileTransformer .
In your agentmain() or premain() method, request to transform classes.
When you receive a call to the transform method, you can check if the class implements MyInterface by using Class.getInterfaces().
Optionally, you can check to see if its Class.getEnclosingClass() is the class in which you wrote/found this code.
If the Class passes these sanity checks, then create a ClassWriter that adds logging to the getSomethingElse() method. The ASMifier helps a lot when trying to figure out how to generate the code you want.
Then, in production, none of that code will exist. In development, you would add your Java Agent in your environment, which would enable your debugging.
Again, there are almost certainly better ways to do this, but there are good reasons to use instrumentation, and this is a mini-crash course in doing it.
Hope that helps,
If you want to turn on logging on in development, the simplest thing to do is
if(LOGGER.isDebugEnabled())
LOGGER.debug("my debug message");
The over head added is sub-nanosecond so even if you are working on a system where every nano-seconds count, this is still the best pattern to use.
You can get the class with
Class.forName("package.OuterClass$NNN");
You need to call a constructor which takes an instance of the outer class.
This sounds like a good case for using aspects.
You can simply apply logging/tracing code around any methods you want in your testing environment and leave them out when you move to production.
Suppose I have a class called Foo. This class will be modified by many people, and WILL print information to the console. To this effect, we have the following method:
private void print(String message){ ... }
which prints out to the screen in the format we want.
However, while reviewing code from other devs I see that they constantly call System.out.println(...)
instead, which results in barely-readable printouts.
My question is the following: is it possible to prevent any and every use of System.out.println() in Foo.java? If so, how?
I've tried looking this up, but all I found had to do with inheritance, which is not related to my question.
Thanks a lot!
N.S.
EDIT: I know that whatever I have to do to prevent the use of a method could be removed by a dev, but we have as a policy never to remove code marked //IMPORTANT so it could still be used as a deterrent.
EDIT2: I know I can simply tell the devs not to do it or use code reviews to filter the "errors" out but 1) I'm already doing it and it costs a lot of time and 2) the question is whether this is possible or not, NOT how to deal with my devs.
public methods are just that - public. There is no way to restrict access to them.
This kind of problem is usually "solved" by setting up some code-checker like PMD or checkstyle and integrating them into the continuous integration build. So violations of these stuff will be emailed to someone with a big hammer :-)
Although communicating that developers should not use System.out directly would be preferred, you could set System.out to another PrintStream, then use the alternative PrintStream in the private method. That way, when people use System.out.println they won't output anything but you'll still be able to use the alternative PrintStream... something like they do here: http://halyph.blogspot.com/2011/07/how-to-disable-systemout.html
Pre-commit hooks for your revision control system (SVN, Git, Mercurial) can grep for uses of System.{err,out} and prevent commit if they occur.
http://stuporglue.org/svn-pre-commit-hook-which-can-syntax-check-all-files/ is an example that takes an action for different changed files based on file extension for SVN. You should be able to modify that example to take an example based on some subset of Java files and reject if something like the following is true
egrep -q '\bSystem\.(err|out)\b'
You can redirect System.out calls to a streams that ignores the output or that redirects it to your logging system.
System.setOut(printStream);
You can also kill those using System.out.println in a production environment.
You can replace the OutputStream of System with your own implementation that would either throw an exception, or redirect the call to your own print implementation (which you would need to make public).
No, it's not possible to 100% prevent a class from ever using a specific method in Java.
Having that said...
My suggestion would be to add code analysis to your build process and failing the build on any occurrence of System.out.println. A good place to start if you're interested in going this route would be to check out PMD.
Also... have some constructive discussions with your developers and talk about why they're doing what they're doing. Good luck.
i need to know which methods were invoked one by one in code. Simple step-by-step debugging doesn't help (need too much time). How can i do this? It would be really great do this without changes of code and saving result in file.
Since it seems that maybe you don't want to check the stack tree, just the order, you could check out BTrace or Adding logging with Java agent.
Before your program finishes, you could Thread.currentThread().getStackTrace(); and then print each of those elements. A stack trace shows you the order of execution in your thread.
Sounds like a cross-cutting concern, especially when you talk about not changing existing code.
AspectJ is available to do this work for you using pointcuts.
http://www.eclipse.org/aspectj/doc/released/progguide/starting-aspectj.html
Do you mean you want to log every method call that occurs in your program? If so, have a look at AspectJ - there's an example here which logs particular methods, but you can easily adapt it to cover all methods.
What about when you catch a Exception you can try to use printStackTrace() function to dump out what has been invoked.
try{
//Your code
}
catch(Exception e){
e.printStackTrace();
}
Run your code in debug mode, you'll be able to set breakpoints to pause the execution, proceed line by line, inspect variables, etc.. Basically all the IDEs have debug mode.
I'd like to know how to - if even possible - reflect what method calls are executed inside the method during execution. I'm especially interested in either external method calls (that is, methods in other classes) or calling some specific method like getDatabaseConnection().
My intention would be to monitor predefined objects' actions inside methods and execute additional code if some specific conditions are met like some method is called with specific values. The monitor would be completely external class or a set of classes with no direct access to the object to be monitored by no other way than reflection.
Aspect J will solve your problem.
Try to define a pointcut like this:
pointcut profilling(): execution(public * *(..)) && (
within(com.myPackage..*) ||
In this way you will catch all the call to any public method within the package com.myPackage. Add as many within clauses you need.
Then add the following code:
Object around(): profilling() {
//Do wherever you need before method call
proceed();
//Do wherever you need after method call
}
IF you want to learn something more about aspectJ follow this guide.
I'd expect BCEL to be able to do this. From the web site:
The Byte Code Engineering Library is
intended to give users a convenient
possibility to analyze, create, and
manipulate (binary) Java class files
(those ending with .class).
The "analyze" part being the important bit here. The JavaDoc isn't visible on the web site (as far as I can see) so I can't easily be sure whether or not it'll help you, but it's a reasonable starting point.
BCEL should offer this capability, but ...
... your requirements sound a lot like Aspect-Oriented Programming (AOP), so you should probably also look at AspectJ (with Eclipse tooling).
The main advantage of AspectJ is that it offers a well-designed way to express your specific conditions.