Accessing every child class of parent class in Java - java

I have to implement a logic whereby given a child class, I need to access its parent class and all other child class of that parent class, if any. I did not find any API in Java Reflection which allows us to access all child classes of a parent class. Is there any way to do it?
For example:
class B extends class A
class C extends class A
Now using class B, I can find the superclass by calling getSuperClass(). But is there any way to find all the child classes once I have the parent class i.e. class B and class C??

If this wasn't homework (where 3rd party librares are probably not allowed), I would have suggested Google Reflections' Reflections#getSubTypesOf().
Set<Class<? extends A>> subTypes = reflections.getSubTypesOf(A.class);
You can do this less or more yourself by scanning the classpath yourself, starting with ClassLoader#getResources() wherein you pass "" as name.

You are correct: there is no direct API for this. I guess you could scan all loaded classes and see if they are a subclass of a given class.
One problem: you'll only able to find classes that are already loaded. None of these methods will find classes that haven't been loaded yet.

You can use:
thisObj.getClass().getSuperclass()
thisObj.getClass().getInterfaces()
thisObj.getClass().getGenericInterfaces()
thisObj.getClass().getGenericSuperclass()
I recently coded something to scan the members of a class and if those were non-primitives scan those as well. However, I did not traverse upwards so I didn't use the above methods but I believe they should do what you want.
EDIT:
I ran a simple test with the following:
public class CheckMe {
public CheckMe() {
}
}
public class CheckMeToo extends CheckMe {
public CheckMeToo() {
}
}
// In main
System.out.println( CheckMeToo.class.getSuperclass() );
// Output
class CheckMe
After that it's a matter of coding the traversal. If its parametrized then things may get a little complicated but still quite doable.
EDIT: Sorry didn't read carefully, let me look further into it.
EDIT: There doesn't seem to be any way to do it without scanning everything in your CLASSPATH and checking to make sure an object is an instance of some class.

Related

java dynamic class loading that avoids java.lang.IllegalAccessError

Oracle JavaDocs explains that IllegalAccessError is
"Thrown if an application attempts to access or modify a field, or to
call a method that it does not have access to."
I try to load a class dynamically and I get this exception.
if I understand correctly when you use a classloader to load a class with a private package dynamically IllegalAccessError happens
the class I am trying to load is using
org.xml.sax.helpers.SecuritySupport
which also states in their description in the following url
http://grepcode.com/file/repository.springsource.com/org.apache.xmlcommons/com.springsource.org.apache.xmlcommons/1.3.4/org/xml/sax/helpers/SecuritySupport.java
that
Unfortunately, we can't load the class using reflection
* because the class is package private. And the class has
* to be package private so the APIs aren't exposed to other
* code that could use them to circumvent security. Thus,
* we accept the risk that the direct reference might fail
* on some JDK 1.1 JVMs, even though we would never execute
* this code in such a case. Sigh...
how can I dynamically load it anyway? I have to get it to work.
also if I get an error when I use a classloader, I cannot recover from that, so how can I know in advance that I cannot load this class?
thanks in advance to anyone who helps
The statement “we can't load the class using reflection because the class is package private” doesn’t make any sense, as can be shown easily:
package somepackage;
class BaseClass {
public static void main(String[] args) throws ReflectiveOperationException {
BaseClass obj=(BaseClass)
Class.forName("somepackage.SubClass").newInstance();
obj.aMethod();
}
void aMethod() {
System.out.println("base class");
}
}
class SubClass extends BaseClass {
#Override
void aMethod() {
System.out.println("method overridden by subclass");
}
}
This works flawlessly, printing method overridden by subclass replicated the actual use case of that SecuritySupport class.
However, since that class obviously serves the purpose of allowing a transition between Java 1.1 and Java 1.2, it might be possible that there were such restrictions twenty years ago, when this transition happened.
Your use case, however, is entirely different. You say that you are trying to load a class which “is using org.xml.sax.helpers.SecuritySupport”, which doesn’t imply that it is using said class via Reflection, but as shown above, that doesn’t matter anyway. It either case, it would only work, if the class is in the same package, whether you load the class “dynamically” or not.
There are only two possible scenarios.
If the class is truly within the same package, which at runtime implies that it also has been loaded by the same class loader, which would require that is also part of the JRE, if the JRE’s org.xml.sax.helpers package defines a SecuritySupport class, then the class can access the class within the same package.
If you are trying to load a class via a different ClassLoader from a different code source, it will not be of that package, even if you’d give it a qualified name of the org.xml.sax.helpers.SomeClass form. If the JRE’s org.xml.sax.helpers package happens to define a SecuritySupport class, all non-JRE classes would be in a different package. When it tries to access that class, which is not part of the official API, it doesn’t work.
Note that all standard class loaders follow a delegation model trying to resolve a name through their parent class loader first, which is the reason why they all would prefer the JRE’s org.xml.sax.helpers.SecuritySupport class, if there is one. With non-standard class loaders, you could have different, unrelated classes with that qualified name, being in different runtime packages.
In that second scenario, the question arises, why your class is using that class. In 2017, there’s rarely a need to differentiate between Java 1.1 and Java 1.2 and the functionality offered by that class is also only relevant for a class within the privileged code source of the JRE (or different code sources with different privileges in general).

