I am currently learning about Reflection and I have seen most of the similar posts to my question on stack however, I don't feel they fully answer my question on it.
I want to know if I have a package in Eclipse can I use Reflection to iterate through the classes in the package to find which one implements interface. There is only 1 interface so either they implement it or don't.
Could anyone provide a basic clear example as to how I may go about this? I have been told by some that this is just not possible whilst other people say it is possible using Reflection.
Thank you to any one who could help clear this matter.
Reflection API does not provide directly facility to iterate over classes in specific package. It concentrates on discovery of class once you have it.
To achieve what you want to have to read the class path of your application, iterate over the class path, open jars and go into directories, find files that end with *.class and get them as resource like getResource(full_class_name) or get it directly as class using Class.forName().
This method has a limitation: you will not see classes loaded by custom class loaders.
Unless this is an exercise I'd recommend you to use Reflections library that does everything you need and (probably) even more... :)
Some more details
Java system property "java.class.path" contains class path of your application separated with ; on Windows and : on Unix.
So, this is the way you can get list of class path elements:
System.getProperty("java.class.path").split(File.pathSeparator)
Here is some code sample that can help you to start:
for (String cpElement : System.getProperty("java.class.path").split(File.pathSeparator)) {
File cpFile = new File(cpElement);
if (!cpFile.exists()) {
continue;
}
if (cpFile.isDirectory()) {
findClassesInDirectory(cpFile);
} else {
findClassesInArchive(cpFile);
}
}
Etc, etc. I am leaving implementation of findClassesInDirectory() and findClassesInArchive() for you. Nice exercise. Have fun.
have you heard of guava-libraries for Java.
They provide useful utilities regarding reflection.
For your specific problem, I would have a look a the TypeToken and the method getTypes().
Good luck
yes you can so it. But with eclipse its more of an AST tree translation and not reflections. See if you want to iterate over source code and see which source file implements the interface you probably need AST tree walkers to do that. But on the other hand if you want to introspect at runtime the class files in a given package or a folder which implement the said interface then you need Reflections to do that. Either way its doable. I cant give you the code to try that out as a little time with Google will give you the answers you need though not all at the same place.
Reflection does not provide all operations for a total inspection.
For a known class one can get the physical URL of a class SomeClass using:
CodeSource codeSource = SomeClass.class.getProtectionDomain().getCodeSource();
if (codeSource == null) {
// Run-time class; URL into the rt.jar.
} else {
URL url = codeSource.getLocation();
// "file:/.... /classes/.../SomeClass.class"
// "jar:file:/... /someJar.jar!/.../SomeClass.class"
}
For Java run time classes (rt.jar) codeSource will be null.
On the URL of the jar you can open a (zip) file system, and walk through folders as any real file system.
You'll probably want to inspect classes without $ in the name (embedded, generated anonymous classes): only fileName.matches("[^$]+\\.class").
Related
How to get the variables name declared within a method in java class?
for eg:
public class A {
String x;
public void xyz(){
int i;
String z = null;
//some code here
}
Method[] methods = A.class.getDeclaredMethods();
for (Method q = methods){
//some code here to get the variables declared inside method (i.e q)
}
}
How can i do that?
Thanks in advance..
There is no simple way to do this.
If those were fields, you could get their names using reflection. However, local variable and parameter names are not loaded into the JVM. So you would need to resort to reading the "A.class" file and extracting the debug information for that method. And the bad news is that if the class wasn't compiled with debug information, then even that wouldn't work.
There are libraries around for reading ".class" files for various purposes, but I can't give a specific recommendation.
But the $64,000 question is "But why ...?". What is the point of listing the local variable names for a method from Java? Can't you just look at the source code? Can't you dump the ".class" file with "javap" or decompile it with some 3rd party decompiler?
I thought for big programs it will be useful to understand and analyze it if we can come to know the variables their types and method names and their parameter list etc so only...
I think you just need a decent IDE ...
To paraphrase another answer, There's no simple way to do this with reflection.
There is a way to do it. You need a full Java source code parser and name/type resolver ("symbol tables").
The Java compiler offers internal APIs to get at that information. Eclipse JDT offers something similar. Our DMS Software Reengineering Toolkit offers a full parser with this information easily accessible, and considerable additional help to build analyzers and/or code generators that take advantage of this extra information. (You can see this information extracted by DMS in the example Java Source Code Browser at my site, see bio).
Frustrated with the damn awful API provided by WebSphere Admin Server, I'm writing my own Java DSL wrapper. My jython files now simply read:
from my.package import MyDSL
config = MyDSL(AdminConfig, AdminTask)
config.goGoGadgetSkates() # or something like that
The essential part is that I send through the (#%$$!##) god objects AdminConfig and AdminTask so that the DSL can use them to perform operations in WAS.
In order to compile the DSL I need to include the class files for this two objects. I find them by first setting the constructor as:
public MyDSL(Object a, Object b) {
System.out.println(a.getClass());
System.out.println(b.getClass());
}
The output showed that the AdminConfig object is an instance of com.ibm.ws.scripting.AdminConfigClient. I easily located the jar that contains this class and all is well.
But AdminTask is an instance of com.ibm.ws.scripting.adminCommand.AdminTask. Despite being present at runtime, this class does not exist anywhere in my classpath or indeed anywhere on my computer's hard drive.
I can only assume com.ibm.ws.scripting.adminCommand.AdminTask is constructed magically by WSAdmin in the jython layer. Perhaps it is defined as a python class?
Before I resort to reflection, can someone please explain where com.ibm.ws.scripting.adminCommand.AdminTask might live and how I might extract a copy of the class file?
The AdminConfigClient class is not API/SPI, so you are creating a fragile infrastructure by relying on that class. The API/SPI entry point is ConfigServiceFactory.
The AdminTask object is backed by the data in CommandMgr. It should be possible to use CommandMgr to do anything you can do with AdminTask.
I want to list/enumerate (at runtime) in my Java program all classes that implements a given interface, and retrieve the class name. Is it possible ? How can i do ?
To elaborate on how to do that using reflection :
You can start off with Thread.currentThread().getContextClassLoader().
Using a package name as path, get at the resources : Enumeration<URL> resources = classLoader.getResources(path);
Then you would have to decode the filenames from the resources, and iterate over them (recursively as some might be directories). Filter the resources for .class files, instantiate the classes with Class.forName() and check the interfaces they implement.
You should use java Reflection
This link offers a tutorial that cover all the thing you can do using Reflection. You can build your code starting from there
Is it possible to load a class by name if you don't know the whole package path? Something like:
getClassLoader().loadClass("Foo");
The class named "Foo" might be around, might not be - I don't know the package. I'd like to get a listing of matching classes and their packages (but not sure that's possible!),
Thanks
Nope. The Java ClassLoader.loadClass(String) method requires that class names must be fully qualified by their package and class name (aka "Binary name" in the Java Language Specification).
If you don't know the package, you don't know the name of a class (because it's part of the fully qualified class name) and therefore cannot find the class.
The Java class loading mechanism basically only allows you to do one thing: ask for a class with its fully qualified name, and the classloader will either return the class or nothing. That's it. There#s no way to ask for partial matches, or to list packages.
Contrary to the previous answers, and in addition to the answers in the question #reader_1000 linked to:
This is possible, by essentially duplicating the logic by which Java searches for classes to load, and looking at all the classfiles. Libraries are available that handle this part, I remember using Reflections. Matching classes by unqualified name isn't their major use case, but the library seems general enough and this should be doable if you poke around. Do note that this will, very likely, be a fairly slow operation.
Using java Reflections:
Class.forName(new Reflections("com.xyz", new SubTypesScanner(false)).getAllTypes().stream()
.filter(o -> o.endsWith(".Foo"))
.findFirst()
.orElse(null));
Even if you don't know the package name, sites like jarFinder might know it
I have a jar file. I want to know which external classes and methods are used by classes inside JAR file. Can anyone suggest me any tool?
For example - if below two classes are packaged into Myjar.jar
import java.util.Vector;
class MyJarClass{
public static void main(String args[]){
Vector v = new Vector();
AnotherClass another = new AnotherClass();
v.addElement("one");
another.doSomething();
}
}
class AnotherClass{
void doSomething(){
}
}
When I supply that JAR to a tool - the tool should show java.util.Vector and Vector.adElements() are from external source (not present in MyJar.jar)
Forgot to mention, i don't have access to sourcecode.
Easy
import com.example.*;
Possible
List<com.example.MyType> = new ArrayList<com.example.MyType>();
A challenge
Class<?> clazz = Class.forName("com.example.MyType");
Mission impossible
List<String> classes = getClassNamesFromUrl("http://example.com/classes.txt");
for (String className:classes) {
doSomethingWith(Class.forName(className));
}
I support Jon's advice to look at the byte code (BCEL) but just be aware, that in general it is not possible to read all dependencies from a jar, as they can be dynamic and defined outside the library (see: Mission impossible).
Hard to tell if there's a tool, have a look at those directories on java-source.net:
Open Source ByteCode Libraries in Java
Open Source Code Analyzers in Java (has some applications to work on jars too, like JDepend. JarAnalyzer sounds promising too, but it is quite old, last update in 2005)
Further reading
How can I visualize jar (not plugin) dependencies? (especially VonC's answer)
You might want to look at BCEL, which will allow you to parse the class files and find out what they use. I expect it'll be a certain amount of effort though.
Check untangle
It's a small cli utility that searches usages of class or packages inside jars or directories containing classes.
Disclaimer: I'm the author of untangle
Check JDepend
The graphical user interface displays the afferent and efferent couplings of each analyzed Java package, presented in the familiar Java Swing tree structure.
JavaDepend could help you for such needs, you can for any code elements get all elements used, it can be jar, namespace, class or method.
CQL an SQL like to query code base gives you more flexibility to request any info about your code.