This question already has answers here:
How can I get a list of all the implementations of an interface programmatically in Java?
(11 answers)
Find Java classes implementing an interface [duplicate]
(9 answers)
Closed 9 years ago.
Can I do it with reflection or something like that?
There's no 100% reliable way to do what you want. The reason is because of how class loading works in Java.
Classes, in Java, are loaded "on demand". The first time a class is referenced in code (either statically or dynamically), the JVM will use the current class loader and try to load it. A ClassLoader has no method that gives all the classes that could be loaded from it, therefore you cannot iterate on classes.
There are some unreliable workarounds. For instance, if you know your ClassLoader will only ever load classes from inside a specific directory, or a specific JAR file, you can then use the classes related to your file system to find what ".class" files are available, then you can load everything (which takes time and will consume a lot of your PermGen, which might be a problem -- remember that you cannot easily unload a class! (unless you do some ClassLoader magic)), and use reflection to filter the classes implementing your interface.
The problem with this workaround is that it will most probably stop working if you ever change your deployment. For instance, if you start deploying a JAR file, then later on you decide to use a servlet container that will deal with WAR files, your code might not work anymore.
If you really want to try this approach, there's a project called Reflections that might be useful.
The most reliable way I've ever implemented this is by using an Annotation Processor. You write an annotation, you annotate your interface, and you write some code that will get executed by the compiler, in compile-time, that will collect the classes implementing your interface and save their names in a resource file. Then you write a class with a method that reads that file and gives you a Class object for each class name listed in that resource file.
The problem with this approach is that only classes that are compiled in my build process will get listed (ie, if you publish a library with an interface and expect others to implement your interface, this approach won't be useful, since your code will never know about the class in others' projects). If this is enough for you, as it was for me, this solution works flawlessly. I can use it in Servlet Containers with WAR (exploded or not) deployments, in executable jars, whatever. It will always work.
Related
I'm using AndroidStudio with maven. what i don't understand is how duplicate classes don't confuse classloaders nor the build process.
I made my own android.util.Log class (like, i made a android.util package inside my app, and inside it i made my own Log class), instead of using the standard android Log.d, i use my own. How and why does this work?
i've read somewhere that there are 3 classloaders - your application classloader, 3rd party libs classloader, and system classloaders. so is it that they go in some kind of priority, where if your application classloader finds the .class file then it gets "linked"? and any other duplicate .class files just don't matter?
and... why isn't this behaviour causing any kind of build errors/warnings?
an example is that ... say i want to use reflection to call a certain private class that both i and android will provide. i want guarantee that whether or not it calls mine or ANdroid's, there's not clash that causes a crash. but i'd like to know exactly why/how it works the way i'm seeing it work.
ClassLoaders are organized in a hierarchy:
http://docs.oracle.com/cd/E19501-01/819-3659/beadf/index.html
This may point to what you're looking for:
http://yenliangl.blogspot.fr/2009/11/dynamic-loading-of-classes-in-your.html
In the past few weeks, I've run into several different peoples' code using .class objects. For example, ArrayList of classes : ArrayList<Class> but how to force those classes to extend some super class?.
I looked them up: http://docs.oracle.com/javase/tutorial/reflect/class/index.html
I'm just wondering why you'd want to use .class objects. I can see getDeclaredFields() and getDeclaredMethods() being potentially useful, but I can't really think of concrete examples as to why I'd actually want to use the .class objects in lieu of something else. Could anyone shed some light on this topic?
Thanks in advance.
I think you misunderstood the concept. Class class has nothing to do with compiled classes (.class).
Class is a class that represents a Java class internal structure, such as fields, methods, etc... This is a compile-time entity, which you can use in your code (even before compiling).
.class is a compiled Java class file, which is Java bytecode. This is not a "code" entity (you cannot use it as a class or object in your code -besides as any file-) and it is not available before compilation.
Reflection (Class is part of the reflection package) is useful when you want to do advanced stuff with the code, like manipulating it, accessing its members, getting information from it, etc...
A typical example where you want to use reflection is making a Java debugger. Since any code can be run on the debugger, you need reflection to get information about the object instances and their structure and show this to the user.
Reflection is one reason to use it. Another good example is dynamically constructing objects at runtime.
For example, the Spring framework uses configuration files that contain the names of Java classes. Somewhere in that code, Spring needs to build object instances of those classes. In this way, the objects are created without the compiler needing to know anything about the Java classes at compile time.
This can be useful when developing an interpreter of a scripting language running on JVM, which has an ability to call Java methods.
Also, might be useful in a system allowing for plugin extensions.
Another use case:
InputStream is = MyClass.class.getResourceAsStream("/some/resource/in/the/jar");
Plug-in are a big use for this.
Dynamically load .class files which are in say, your plugins folder and execute some specified function from said files. Then, you can have 0 or more plug-ins and any combination of them installed for your application at a time.
Is there anyway to find all the class names which are extending a particular class by using classloader information?
More Detailed Explanation
I have a jar file which has 3 classes X (extends A), Y (extends A) and Z (extends B). I have put this jar file into the classpath and start the JVM (calling main method of some class). Now from this main method is there any way to find the classes which are sub classes of A? i.e. classes X and Y as they are extending the class A.
Unfortunately there's no easy way to do it. The JVM has no information about a particular class until it gets loaded by a classloader. But to have the classloader actually load the class, you must know the name of the class. Chicken and egg problem.
However, there is some other, but a bit more complicated way.
To determine which .jar files are on the classpath when running your application, you can call the System.getProperty("java.class.path") then split the classpath entries along the File.separatorChar characters. Classpath entries may be numerous, consider filtering them somehow (limiting only to a specific directory, leaving out standard entries like rt.jar, etc.)
If you know which .jar file contains your classes of interest, you can open it with an instance of the class JarFile. Then you can iterate over all entries (eg. .class files) and from their internal path in the JAR file you are able to construct their fully qualified class name.
With the classname in your hand, you can call Class.forName() to load the class, and the you can use reflection to get the superclasses of each class to find out whether it extends your particular class or not.
Note that this method is quite resource consuming, you make the JVM to actually load all the classes from a .jar file (or multiple .jar files), even if you won't use them later. This wastes a fair amount af memory (PermGen space).
There are some low-level libraries that manipulate Java bytecode and class files (see BCEL or ASM). Using them you will be able to determine the superclass for a class without actually (class)loading it, thus this way is more faster and uses less memory.
Your question resembles the way JavaEE application servers work when deploying a web application. To find out which classes to load and initialize as for example HTTP servlets they must examine all classes in the web archive looking for a specific Java annotation or superclass. However they are at least know which .war file to scan. Apache Tomcat for example uses BCEL instead of Java classloading mechanism.
If you're designing some sort of dynamic classloading mechanism for your application, then consider other design options to narrow down the numbers of classes your loader must scan to find the proper class to load: Telling the exact name of the .jar file instead of putting it on the classpath, using some meta information in the JAR (you can use the aforementioned JarFile to read entries from the META-INF/manifest.mf file) to specify which classes to look for, etc.
just fore the sake of completeness
http://code.google.com/p/reflections/
others where mentioned in the linked post
I'm quite restricted in the platform I'm currently working on (JDK 1.3, BD-J). One JAR file I would like to use attempts to perform a self-integrity check on load and if it fails it goes into an inoperable state. It's quite difficult to find out why this is happening but most sources point to that it cannot find/access it self through the BD-J structure, so it dies.
This rules out using it at load time and instead to load it in the application itself. This is quite a large library so I have to create quite an amount of interfaces so I can cast a loaded object to it and potentially use it. This is where my problem lies.
The interfaces are loaded on normal load time and the library is then loaded during run time and casted to the previously loaded interfaces, is this a problem? I'm receiving ClassCastException
I've based the interfaces off the libraries public methods as best I can, but when I attempt to cast to an interface I receive the ClassCastException. Note: It all loads fine, I can access constructors and read the method names. Just when casting it for it to be useable it fails.
The interface packages are different in my project to that of the toolkit, does this matter?
I'm running out of ideas, is there something I have overlooked?
Thanks.
I'm not sure I fully grok what your problem is - maybe some more details about what the class hierarchy looks like would help in figuring out the situation. From what you wrote I can guess two possible scenarios:
.1. The classes you want to use do not implement any interface.
In this case no matter what you name your interfaces, it will not work, since the classes you're loading do not implement them. You're stuck with using reflection if you can't load that jar as part of the boot classpath.
.2. The classes you want implement some interface that you're trying to replicate.
In this case you interface implementation must match the exact qualified name of the interface the classes are implementing. Normally, when loading the classes from the jar, the class loader will pick up the interfaces from the system class loader first, thus loading your interfaces, and everything should work.
If they use some crazy internal class loader, though, they might still try to load their own interfaces. You could try to figure out if that's the case by using "-XX:+TraceClassLoading", although I don't know if the 1.3 jre will understand that option.
Now if you're willing to experiment more, you could also try another approach. Write your own class loader that loads both the classes from that jar and the code you want to run. That way, your code would be able to directly refer to the classes in that jar, but to start your application the "main" method will have to be one that initializes this classloader, loads the "real" main class using reflection, and executes its main() method also via reflection.
Most probably the classes are loaded by different class loaders. http://mindprod.com/jgloss/classloader.html may give some idea.
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Can anyone point me a good resource or explain me about the concept behind Class Loaders? I found the following resource on class loaders http://www.onjava.com/lpt/a/5586 but still no help. The following questions may look silly but trying to answer them always confuses me.
Why do developers write Custom class loaders, why not invoke a Bootstrap class loader to invoke your custom classes? What is the need to define custom class loaders?
Why there are so many varieties of class loaders? eg: Bootsrap, Comman, Catalina class loader etc.,
Thanks in advance.
I found the following, valid reasons to create custom classloaders:
You want to load a class from an unconventional source (For example, the bytecode for one class is stored in a database, across the network or carried as 0 and 1s by pidgeons - MessengerPidgeonClassLoader). There is some ClassLoader implementations already in the API for such cases, such as URLClassLoader.
You need to define a different hierarchy to load classes. Default implementations of the ClassLoader delegate the search first to the parent, then they try to load the class themselves. Maybe you want a different hierarchy. This is the reason why OSGI and Eclipse have its own ClassLoaders as the Manifest .MF files define all types of weird hierarchy paths (buddy-classloading, for example). All Eclipse classloaders implement the BundleClassLoader interface and have some extra code to find resources within Eclipse Plugins.
You need to do some modification to the bytecode. Maybe the bytecode is encrypted, and you will unencrypt it on the fly (Not that it helps, really, but has been tried). Maybe you want to "patch" the classes loaded on the fly (A la JDO bytecode enhancement).
Using a different classloader than the System Classloader is required if you need to unload classes from memory, or to load classes than could change their definition at runtime. A typical case is an application that generates a class on the fly from an XML file, for example, and then tries to reload this class. Once a class is in the System Classloader, there is no way to unload it and have a new definition.
A common use of classloaders is to isolate a JAR. If you have an application which uses plugins (Eclipse, Maven 2), then you can have this situation: Plugin X needs jar A with version 1.0 while plugin Y need the same jar but version 2.0. X does not run with version 2.0, though.
If you have classloaders, you can create partitions of classes (think of isolated islands connected by thin bridges; the bridges are the classloaders). This way, the classloaders can control what each plugin can see.
When plugin X instantiates a class Foo, which has static fields, this is no problem and there won't be a mixup with the "same" class in plugin Y because each classloader will in fact create its own instance of the class Foo. You then have two classes in memory, where cl1.getName().equals(cl2.getName()) is true but cl1.equals(cl2) is not. This means that instances of cl1 are not assignment compatible to instances of cl2. This can lead to strange ClassCastExceptions which say that org.project.Foo can't be assigned to org.project.Foo.
Just like with remote islands, the two classes are not aware that the other one exists. Think of human clones which are born and then raised on different islands. From the point of view of the VM, there is no problem because instances of the type Class are handled like any other object: There can be several of them. That you think that some of them are "the same" doesn't matter to the VM.
Another use for this pattern is that you can get rid of classes loaded this way: Just make sure that no one has a pointer to any object created from classes loaded from a classloader and then forget about the classloader, too. On the next run of the GC, all classes loaded by this classloader are removed from memory. This allows you to "reload" your application without having to restart the whole VM.
Another good link for java class loaders - Java classloaders
A couple blogs I've written in the deep past about using post-delegation classloaders:
Writing a post-delegation classloader
A Tale of Two Classloaders
You can't go past the raw source, in cases like this. If you really want the inside dope, the hard core, read the relevant bits of the Java Virtual Machine Specification.
It's extremely rare that you need to create your own ClassLoader. And genereally if you need to, you should already have a really good understanding of what the ClassLoader does.
In other words, if you're asking why you would need to create your own ClassLoader, then you don't need to create one ;)
That being said, I've also seen a ClassLoader being created for an application that dealt with cryptography. This way every time you create a java.netSocket or some kind of file/stream object, instead of using the JVM versions it would use their own special custom built classes. This way they could guarantee the that all information was encrypted and that there were no developer errors.
But it's not very common. You can go a whole Java career without ever needing to create your own custom ClassLoader. Actually if you need to create one, you should really ask if it's necessary.
An example:
Tomcat use customized WebAppClassloader to load and isolate classes/jars from different web applications.
Why do developers write Custom class loaders, why not invoke a Bootstrap class loader to invoke your custom classes? What is the need to define custom class loaders?
Depending on the application, the developers might override or completely replace the class loading mechanism to suit their needs.
For instance, I have used one application whose classes are loaded from a LDAP :S
Other apps need independent class managing ( like most of the application servers that support hot-deploy )
About resources, there are TONS, in the web, that simply cannot be listed.