Understanding the difference between extending a class and importing a class [duplicate]

This question already has answers here:
What's the difference between importing and extending a class?
(10 answers)
Closed 7 years ago.
I have seen several threads that define extending a class as a way for a personalized class to inherit the methods of the class that it is extended to. When you import a class and create an instance of that class you have access to its methods, can someone please explain to me how extending a class to provide those methods to your own class is effectively different, in other words, the only difference I see is that when you import you create an instance of a standardized class, and when you extend you effectively turn your personalized class into the standardized class only with a different name. I am aware I am wrong, but the answers I have read have failed to help me fundamentally understand the difference.
Importing and extending are two very different things.
Importing
Classes are organized in packages, which provide a namespace facility that avoids name conflicts. Importing allows you to use the class in your code without the namespace information.
Importing is optional. You never have to import anything if you always use the fully qualified name of the class, but that makes your code hard to read.
If you want to make a list of Calendar objects, for example, you either import java.util.List, java.util.ArrayList and java.util.Calendar and use:
List<Calendar> array = new ArrayList<>();
Or import nothing and use:
java.util.List<java.util.Calendar> array = new java.util.ArrayList<>();
Sometimes you have two classes with the same name in different packages. In that case, if you use both of them in your code you can't import both. You will have to refer to one of them by their fully qualified name. For example:
List<java.awt.List> array; // you have to import java.util.List, but can't also import java.awt.List
Extending
When you extend in Java you are saying that the subclass is a type of the original class. That's the most important aspect you have to be aware of when using extends. Is you say Bus extends Vehicle you are saying that Bus is a Vehicle. You not only inherit all the non-private methods and fields of the superclass, but also can use the subclass anywhere you could legally use the superclass. For example, if you have this method:
public park(Vehicle v) {
v.drive();
v.turn(Direction.LEFT);
v.stop();
}
you could pass a Bus as an argument, because Bus is a Vehicle.
parkingLot.park(new Bus());
and the drive(), turn() and stop() methods will be called in the Bus. That is polymorphism.
Although you inherit methods, inheritance is not the best way to reuse code. Most of the time when you need to reuse code you can do it by using composition (making your class have a reference to another class, instead of being one). A Car shouldn't extend Motor because a car is not a motor, but it could have a motor and delegate a call to the motor's turnOn() method when the car's drive() method is called.
You can also have polymorphism without inheritance in Java using interfaces.
To make a simple example (but bad :/ ). Lets say you have a Person class.
public Person
{
int age;
string name;
}
Then you have different type of persons that inherit the Person class, eg.
public SoftwareDeveloper extends Person
{
string codingLanguage;
}
Now you can easily create a SoftwareDeveloper and use its attributes like this:
public static void main ()
{
SoftwareDeveloper developer = new SoftwareDeveloper();
System.print.out(developer.name);
}
If you would "import" instead, you would have to create an instance of Person in SoftwareDevelopers constructor and make it public. So your code would be to access the attribute:
public SoftwareDeveloper
{
public Person person;
string codingLanguage;
public SoftwareDeveloper(){
person = new Person();
}
}
public static void main ()
{
SoftwareDeveloper developer = new SoftwareDeveloper();
System.print.out(developer.person.name);
}
I think in small scale your reasoning works fine but the idea of extending is that your class inherits all the methods of the extended class.
But if you start with a simple idea or program and want to expand it massively the use of instantiating all the classes you need becomes much more consuming. On even a simple idea the increase in imports can explode.
Example:
Animal - warm blooded - biped - human
Animal - warm blooded - quadruped - feline - cougar - panther
Now you want to have your panther have all the methods of the 5 classes its built apoun.
So that 5 imports and objects you have to manipulate to get to all the methods you want to access. But if all these are extending each other you just have direct access to the methods. And this is a simple example now imagine a huge accounting program.
So point I trying to make....I think...Is that its much more prevalent and easier to understand the usefulness in extending classes when you look at it in the large scale.
Hope this helps or makes as much sense as it does to me.
Extending a class means that your class is "inheriting" the methods of the standard class; in other words, you are taking an existing class and building your class on top of it. That is how Java manages all objects (i.e. every class that you create actually extends the default Object class). When you import a class, on the other hand, you have access to all its functionality, but you cannot build on top of it as you could with inheritance.
Let's start with importing a class. You import a class in order to use it in another class, if that class is in another package. It's really just a shortcut that's saying when you see a class called X used, what I really mean if com.somepackage.X.
Extending is taking a class and using it as a base for a new class. There's alsorts of reasons to do this (well beyond the scope of an answer here) but the important thing is that you inherit the behaviour of the class you are extending and have the choice of whether or not to override that behaviour or add additional behaviour.
For good example of classes being extended, look at the Collection API in java.util where you can see java.util.AbstractList is extended to ultimately create two different types of list, each with different characteristics - java.util.ArrayList and java.util.LinkedList.
Lets look on an example.
We have class which provide an update function to database and containing a String variable.
public class DBupdate {
public String StrVar = "Hello";
...
public void doUpdate(String expression) {
try {
connect();
runExp(expression);
disconnect();
} catch ...
}
}
If you import it. You will do something like
log(new DBupdate.StrVar);
String myExp = "UPDATE ..."; // SQL
new DBupdate.doUpdate(myExp);
If you extend.
log(StrVar);
String myExp = "UPDATE ..."; // SQL
doUpdate(myExp);
doUpdate() function and StrVar became part of your new class. So all functions and variables (which are public or protected) are part of your new class (inherited).
Example for usefull import (and not extend/inherit) is log4j. It is doing work like writing to console and into a file. But you want just to use it "log" function and no speacial functions it is using for its work.
Example for usefull inherit is java.lang.Thread. If you class became a thread it can be treated as a Thread and will be splitted to run parallel, if you use java.lang.Thread function "start()". (Override run() method to do so some stuff...)
At the very simplest case it can be said that, Import Statement improves readability and reduces the length of the code.
In java we implement dynamic loading, language import statement no class file is loaded at the time of import statement, when ever we are suing a class, at the time of only the corresponding .calss file will be loaded.
Extends-
In Java, when we wish to extend the usefulness of a class, we can create a new class that inherits the attributes and methods of another. We don't need a copy of the original source code (as is the case with many other languages) to extend the usefulness of a library. We simply need a compiled '.class' file, from which we can create a new enhancement. I could not find a better way to explain so just refer this link..(source -http://www.javacoffeebreak.com/java104/java104.html)

