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.
Related
I tried to make a reflection to my code but I came across a problem because I had to extend class with reflected class, it was something like this:
I have this classes reflected:
"some.package.a.SomeClass"
"some.package.b.SomeClass"
and now I need to extend another class with one of them
public MyClass extends SomeClass {
#Override
public Object...
is there any way that I can achieve this?
Using off-the-shelf Java, you cannot extend a class given to you only through reflection. There are third-party libraries that let you overcome this restriction (see this Q&A).
Extending a class requires defining a new class, and compiling it into bytecode. Reflection happens at run-time. It is inherently a read-only API, so you cannot emit new classes with it.
Implementing an interface gives you another option of using a Proxy, but you cannot specify your own base class.
I am now studying a java and I'm at the part of Abstract.
I read sorta strange part to me that there is an abstract class
which does not include any abstarct method.
Why do they use this kind of class?
To prevent instantiation of that class and use it only as a base class. Child classes can use the general methods defined in the abstract class.
For example it doesn't make sense to create an instance of AbstractVehicle. But All vehicles can reuse a common registerMileage(int) method.
A common reason to do this is to have the abstract class provide exploding implementations of the abstract methods as a convenience to subclasses who don't have to implement all the abstract methods, just those they want to - the remaining ones will still explode but it won't matter if those execution paths aren't exercised.
HttpServlet is an example of this pattern in action. It has default implementations for all methods that handle the different request types, but they all throw an exception. The subclass must override these if they want to do something meaningful. It's OK to leave some handler methods not overridden as long as they are never called.
Yes, we can have abstract class without any abstract method.
Best example of abstract class without any abstract method is HttpServlet
If this class extends another abstract class and don't have implementation of inherited abstract methods.
This class contains some common logic for all its inheritors, but itself does not represent usable entity (in terms of particular application)
These type of classes are used for a implement a general logic which can be implemented by other classes. Making it abstract prevents from instantiating it. But other classes can inherit the class and its methods.
Say you have a set of related classes, but no related (shared) code, yet. If we make all of these classes extend a base class with no abstract methods, that then if we wan't all of these classes to have an identical method/feature in the future, that can be done in one shot by putting it in the base class. So code is not repeated and it reflects in all child classes by including it in just one place.
Another example for having such class is when you implement creation helpers. These classes are used to ease the client in the creation of objects, which are related in topic but decoupled depending on the need. By nature, the methods of this creator classes are all static and they can be seen as utility classes as well.Obviously, instatntation of this classes is futile and hence the abstractkeyword.
To mention a recent example I met was the Sftpclass from org.springframework.integration.dsl.sftp which is basically an easy way to require objects (e.g: adapters, gateways) from the sftp api.
I develop a abstract class to prevent instantiation of that class and use it only as a base class. because, These type of classes are used for a implement a general logic which can be implemented by other classes. Sometimes, I have a default implementation for every method in abstract class. In the manner, it doesn't force the sub-class to override all of method, but also it implement everyone that is need.It means implicitly you have to override at least one method to make scene using this abstract class.
I can't think of any good reason to use it. It could be used as "marker" but an interface would be a better choice.
Abstract class without abstract method means you can create object of that abstract class.
See my Example.
abstract class Example{
void display(){
System.out.println("Hi I am Abstract Class.");
}
}
class ExampleDemo
{
public static void main(String[] args)
{
Example ob = new Example(){};
ob.display();
}
}
If you write one abstract method inside abstract class then it will not compile.
Which means if you create abstract class without abstract method then you can create Object of that Abstract Class.
Assume I obtained a Class object by loading a class dynamically using Class.forName("Foo"). Foo is abstract in this case, so I cannot call newInstance() on it. (How) is it possible to declare a concrete subclass of Foo?
You declare it as not abstract e.g.
class Bar extends Foo {
// implement methods are required.
}
In short, just because you loaded the class dynamically doesn't mean the rules change ;)
Foo is not available at compile-time
If you don't have Foo available at compile time, you still need to have a sub-class of this class which is concrete to create it. To do this you have two options.
find a concrete class and create that. You can use the Reflections library to find such a class.
generate code and compile it using the Compiler API, or BeanShell.
generate byte code for the subclass using ObjectWeb's ASM.
I suspect the first option is what you need because unless there is a subclass provided for you, you still need to generate the code for the abstract methods.
Here's something that's got me a bit stumped but intrigued all the same. In my Android game I have various Levels that extend the superclass Level. What I am trying to do is build a levelDirectory (based on the Singleton DP) that essentially is an object that has a HashMap object within it that stores all the Level subclasses. Here is my question:
We're all familiar with the enhanced for loop, but how can I write something that would be the equivalent of
for(Level l : An Array Of Every Level Subclass In My Project that is an Extension of the Level Superclass){
HashMap.put(l.name, l);
}
I am trying to build a system that can dynamically update itself when I add more and more level subclasses. I know having a method in Level that submitted itself to the static Directory and was called in the Level's constructor is an option, But I'm just wondering whether there is a way of doing what I said above in that enhanced for loop?
Many thanks
The question itself is wrong. You cannot loop over List ("Every Level Subclass In My Project") and get instances of Level. l should be Class.
From the context, I think you meant "every instance of every Level subclass". No, it is not possible - a virtual machine is not and should not be a database. You cannot just query for objects, you have to manage references in your code (but that you already knew that - your constructor solution will work).
Option 1:
Lately I had to solve a similar problem within JavaSE. I'm using the Google Reflections Library for that:
http://code.google.com/p/reflections/
However I'm not sure if it can run with Android. I think it's worth to give it a try, since it's quite easy to use. In your case you would do something like:
Reflections reflections = new Reflections("my.project.prefix");
Set<Class<? extends Level>> subTypes = reflections.getSubTypesOf(Level.class);
That would give you a Set (subTypes) to iterate on and put it in the HashMap.
Option 2:
You could maybe use custom annotations to annotate your Level classes, for example:
#Level public class MyCustomLevel {}
Then use a custom annotation processor which implements AbstractProcessor to process the annotation at compile time. Implement the process method to find all classes annotated with your #Level annotation. Now you can write the full names of the found classes to a property file in your META-INF dir. From your application you can read this property file and instantiate the classes using reflection.
If you're trying to dynamically fetch the list of all classes that extend Level at runtime, that's not really possible, I'm afraid. Have a look at this thread: How do you find all subclasses of a given class in Java?
I think you might want to make the level an interface and then check if it's an interface.
In its most common form, an interface is a group of related methods with empty bodies. A bicycle's behavior, if specified as an interface, might appear as follows:
interface Bicycle {
void changeCadence(int newValue); // wheel revolutions per minute
void changeGear(int newValue);
void speedUp(int increment);
void applyBrakes(int decrement);
}
To implement this interface, the name of your class would change (to a particular brand of bicycle, for example, such as ACMEBicycle), and you'd use the implements keyword in the class declaration:
class ACMEBicycle implements Bicycle {
// remainder of this class implemented as before
}
Implementing an interface allows a class to become more formal about the behavior it promises to provide. Interfaces form a contract between the class and the outside world, and this contract is enforced at build time by the compiler. If your class claims to implement an interface, all methods defined by that interface must appear in its source code before the class will successfully compile.
I think standard way in the "spirit" of java is the service provider pattern.
Add a declaration file in the META-INF/services of the "plugin" jar and use java.util.ServiceLoader (http://developer.android.com/reference/java/util/ServiceLoader.html) to enumerate your providers.
Don't know much about Android but sounds like Reflection might help here, so what do you know about reflection in Java?
EDIT
Didn't know you had to limit yourself to loaded levels. That being the case you would want to do your tracking on every instance as it is created pretty much like you proposed in your question.
My idea involved parsing all the directories of a project looking for subclasses - it could be done once at the start of program execution but it would list levels that may never get instantiated...
I have got a question in my finished interview that I wouldn't get the right answer.
Assume that we have 3 class, Base, Derivate1 and Derivate 2,
Their relations are shown as follow
public class Base {...}
public class Derivate1 extends Base {...}
public class Derivate2 extends Derivate1 {...}
Then we found out that Derivate1 and Derivate2 are unnecessary for our program, but their method implementations are useful. So, how can we get rid of Derivate1 and Derivate2 but still keep their methods? In this case, we are expecting that user cannot create new instance of Derivate1 and Derivate2, but they still can use the method implementations in Derivate1 and Derivate2. Of course, we are allow to change the code in class Base.
What do you think about that and can you tell what they're actually asking?
Thanks a lot.
PS.
There are abit of hints from my interviewer when I have discuss the them.
The derivate classes are from the third party. They are badly design, so we don't want our client to use them, which means user should not allow to create instance from the derivate classes.
The derviate class contains overriding methods that are useful for the Base class, we can create method with different name in the Base to implement those useful behavious in derviated classes.
And thank you for all those interesting answers...
Simple refactoring:
Copy all code from Derivate1 and Derivate2 into Base.
Delete Derivate1 and Derivate2 classes
Ensure no missing references (if you are already holding pointers to Derivate objects as Base, you should be good)
Compile
?????
Profit!
Even if you have more subclasses such as Derivate3 and Derivate4 down the hierarchy, there should be no problem in having them extend Base.
(non-static) Methods from Derivate1 and Derivate2 are only usable if we create Derivate1 and Derivate2 instances. Creating a Base instance (like with new Base()) will not give access to (non-static) method declared in subclasses.
So to keep the methods, one could add (refactor) them to the Base class. If we just don't want public constructors for the sub classes but keep the object graph as it is, on could use a Factory pattern to have them created on demand. But even in this case one had to cast the object returned by the factory to either Derivate1 or Derivate2 to use the (non-static) methods.
I guess I know what they wanted to hear, the common recommendation 'favour composition over inheritance'. So instead of saying Derivate1 is-a Base you do a Derivate1 has-a Base:
public class Derivate1 {
private Base base;
// ... more
}
public class Derivate2 {
private Derivate1 derivate1;
// ... more
}
No more inheritance and both Derivates can still use methods of their former super classes.
From the hints they gave you, I think the answer was adapter pattern, which sometimes is used for legacy code.
You can have a look at it here:
http://en.wikipedia.org/wiki/Adapter_pattern
We could do two things:
we could pull up some methods of Derivate1 and Derivate2 to Base, when this makes sense (as noted above)
we could make both Derivate1 and Derivate2 abstract: this prevents instantiation, but not inheritance
I think they meant extracting derivate to interface
If it makes sense, you can directly include these methods in your base class. But it depends on the meanings of this class, of course. If it is possible, you could ty to use static methods in a utility class. By the way, your developers will have to change their use of the API in both cases.
The first obvious thing is that each of the classes in the hierarchy is concrete - in general, either a type should be abstract, or a leaf type. Secondly, there isn't quite enough information as to what these methods are - if they override something in Base or Derived1, you can't move them into Base; if they are utility methods which would apply to any Base then they might be moved into Base, if they are independent of Base then then they could be moved into a helper class or a strategy.
But I would question the idea that a class is not required but its behaviour is - it sort of implies that the questioner is looking at designing an ontology rather than an object oriented program - the only reason a class exists is to provide behaviour, and coherently encapsulating a useful behaviour is a sufficient and necessary condition for a class to exist.
Since you do not own the derivate classes you cannot delete them. The base class is all yours so you have control. The client is yours so you have control there. So the best way would be to have an all new class that is exposed to the client. This class essentially creates the derivate instances (note: your client isn't dealing with it anymore) and use their useful functions.