Finding usages of Java Reflection in a codebase - java

I'd like to avoid using Reflection where possible. I have a legacy codebase to refactor that has at least one getMethod(), and now I'm afraid to delete functions that seem to be dead.
How can I easily find places in the code where I can work backwards from? Is there a static analyser that can collect Reflection API usage?
Searching for every variant of getClass() and getMethod() seems tedious.

I don't know of any tools on top of my head but it wouldn't be to hard to write script which traverses project structure, going through all directories(packages) and checks in each file if it contains import of java.lang.reflect or calls to getMethod()/ getClass().
There is FileVisitor interface in java which can help you do this.
This answer might also help you as an alternative to FileVisitor
. There is implementation of breadth first search traversal of directories, so you would have to add on top of it:
Read all files from directory
For each file check if it contains reflection keywords as mentioned above
Generate report for each file found
Keep in mind that reflection might be there for problems which are otherwise not possible to solve. Think of frameworks which must work with any supplied classes, processing of runtime annotations and so on.
Hence i would suggest you to be sure that the problem solved by reflection can be and is worth refactoring.

Related

Find out used classes and methods from Java source code

For Java source files, I would like to find out:
Which classes use which other classes (fully qualified names)?
Which methods call which other methods (fully qualified names)?
What would be a reasonable way to achieve that?
EDIT:
To clarify: I want a list of source code files as input. The output should be (as specified above) which class uses which other class and which method calls which other method. I do not want to inspect other loaded classes at runtime, like when using reflection.
You need to use static analysis tool as STAN standalone mode:
The standalone application is targeted to architects and project managers who are typically not using the IDE.
Or JArchitect (available also using command line)
JArchitect is a powerful tool for static code analysis. It can provide a lot of insight into complex code bases. Using custom code queries you are able to build your own rule sets in a very comfortable way.
In the Class Browser right-click menu, JArchitect proposes to explore the graph of dependencies between members (methods + fields) of a type.
Another option is SourceTrail
The graph visualization provides a quick overview of any class, method, field, etc., of interest and all its relations. The graph is fully interactive. Use it to move through the codebase by focusing on related nodes and edges.
(source: sourcetrail.com)
Unfortunately, reflection doesn't give you all the information you need to do this.
I've done it with ASM (https://asm.ow2.io/).
It provides the ability to walk the byte code of all of your classes using the visitor pattern, including the actual method implementations, from which you can extract the references to other classes.
I'm sorry that I cannot provide the implementation, because it's proprietary.
Note that this works from your .jar files, not your sources. If you really need to work from sources, then have a look at https://github.com/javaparser . Really, though, it's better to use the byte code, since the java language changes frequently, while the byte code specification does not.
I am not sure how to get a listing, but for identifying refactoring opportunities, you might try IntelliJ IDEA. It will dull out the signature line of any methods that are not accessed in the project. It will also detect code segments that are repeated elsewhere in the project, so you can extract common code.

Modify Java sourcecode programmatically with Java or Groovy

To automate certain manual tasks in an legacy project, I need to modify existing java files from within java or groovy code.
I donĀ“t want to use RegEx, because it would be neither quick nor clean in my opinion.
I found javassist and srcgen4javassist. The first one lets me modify my sources as I wish, but only writes bytecode, loosing all comments and annotations. And with the second one I didnt manage to read an existing Class not created with srcgen4javassist itself.
Is there an elegant solution, or do i need to bite the bullet and use Regex?
you could really parse the code using something like eclipse's ASTParser at which point you coudl locate your replacement targets xpath-style, but its a lot of work.
you could also consider marking replacement areas with annotation and writing an annotation processor to generate/alter sources at runtime, but (at least in my opinion) the API is cumbersome.
you can combine regexp with some marker in the source code, something like
//START REPLACEMENT-TARGET
...code to be edited/replaced
//END REPLACEMENT TARGET
which would make your regexp targeting a lot safer.

Java: Locate reflection code usage

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

Is there a way to get all the classes that implement a certain method?

The title speaks for itself. The language is Java.
Yes, there is. This is however a tedious and expensive work. You need to crawl through all class files and all JAR files with help of ClassLoader#getResources() and a shot of java.io.File and load all classes of it with help of Class#forName() and finally check if the method is there by Class#getMethod().
However, there are 3rd party API's which can take the tedious work from hands, but it is still expensive, because loading a class would cause its static initializers being executed.
A cleaner way is to make use of annotations and annotate the methods in question and then make use of libraries which searches for classes/methods/fields based on the annotations, such as Google Reflections.
On the other hand, if the entire package name or the JAR file name is known beforehand, then the work will be less tedious and expensive (no need to do stuff recursively nor to load the all of the classes of entire classpath).
Update: I remember, I ever wrote sample code to achieve something like that, you can find it here. It's good to start with, you only need to change it a bit to check the method.
No, you can't, in general. If you could get a complete list of available classes you could check each of them using reflection - but you can't ask a classloader for a list of everything that's available. (For instance, it may be fetching classes over HTTP, and may not know all the files available.)
If you knew that you were interested in classes in a jar file, however, you could open the jar file, find all the class files within it and ask the classloader for those classes. It would be somewhat fiddly.
What's the bigger picture here? There may be a better way to approach the problem.
Also, in Eclipse, you can simply ask for this :
Clic on the method, and type Ctrl-T.

How do I strip the fluff out of a third party library?

It may not be best practice but are there ways of removing unsused classes from a third party's jar files. Something that looks at the way in which my classes are using the library and does some kind of coverage analysis, then spits out another jar with all of the untouched classes removed.
Obviously there are issues with this. Specifically, the usage scenario I put it though may not use all classes all the time.
But neglecting these problems, can it be done in principle?
There is a way.
The JarJar project does this AFAIR. The first goal of the JarJar project is to allow one to embed third party libraries in your own jar, changing the package structure if necessary. Doing so it can strip out the classes that are not needed.
Check it out at http://code.google.com/p/jarjar/.
Here is a link about shrinking jars: http://sixlegs.com/blog/java/jarjar-keep.html
There is a tool in Ant called a classfileset. You specify the list of root classes that you know you need, and then the classfileset recursively analyzes their code to find all dependencies.
Alternatively, you could develop a good test suite that exercises all of the functions that you need, then run your tests under a test coverage tool. The tool will tell you which classes (and statement in them) were actually utilized. This could give you an even smaller set of code than what you'd find with static analysis.
I use ProGuard for this. As well as being an excellent obfuscator, it has a code shrinking phase which can combine multiple JARs and then strip out any unused classes or class members. It does an excellent job at shrinking.
At a previous job, I used a Java obfuscator that as well as obfuscating the code, also removed classes and methods that weren't being used. If you were doing "Class.byName" or any other type of reflection stuff, you needed to tell the obfuscator because it couldn't tell by inspecting the code what classes or methods called by reflection.
The problem, of course, is that you don't know if other parts of the third party library are doing any reflection, and so removing an "unused" class might cause things to break in an obscure case that you haven't tested.
jar is just a zip file, so I guess you can. If you could get to the source, it's cleaner. Maybe try disassembling the class?
Adding to this question, can that improve performance? Since the classes not used would not be JIT compiled improving startup time or does the java automatically detect that while compiling to bytecode and do not even deal with the code that is not used?
This would be an interesting project (has anyone done it already?)
I presume you'd give the tool your jar(s) as a starting point, and the library jar to clean up. It could use reflection to determine which classes your jar(s) reference directly, and which are used indirectly down the call tree (this is not trivial at all, but doable). If it encounters any reflection code in any of the two places, it should give a very loud warning.

Categories

Resources