Object vs Extend in Java

I may be wrong as I have not got too much experience with Java, but here is a question.
I have a class which contains many methods (basically it is a simple library).
I create an object of this class let's say MyLibrary obj = new MyLibrary(parameters);
The parameters set up any necessary functionality for the library to run correctly.
Then I can call obj.getSomething/obj.setSomething/obj.createSomething etc etc...
In my main class I really need only one this kind of library object.
Now... Would it be more useful for me not to use it as an object, but put it as extends and then create a function inside of the library like a constructor which I would call manually?
EDIT:
The relation between the one class and MyLibrary is very close. Basically, I have many classes which do similar things but have some different higher layer functionality. So I separated method which must be in all those classes.
It seems it is very similar to shape class and triangle, circle, square example. So MyLibrary is similar to shape which contains all the foundation.
What you described strongly resembles a utility class, similar to Java's Collections. The class has only static methods, and a private constructor to prevent instantiations. This is a well-known idiomatic pattern in Java - you can use it to create your own groups of methods providing related functionality.
You should not extend, or even instantiate, utility classes at all. Starting with Java-5, you can statically import them so that you could use their methods without making an explicit reference to their class.
extends is used when you need an inheritance hierarchy. It seems more logical to put your code in two separate classes here, like you have it now.
Also, if your "library class" does multiple unrelated things, it should probably be split into multiple classes - one for each task.
You should really only use extends when you have a is-a relationship. So, you can think, is my main class a MyLibrary or should my class have a MyLibrary.
From your described problem, it sounds like having MyLibrary is the way to go.
With the limited detail that you have provided, you might want to consider the Singleton pattern.
extends should only be used when one object needs to inherit the characteristics and functionality of another one because they are very closely related. For example, if you have a Shape class, then you would extend Shape to create Circle, Square, and Triangle. Before you use extends you should learn more about inheritence and when you should and should not use it.
I would make this a static class to use. Similiar to javas MATH class API for math class. You can just use the methods of the class without making an object of it.
Well If your class if performing utility functions then you should mark all methods as static and use operations like
MyLibrary.doSomething();
MyLibrary.createSomething();
MyLibrary.getSomething();
But this wont allow you to keep some data members in the class and if you keep them they will be static as well.
I don't think so that extends suits your case.
Also if you want to keep only an object then you should look at Singleton A class for which only one instance can be created.
Assuming you are just using MyLibrary and may not alter it, you should use a wrapper that makes the whole thing a Singleton, as already proposed by Code-Guru.
public class MyLibraryWrapper {
private static MyLibrary instance = null;
private MyLibraryWrapper() {}
public static MyLibrary getInstance() {
if (instance == null)
instance = new MyLibrary();
return instance;
So in your code you would use
MyLibraryWrapper.getInstance().getSomething();
Best way to create singleton in java 1.5 or above is to use ENUM.
public enum Test {
INSTANCE;
}
INSTANCE is the only instance of Test class.

How to make an abstract class non-abstract with Javassist?

In a small framework I am building, I would like to change certain abstract classes to non-abstract using Javassist.
I already transformed all the abstract methods in non-abstract ones implementing the dynamically generated code I need. But I have not yet succeed in making the class non-abstract.
What I have tried is something similar to this:
Let's say c is the class I would like to make non abstract. So I have written:
public void instrument(Class c) {
...//some ignored exception management
CtClass ctClass = ClassPool.getDefault().get(c.getName());
ctClass.setModifiers(c.getModifiers() & ~Modifier.ABSTRACT);
return ctClass.toClass().newInstance();
}
However, the call to:
ctClass.toClass();
is raising the following CannotCompileException:
"attempted duplicate class definition for name: <class_name>."
This is because the class has already been loaded, since I am invoking its getName method. It seems to me this is the only mechanism I have to get a CtClass from an existing class, but please someone tell me if that is not correct. Hardcoding the name of the class instead of calling its getName method is far from been an ideal solution, given that I need to apply this routine to many classes.
Any workaround to do this ?. If it is not possible at all I will dynamically generate a new class that extends the abstract class, implements its constructors, and the abstract method of all its ancestors (a bit more complicated, so I would be very happy if I succeed just making the original class non-abstrat instead).
Have you tried creating an extending Class rather than changing the existing Class? So create a Class, implement all the methods and use setSuperClass() to make it extend your abstract Class.
The problem, as you described it, is that you have already loaded the Class you are attempting to redefine. It is illegal to attempt to redefine a class that is already loaded by a classloader.
One option might be to do a bit of classloader trickery: create a new classloader that doesn't have your existing classes loaded (parent is the system classloader) and have Javassist load through that (use aCtClass.toClass() method that takes a ClassLoader argument).
As it has suggested, there might be a better way to achieve your goal, and creating subclasses might be a better design. Is using interfaces instead of abstract classes an option? If so, dynamic proxies is an option as well, their advantage being you don't need any 3rd party libraries to create them.

In Java, is there a way load class implementing interface that does not exist?

I've seen Java doing a lot of magic, but is it possible to do this:
At runtime, using (for example) ClassLoader.defineClass, load class A that implements interface B. The interface B does not actually exist in class path. Java will throw an exception (ClassNotFoundException IIRC) and the class won't be loaded. All other parts of class A are OK, and I know for a fact that no other part of program will be using interface B. So, what I want to do is to make the interpreter ignore the missing interface definition and load a class that is completely the same as A except that is does not implement the interface B.
Is this possible? It of course could be achieved by catching the exception and manually editing the binary data of class A, then loading it again. Or by creating a dummy empty interface named B at runtime by manually constructing the B.class file and then loading it. But it seems a bit messy, so my question is, does Java provide any convenient ways to do this?
If not, I guess, I'll try implementing one of those two methods, but I still want to hear an opinion.
I'm doing this to provide a convenient way for two different code bases to interact with each other if they both are loaded, and to just work fine if only one of them is.
I'm not aware of any non-messy solutions to this that work similarly to what you're describing. It all boils down to a custom ClassLoader. Custom ClassLoaders are kind-of hard to begin with and if they have very specific semantics like this, then they become very ugly.
Not to mention the types of problems that you'll run into if your code suddenly doesn't run inside that ClassLoader.
I think the sane solution to this is to produce a mylibrary.jar and a mylibrary-noB.jar (or even more explicit: mylibrary-withB.jar and mylibrary-noB.jar) and let the users just select which one they want.
It is fairly common to include a second jar with the additional interfaces. The second jar can be included if needed and dropped if not. If its added to the end of the class path, this will happen implicitly.
Ultimately, the code in the classpath entry where interface B is defined has to use the same class as the code in the classpath entry where class A is defined. So defining a dummy interface will not work.
In Java you can dynamically implement an interface with a Proxy:
http://download.oracle.com/javase/6/docs/api/java/lang/reflect/Proxy.html
So at a later point in time, when your interface A is available, you can get it by reflection and create Proxy that implements its methods. The following example shows this with the java.lang.Runnable interface as interface A:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) throws Exception {
Class interfaceClass = Class.forName("java.lang.Runnable");
Object implementingRunnable = Proxy.newProxyInstance(
ProxyTest.class.getClassLoader(),
new Class[] {interfaceClass},
new MyInvocationHandler()
);
((Runnable)implementingRunnable).run();
}
static class MyInvocationHandler implements InvocationHandler {
public Object invoke(Object proxy, Method m, Object[] args)
throws Throwable {
System.out.println("called " + m);
return null;
}
}
}
Of course at some point you have to actually cast the proxy to the interface A. You would have to do this in a class that is defined in the same class path entry as the interface.

Categories