Can a class add a method to itself at runtime (like from a static block), so that if someone is performing reflection on this class, they'll see the new method, even though it wasn't defined at compile time?
Background:
A framework I'm using expects Action classes to be defined that have a doAction(...) method, by convention. The framework inspects these classes at runtime to see what type of parameters are available in their doAction() method. For example: doAction(String a, Integer b)
I'd like each class to be able to programatically generate its doAction() method with various parameters, just-in-time when it is inspected. The body of the method can be empty.
It's not simple. Once a class is loaded by a classloader, there is no way to change the methods of loaded classes. When a class is requested, a classloader will load it and link it. And there is no way (with Java) to change the linked code or to add/remove methods.
The only trick that comes to my mind is playing with classloaders. If we delete a custom classloader, then the classes loaded by that classloader should be deleted or inaccessible too. The idea that comes to my mind is to
implement one custom classloader
load the dynamic class with that custom classloader
if we have an updated version of this class,
remove the custom classloader and
load the new version of this class with a new instance of the custom classloader
I leave that as food for thought, can't prove, if this leads to a solution or if we have pitfalls.
As a simple answer to the question: No, we can't change a loaded class like we can change the content of fields with reflection. (we can't add or remove fields too).
Andres_D is right, we can very well do so using custom class loading, here is a detailed guide on how to do this: http://www.javaworld.com/javaworld/jw-06-2006/jw-0612-dynamic.html?page=1
The article explains how to write dynamic Java code. It discusses runtime source code compilation, class reloading, and the use of the Proxy design pattern to make modifications to a dynamic class transparent to its caller.
In fact researcher in Austria have written a JVM that even allows reloading classes with different type hierarchies. They have achieved this by using existing thread save points to generate a complete 'side universe' of an object and all it's related references and referenced content and then once fully reshuffled with all required changes simply swap in all changed classes. [1] Here a link to their project http://ssw.jku.at/dcevm/ the oracle sponsorship certainly makes for interesting speculations on future plans.
Less intrusive changes to method bodies and fields are already possible in the standard java VM using the Hot Swap capabilities of the JPDA as introduced in Java 1.4:
docs.oracle.com/javase/1.4.2/docs/guide/jpda/enhancements.html#hotswap
I'm not sure whether it was the first one but this Sun employee's paper from 2001 appears to be one of the early proposals mentioning the capabilities of the HotSpot to Hot Swap. [2]
REFERENCE
[1] T. Würthinger, C. Wimmer, and L. Stadler, “Dynamic Code Evolution for Java,” presented at the 8th International Conference on the Principles and Practice of Programming in Java, Vienna, 2010.
[2] M. Dmitriev, “Towards flexible and safe technology for runtime evolution of java language applications,” in OOPSLA Workshop on Engineering Complex Object-Oriented Systems for Evolution, 2001.
I've never tried anything quite like that myself, but you should have a look at ASM, cglib, and Javassist.
No, that is not (easily) possible in Java.
It sounds like you are trying to use Java as if it is a dynamic programming language. For example, Ruby has open classes: you can add and remove methods from Ruby classes at runtime. In Ruby, you can also have a "method missing" method in your class, that will be called when you try to call a method that doesn't exist in the class. Such a thing also doesn't exist in Java.
There is a version of Ruby that runs on the JVM, JRuby, and it has to do very difficult tricks to make open classes work on the JVM.
You can have a doAction method which does whatever you would like the generated method to do. Is there a reason it needs to be generated or can it be dynamic?
It looks like there is no way to add method dynamically. But you can prepare an class with a list of Methods or an hash like:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashMap;
public class GenericClass {
private HashMap<String, Method> methodMap = new HashMap<String, Method>();
public Object call(String methodName,Object ...args)
throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method method = methodMap.get(methodName);
return method.invoke(null, args);
}
public void add(String name,Method method){
if(Modifier.isStatic(method.getModifiers()))
methodMap.put(name, method);
}
public static void main(String[] args) {
try {
GenericClass task = new GenericClass();
task.add("Name",Object.class.getMethod("Name", new Class<?>[0]));
} catch (NoSuchMethodException | SecurityException e) {
e.printStackTrace();
}
}
}
Than, using reflections you can set or unset the attribute.
I believe you need some byte code altering tool/framework, such as asm, cglib or javassist.
You can achieve this via aspects/weaving like it's done Spring, but I believe you still need to have the method defined first.
Proxy may help. But have to instantiate a Proxy every time you want to add or remove a method.
What I suggest should work for your situation:
1. You have an existing class MyClass with n methods
2. You want to include (n+1) th method which is not in the class while compiling in another .java source file
My way to solve it is Inheritance. Create a new .java source file for a Class MyClassPlusOne extending the first class MyClass. Compile this class and use the object. How can I compile and deploy a java class at runtime?
class MyClassPlusOne extends MyClass
{
void doAction(String a, Integer b)
{
int myNPlus1 = a+b;
//add whatever you want before compiling this code
}
}
I'm not sure that is possible. However, you could use AspectJ, ASM, etc. and weave these methods into the appropriate classes.
The other alternative is to use composition to wrap the target class and provide the doAction method. You would end up delegating to the target class in this case.
This is a rather old question, but I still found myself looking at it today so, just in case, I'll add my two cents.
If you are using Java 8+, you can define "default" implementations of an interface method, so you can just define the interface with all the extra methods with empty default implementations, and add the implements clause in the desired classes. This approach, in some cases, may be the easiest one.
If you don't have control over the definition of the classes, or you need compatibility with older Java versions, you can still define an interface containing all the required extra methods; but in this case, implement a "Decorator" class with a method that receives the object to "decorate" as parameter, and returns a DynamicProxy instance, wrapping the passed object with this interface.
If you are using Spring, the decorator can be added to the context as a #Component, so you can inject it wherever you need to use it. If any of the objects you need to inject are Spring Beans, you could implement a FactoryBean that uses the decorator to return the instances, so you can just forget about calling the decorator explicitly for them.
Related
Hello StackOverflow Community,
I recently discovered Java Instrumentation and what great things you can do with it, so I decided to write a small library for me that simplifies some of these things.
I have the following method (simplified):
public static void editClass(Class<*> clazz) {
...
}
It adds a transformer via Instrumentation that transforms the bytecode of loaded classes with the name of clazz.getName().
So in my premain method, I can say
editClass(Foo.class);
My problem is, by specifying the class via a reference to it (.class), this class gets loaded before the transformer is added, so after that, I have to retransform the class which prevents me from adding/removing methods and so on.
So, is there a way to not load the class when using this class reference? Or an other way to implement this? I know that I could just pass the class name as an argument, but I would really like to make this whole library type-safe and make refactoring easier.
Thanks in advance!
If you want to call the editClass method from premain only and we assume that the Java Agent itself does not use the class otherwise, so that the class literal inside the editClass call would be the only trigger, you can do the following:
provide both methods, editClass(Class<?> clazz) and editClass(String qualifiedName)
write the premain method (or agent classes in general) using editClass(Class<?>) and enjoy compile-time safety regarding the existence of the classes referenced via literals
perform a static code transformation of the agent classes, replacing all calls of editClass(Class<?>) with editClass(String)
This shouldn’t be too hard, as you only have to replace all sequences of ldc packagename/Foo.class, invokestatic (Ljava/lang/Class;)V with ldc "packagename.Foo", invokestatic (Ljava/lang/String;)V.
It may become even easier when the method editClass(String qualifiedName) can handle the internal class names (using slashes instead of dots).
Since you said you “recently discovered Java Instrumentation”, this might be a good exercise in class file transformations
Use the transformed Agent classes which have no references to the classes to transform anymore, to perform the load time transformations
I have a package called "func_commands" that has a bunch of classes that each have the functions "cmd" and "man". I want to be able to load them without specifically stating their names, since I'm using an interface right now, and I want my program to be modular, so that classes can be added or removed by the user, and loaded/unloaded accordingly on the program's next restart.
I've heard that Reflections can do this, but I can't find a working tutorial on how to do it, and I'm an idiot when it comes to documentation. Does anyone know how to do this?
I've been able to use it to find the classes that extend my interface, but I can't figure out how to make it load said classes.
Reflections reflections = new Reflections("func_commands"); //init reflections and point it to the package (I think thats what the string does, I forgot)
Set<Class<? extends Command>> allClasses =
reflections.getSubTypesOf(Command.class); //get the classes from it that extend Commnd
How I'm currently loading the classes:
for(Command command:CommandArray.commands) {
command.cmd(e);
command.man(e);
};
//meanwhile in CommandArray...
public static Command[] commands = {
new ClassA(),
new ClassB(),
new ClassC()
};
I want to be able to load them without specifically stating their names, since I'm using an interface right now, and I want my program to be modular, so that classes can be added or removed by the user, and loaded/unloaded accordingly on the program's next restart.
What you probably mean by this is that you want to be able to instantiate classes and only access their public API via interfaces. This is very good practice.
There are multiple ways to achieve this and you are quite right in noting that reflection is one of them. However, this is quite costly and it involves having to cast the instantiated class. This removes any compile time checks from your program.
Another common practice is to provide a static factory class with methods to instantiate objects. A very good example of this is present in the JDK. EnumSet does not have any constructors and only has a static factory. Under the hood, two different classes, namely, RegularEnumSet and JumboEnumSet are instantiated based on the size of the underlying Enum. You use a similar approach an define classes within the static factory and swap out implementations for different needs.
More information about static factories can be found at: https://dzone.com/articles/constructors-or-static-factory-methods
EDITED: Added a link for reflective class instantiation as well: http://tutorials.jenkov.com/java-reflection/dynamic-class-loading-reloading.html
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'm writing (well, completing) an "extension" of Java which will help role programming.
I translate my code to Java code with javacc. My compilers add to every declared class some code. Here's an example to be clearer:
MyClass extends String implements ObjectWithRoles { //implements... is added
/*Added by me */
public setRole(...){...}
public ...
/*Ends of stuff added*/
...//myClass stuff
}
It adds Implements.. and the necessary methods to EVERY SINGLE CLASS you declare. Quite rough, isnt'it?
It will be better if I write my methods in one class and all class extends that.. but.. if class already extends another class (just like the example)?
I don't want to create a sort of wrapper that manage roles because i don't want that the programmer has to know much more than Java, few new reserved words and their use.
My idea was to extends java.lang.Object.. but you can't. (right?)
Other ideas?
I'm new here, but I follow this site so thank you for reading and all the answers you give! (I apologize for english, I'm italian)
If it is only like a "research" project in which you want to explore how such extension would work, you could provide your own implementation of the Object class. Simply copy the existing object implementation, add your setRole method etc, and give -Xbootclasspath:.:/usr/lib/jvm/java-6-sun/jre/lib/rt.jar as parameter to the java command. (I will look for api-classes in . before looking in the real rt.jar.)
You should consider using composition rather than inheritence to solve this problem; that way you can provide the functionality you need without using up your "one-shot" at inheritence.
For example, the JDK provides a class PropertyChangeSupport, which can be used to manage PropertyChangeListeners and the firing of PropertyChangeEvents. In situations where you wish to write a class that fires PropertyChangeEvents you could embed a PropertyChangeSupport instance variable and delegate all method calls to that. This avoids the need for inheritence and means you can supplement an existing class hierarchy with new functionality.
public class MyClass extends MySuperClass {
private final PropertyChangeSupport support;
public MyClass() {
this.support = new PropertyChangeSupport(this);
}
public void addPropertyChangeListener(PropertyChangeListener l) {
support.addPropertyChangeListener(l);
}
protected void firePropertyChangeEvent() {
PropertyChangeEvent evt = new ...
support.firePropertyChangeEvent(evt);
}
}
you can extend Object - every class extends it.
you seem to need something like multiple inheritance - there isn't such a thing in Java
if you want to add functionality, use object composition. I.e.,
YourClass extends Whatever implements ObjectWithRoles {
private RoleHandler roleHandler;
public RoleHandler getRoleHandler() {..} // defined by the interface
}
And then all of the methods are placed in the RoleHandler
If you're talking about adding a role to all your objects I would also consider an annotation-based solution. You'd annotate your classes with something like #Role("User"). In another class you can extract that role value and use it.
I think it would need an annotation with runtime retention and you can check, run-time, whether the annotation is present using reflection and get that annotation using getAnnotation. I feel that this would be a lot cleaner than extending all your classes automatically.
I believe there are some frameworks which use exactly such a solution, so there should be example code somewhere.
If you are doing what you are doing, then inheritance is probably not the correct idiom. You may want to consider the decorator pattern, whereby you construct a class that takes as its parameter some other class with less functionality, and adds some additional functionality to it, delegating to the existing class for functionality that already exists. If the implementation is common to many of your decorators, you may want to consider putting that functionality in class that can be shared and to which you can delegate for all your decorators. Depending on what you need, double-dispatch or reflection may be appropriate in order to make similar but not quite the same decorators for a large variety of classes.
Also, as has been pointed out in the comments, String is declared "final" and, therefore, cannot be extended. So, you should really consider a solution whereby you delegate/decorate objects. For example, you might have some object that wraps a string and provides access to the string via getString() or toString(), but then adds the additional functionality on top of the String class.
If you just want to associate some objects with additional attributes, use a Map (e.g. HashMap).
What you really want to do would be monkey patching, i.e. changing the behaviour of existing classes without modifying their code.
Unfortunately, Java does not support this, nor things like mixins that might be used alternatively. So unless you're willing to switch to a more dynamic language like Groovy, you'll have to live with less elegant solutions like composition.
Is there a way to create Java classes # at runtime
(classes methods n variables), with using Java reflection API
You can't do that using reflection. You need a bytecode manipulation library, like Jakarta BCEL.
The standard Java API provides a set of static methods, that allows you to dynamically create a class that implements one (or many) interfaces.
Those methods are part of the class java.lang.reflect.Proxy.
What do you require this for?
Interpreting the question in a very loose manor I can think of four likely options.
If you have a class that you add something too you might find that Aspect-oriented programming is what you are really after.
If you have an interface that you want to dynamically implement (as posted by barjak) what you want is java.lang.reflect.Proxy. This does not let create "code" at runtime but rather allows you link existing code to to a interface.
Finally (at three I know) you have actually building random classes at runtime. This you will need something like cglib or BCEL. While there are cases when this is required it is IMO rare.
One other option is that you don't really need runtime but rather build time. In this case you might be able to use annotations and apt (Java 5) / Processor (Java 6).
Sure there is. You need a java.lang.Class instance initially, for the target class you wish to create. Depending on your structure, this might either be passed in by a caller (if they're supplying the concrete class they want created), or you can statically access the class variable (e.g. MyFooImpl.class).
The simplest way is to call Class.newInstance(). This invokes the default, no-arg constructor (assuming there is one for the class; if not it throws an exception).
If you need to invoke a particular constructor with some argument, you need to call Class.getConstructor() to get a Constructor instance, which you can then call newInstance on.
In all cases you'll need to deal with reflection exceptions that you wouldn't get if invoking the constructor directly.
Big edit: I assume your question was about creating instances of a class via reflection. However I'm beginning to think that you're asking about defining new classes through at runtime. If so, then reflection won't help you here - you'd need to invoke a compiler programatically, which I believe can be done but I'm not 100% on the details. I think you'd also have to go through some hoops to get the ClassLoader to pick up your new class too.
You can create the source code string and compile it to an class file using Janino.
As people have already mentioned, there's no way of creating new classes at runtime using reflection. One library that I know is used by different mocking libraries and the likes is cglib.
you can use javassist. here is sudo code
javassist.ClassPool pool = new ClassPool(true);
CtClass bclass = pool.makeClass("brandnewclass);
bclass.addConstructor(CtNewConstructor.defaultConstructor(bclass));
CtClass[] fieldclasses = new CtClass[fields.length];
CtClass serClass = pool.get(Serializable.class.getName());
bclass.addInterface(serClass);
Class clazz = pool.loadClass("className");
obj = clazz.newInstance();
Use reflection to extract values from an existing class and assign values to new class.
hope this helps.
Gopi