I need to diagnose all invoked methods in a class(either declared in the class or not) using it's source code. Means that give the class source code to a method as an input and get the invoked method by the class as the output. In fact I need a class/method which operates same as java lexical analyzer .
Is there any method to diagnose all invoked methods ?
of course I tried to use Runtime.traceMethodCalls(); to solve the problem but there was no output. I've read I need to run java debug with java -g but unfortunately when I try to run java -g it makes error. Now what should I do ? Is there any approach ?
1) In the general case, no. Reflection will always allow the code to make method calls that you won't be able to analyze without actually running the code.
2) Tracing the method calls won't give you the full picture either, since a method is not in any way guaranteed (or even likely) to make all the calls it can every time you call it.
Your best bet is some kind of "best effort" code analysis. You may want to try enlisting the compiler's help with that. For example, compile the code and analyze the generated class file for all emitted external symbols. It won't guarantee catching every call (see #1), but it will get you close in most cases.
You can utilize one of the open source static analyzers for Java as a starting point. Checkstyle allows you to build your own modules. Soot has a pretty flexible API and a good example of call analysis. FindBugs might also allow you too write a custom module. AFAIK all three are embeddable in the form of a JAR, so you can incorporate whatever you come up with into your own custom program.
From your question it is hard to determine what is exactly problem you're trying to solve.
But in case:
If you want to analyze source code, to see which parts of it are redundant and may be removed, then you could use some IDE (Eclipse, IntelliJ IDEA Community Edition etc.) In IDE's you have features to search for usages of method and also you have functionality to analyze code and highlight unused methods as warnings/errors.
If you want to see where during runtime some method is called, then you could use profiling tool to collect information on those method invocations. Depending on tool you could see also from where those methods were called. But bare in mind, that when you execute program, then it is not guaranteed that your interesting method is called from every possible place.
if you are developing an automated tool for displaying calling graphs of methods. Then you need to parse source and start working with code entities. One way would be to implement your own compiler and go on from there. But easier way would be to reuse opensourced parser/compiler/analyzer and build your tool around it.
I've used IntelliJ IDEA CE that has such functionalitys and may be downloaded with source http://www.jetbrains.org/display/IJOS/Home
Also there is well known product Eclipse that has its sources available.
Both of these products have enormous code base, so isolating interesting part would be difficult. But it would still be easier than writing your own java compiler and werifying that it works for every corner case.
For analyzing the bytecode as mentioned above you could take a look at JBoss Bytecode. It is more for testing but may also be helpful for analyzing code.
sven.malvik.de
You may plug into the compiler.
Have a look the source of Project Lombok for instance.
There is no general mechanism, so they have one mechanism for javac and one for eclipse's compiler.
http://projectlombok.org/
Related
I am writing a plugin of another large java program .
I want to modify some byte code of some java method of the java program during runtime, so that I can intercept the method calls (namely, inject some hooking code into the method).
Any way can achieve this?
PS:
I've checked the following approaches:
1.change the classloader of the java program. (we CANNOT change it)
2.use java proxy. (We CANNOT use java proxy, because java proxy would create a new proxy object. We DON'T use the proxy object. We need to hook the java program's object, and Use that object)
3. use -javaagent option ( we CANNOT add the commandline option for the java program.)
PS more [Edited again]:
My classes was loaded by ext class loader (I put my jar files in JAVA_HOME\lib\ext folder).
The large java program is an applet program loaded by Browser. When the browser start the applet, it also loads my classes.
PS more more [Edited again]:
Although it's running in Applet. I can have full permission. Because I can modify java.policy and java.security file.
Thanks,
Calvin
Just use -javaagent opiton, which is used to modify the bytecode at runtime. You can find more about -javaagent from This Link or from This Link
There are several libraries which you can use. See for example here.
Once a class was already loaded/initialized by the VM it will be impossible to manipulate, though.
By the way, in principle you can also just replace the class to be 'hooked' with your own proxy class file. As long as the class' visible interface does not change this may work. (Sub-classes of the class may horribly fail at runtime though.) This replacement can be as easy as changing the classpath so that your class of the same name will be found first, before the original one. Delegating to the original class of the same name may be a little more complex in this case.
Yes, you can, but the process would be a bit tricky, as you would operate directly with memory. For this purpose, you'd look at unofficial documentation on sun.misc package and its Unsafe class.
Warning 1: the Unsafe class would be removed in JDK 9 according to official sources.
Warning 2: the Sun company would not take responsibility for your code to work correctly, as this class should not be used at all, and exists for system usage only.
Sorry, but this is not possible. First off, bytecode is immutable after classloading. The JVM provides several APIs that can be used to do something like this, but they are obviously highly privileged.
If you're running in a low privilege environment like a browser Applet, then you're obviously not going to be allowed to do this, and any method you could should be considered a security vulnerability.
But the question is why you are using applets in the first place, and why you want to modify code after loading. There's almost certainly a better way to do what you're trying to do.
Every once in a while I'm in the Eclipse Debug mode, and wish I could simply pick the Object that I am currently inspecting/watching, put some kind of "Object Breakpoint" on it, and step to the next line of code that accesses it.
Now, I know that I can put breakpoints on Classes, but I usually have hundreds or even thousands of instances in memory, most of which have a long life time. They often go in and out of frameworks. They are wrapped into Collections, filtered and unwrapped again. In short: a regular, large application.
Usually I still find the problem by looking for rare features of that Object, using conditional method breakpoints and a lot of informed guessing. However, I think I sometimes could be much faster if I had something like the described feature.
What I found after some searching is the Debug Proxy (scroll down to examples). It is a container class that will use Javas reflection API to make itself look like the contained Object, thus you can use it instead of the contained Object in your application. Being an InvocationHandler, the DebugProxy can now "intercept" invocations of methods in the contained Object.
Using the proxy for actual debugging is as easy as adding this line to your application.
IMyObject = (IMyObject) DebugProxy.newInstance(new MyObject());
I can then set breakpoints inside the DebugProxies source code.
However, there are at least two problems with this approach.
It works but it is still a hack, and there are a lot of features missing, such as filtering options.
The Proxy-Object cannot be down-cast to the implementing class.
The 2. problem is the more serious one. I was able to use the DebugProxy with Classes generated by EMF, and there is no problem to follow the Object throughout the Framework. However, when I am trying to debug code that doesn't use interfaces for all interesting Classes, the DebugProxy will quickly fail.
Does anybody know about alternatives?
Maybe the Eclipse JDT Debugger already has such a feature and I simply don't see it!?
I know there is the Java instrumentation API, and frameworks such as AspectJ. Could these be used to get a practical solution?
I added basic filtering to the DebugProxy and modified the output so Eclipse Console View shows a link to the calling line of code:
Problem number two remains unsolved, though. I put up the source code on GitHub. Maybe somebody will come up with something.
A completely different way to approach this would be to automatically add breakpoints with conditions comparing the current hashCode() with the HashCode of the Object in question. This may not be too difficult for someone who knows more about the JDT internals.
We have huge codebase and some classes are often used via reflection all over the code. We can safely remove classes and compiler is happy, but some of them are used dynamically using reflection so I can't locate them otherwise than searching strings ...
Is there some reflection explorer for Java code?
No simple tool to do this. However you can use code coverage instead. What this does is give you a report of all the line of code executed. This can be even more useful in either improving test code or removing dead code.
Reflections is by definition very dynamic and you have to run the right code to see what it would do. i.e. you have to have reasonable tests. You can add logging to everything Reflection does if you can access this code, or perhaps you can use instrumentation of these libraries (or change them directly)
I suggest, using appropriately licensed source for your JRE, modifying the reflection classes to log when classes are used by reflection (use a map/WeakHashMap to ignore duplicates). Your modified system classes can replace those in rt.jar with -Xbootclasspath/p: on the command line (on Oracle "Sun" JRE, others will presumably have something similar). Run your program and tests and see what comes up.
(Possibly you might have to hack around issues with class loading order in the system classes.)
I doubt any such utility is readily available, but I could be wrong.
This is quite complex, considering that dynamically loaded classes (via reflection) can themselves load other classes dynamically and that the names of loaded classes may come from variables or some runtime input.
Your codebase probably does neither of these. If this a one time effort searching strings might be a good option. Or you look for calls to reflection methods.
As the other posters have mentioned, this cannot be done with static analysis due to the dynamic nature of Reflection. If you are using Eclipse, you might find this coverage tool to be useful, and it's very easy to work with. It's called EclEmma
I have taken a look at the PMD api which I want to use to detect unused instance variables and methods in a class. I see that it can be invoked from the command line, however I would like to perform a redundancy analysis of my class by invoking PMD programatically. Unfortunately, the api doesn't contain any information regarding the various classes and methods. Does anyone have any information regarding how PMD can be invoked to detect redundant code programatically?
Do you mean invoke it as a part of your build? It wouldn't make much sense to invoke PMD to analyze the source code during the runtime of the actual application.
Take a look at maven-pmd-plugin or the Ant task.
Have you heard of any library which would allow me to set up tracing for specific methods at runtime?
Instead of adding (and removing) lots of System.out.println in my code (and having to re-compile and re-deploy) I would like to have a magic thing which would print out a line for each call of selected method without any change in the code. This would work without re-compiling, so some kind of JVM agent (or some non-standard JVM would be needed?). Sounds like a job for aspect programming?
A typical scenario would be to start an application, configure the traced methods dynamically (in a separate file or similar) and then everytime a selected method is called a line with its name (and arguments) is printed out to System.out (or some log file).
Naturally one could think of tens of additional features, but this basic set would be a great tool. BTW, I use Eclipse interactive debugger too, not only the System.out tracing technique, but both have some advantages and sometimes Eclipse is not enough.
Yes what you are referring to is known as Aspect oriented programming. A typical library providing this for Java is AspectJ. You define what are called pointcuts, essentially regular expressions for classes and method names, including wildcards, and the code to execute at each pointcut, known as an advice. This is useful for logging and also security checks and similar cross cutting concerns.
You can turn pointcut advices on and off through configuration. You can have an advice execute before a method call, after it returns or even after it throws an exception. Arguments are also available.
An aspectj java agent is needed for this to work.
In my experience, that kind of very detailed tracing (much more detailed than one would normally use for logging) as a debugging technique is indicative of insufficient unit testing and integration testing.
You can do this using a tool called InTrace.
NOTE: InTrace is a free and open source tool which I have written.
Log4J useful for disabling logging depending on "log-level" (DEBUG, INFO, WARN, FATAL).
You specify in configuration file what the least level you want to appear in logs, e.g., don't log anything below INFO level, and voila!
Looks like there's yet another solution - called Byteman. In their own words:
Byteman is a tool which simplifies tracing and testing of Java
programs. Byteman allows you to insert extra Java code into your
application, either as it is loaded during JVM startup or even after
it has already started running. The injected code is allowed to access
any of your data and call any application methods, including where
they are private. You can inject code almost anywhere you want and
there is no need to prepare the original source code in advance nor do
you have to recompile, repackage or redeploy your application. In fact
you can remove injected code and reinstall different code while the
application continues to execute.
Jackplay is the tool you are looking for.
It allows you to enable logging on method entry and exit points without any coding or redeployment.
It also allows redefining a method body. It gives you web based UI as control panel to enable or undo tracing on your class.methods.