Using Reflections to dynamically load all classes in a package - java

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

Related

Is there a way to create Model here without duplicating the code?

I need to use two similar libraries one for one specific session of MVC. Means, they (their methods) won't be used simultaneously (I'll use If...Else around that specific session to choose methods of only one library at a time). The problem is:
For both libraries to work, its mandatory for my Entities (Model) to extend their classes (wished I was with C++).
They don't provide any Interface. So, I can't do multi-inheritance.
The only choice I have left: Create two different Models each for both libraries & use specific Model based on session (or being used libraries).
But, it'll duplicate the codes in Models. At this time there's no need to sync data between them due to use of persistent storage between MVC sessions. But still, duplicate code is a big headache to manage. Is there a way to avoid this?
You could create Adapters for each specific libraray. This would keep your own code clean from the other libraries.
Also you should consider using the Strategy Pattern for switching between both libraries. This becomes handy when the code becomes more complex and you can mock the libraries in tests.
You can't get around including both libraries if that's what you're asking. You could have a few options just depends on how you want things to work.
From what I understand, you could create two classes, each extending a different library, these classes implement an Interface, override any methods you need to.
Pseudo code:
private class Lib1Adapter extends Lib1 implements LibAdapter {
// wrapper methods call lib1 methods
}
private class Lib2Adapter extends Lib2 implements LibAdapter {
// wrapper methods call lib2 methods
}
public interface LibAdapter {
// method signatures for publicly accessible methods
}
public class YourModel {
public LibAdapter la = < boolean statement > ? new Lib1Adapter() : new Lib2Adapter();
}

Can a Java class add a method to itself at runtime?

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.

How to hide the internal structure of a Java API to the rest of the world

i am developing a Java Api to do things (secret, uhhhh ;).
Is there a way to hide classes, and the internal structure of my API?
What i found until now:
Using inner classes (ugly way, i do not want to put all in on class file)
All classes in one package so that i can use the "package"-visibilty (also ugly, i need more packages)
Example:
---
package net.my.app;
//this is the Public Access
class MyPublicClass{
public void somePublicFunction(){
//access to not visibil classes
}
}
---
package net.my.app.notvisible:
//this is what i want to hide
class MyNOTPublicClass{
...
}
---
Any ideas?
Thank you!
There are two solutions to your question that don't involve keeping all classes in the same package.
The first is to use the Friend Accessor/Friend Package pattern described in (Practical API Design, Tulach 2008).
The second is to use OSGi.
Related Questions: 1, 2, 3, and 4.
Use interfaces to define what your
app does
Create a main entry point to accesses services, returning interfaces only
I wouldn't bother about actually hiding the implementation classes. You can never really hide them in Java, and those who are technically interested might just start your app with a debugger. Just provide no public constructors, for example
Regarding this comment:
Sean, would you elaborate a little
more on your answer? ...
One way to implement my second bullet point I mean using a Service Lookup class, e.g.
public class Lookup {
private static final Foo foo = new FooImpl();
public static Foo getFoo() {
return foo;
}
}
Foo is an interface, FooImpl an implementation class (which can be package private if you want to enforce that it can't be instantiated by clients)
What do you mean by 'hide'?
You can use the final modifier to stop people from extending methods and classes you don't want them to extend. If you want to stop people from decompiling your code, you can use code obfuscation and if you want to take it even further, you can use anonymous inner classes that implement interfaces.
You can try and make only your interfaces public. Have a look at the Factory Pattern.
Alternatively, you can implement you're application in OSGI.
Neither of these methods would allow you to hide the implementation completely to someone who really wanted to see it. Someone could still use a decompiler to examine you .class files, or even examine the code in memory.
If you really need to protect your implementation in this way, then a good approach would be to only allow access to your application as a remote service and host it on a secure machine.

Hiding classes in a jar file

Is it really impossible to hide some classes in a jar file?
I wanted not to allow direct instantiation of the classes to keep it more flexible. Only the factory (or a facade) should be visible of this jar.
Is there any other way than solve this problem than creating two projects?
(Two projects: the first one contains the classes (implementation) and the other one references to the first one and contains the factory; later only the second one will be referenced)
I'm understanding you're not looking to hide the actual classes, just prevent their construction outside a factory class. This I think can be quite easily achieved by using package private (default) visibility in the class constructors. The only limitation is that you'll need to have the classes and the factory in the same package so in a medium to large codebase things may get unnecessarily complex.
If I understand your question correctly, you would like to make sure that users of your library are forced to use your factory to instantiate their objects rather than using the constructors themselves.
As I see it there are two possibilities, one of which is silly but usable in few, specific cases, and the other one is the most practical and probably most commonly used way of doing it.
You could make all your classes into
private inner classes of the
factory. This would work if you had
one factory per class, but is hardly
workable if you have a lot of
different classes being managed
through one factory.
You could use the protected access modifier to
restrict access to your class
constructors. This is common
practice when using the factory
pattern.
I think you will have either compiler failure or warning if your public factory method try to return something which is "hidden".
No, you can not hide a public class without reimplementing your own ClassLoader or using OSGi or anything similar.
What you can do is to separate interface api from the implementation, e.g. have one project which contains only the interfaces and another porject which contains the implmentations. However, you still cannot hide the implementation classes.
Obfuscation can help you somehow.
With standard classloaders and plain old jar files, this is not possible. OSGi has this concept of making visible only some packages to another bundle(i.e. separation of public api and internal implementation).
If you are using eclipse, you may enforce such rules with this
If I understand you correctly when you say "not to allow direct instantiation of the classes to keep it more flexible", a properly executed facade pattern will handle this.
Restrict the constructors of all the classes you want to hide to package scope. Open the facade class to public scope.
http://mindprod.com/jgloss/packagescope.html
"If you have a variable or method in
your class that you don’t want clients
of your class directly accessing,
don’t give it a public, protected or
private declaration. Due to an
oversight in the design of Java, you
can’t explicitly declare the default
“package” accessibility. Other members
of the package will be able to see it,
but classes outside the package that
inherit from yours, won’t. The
protected accessibility attribute
offers slightly more visibibily. A
protected method is visible to
inheriting classes, even not part of
the same package. A package scope
(default) method is not. That is the
only difference between protected and
package scope. "
There are two solutions to your question that don't involve keeping all classes in the same package.
The first is to use the Friend Accessor/Friend Package pattern described in (Practical API Design, Tulach 2008).
The second is to use OSGi. There is an article here explaining how OSGi accomplishes this.
Related Questions: 1, 2, 3, and 4.
You can do such magics with a custom class loader but:
the correct separation will be available only in a project staffed with your class loader;
it's really doubtful that the effort to create such loader is worthy.
In such situations I would do something similar to what we may see in the standard Java. E.g.you see javax.xml.stream.XMLInputFactory but somewhere you have com.sun.xml.internal.stream.XMLInputFactoryImpl. It is perfectly compilable if you write:
new com.sun.xml.internal.stream.XMLInputFactoryImpl()
though you will hardly do it :-) With a system property you may control the actual implementation that is being loaded. To me such approach is fine in many situations.
I hope I have understood your question correctly ;)
Cheers!

A Way Of Saying "For All Subclasses In My Project That Extend This Superclass"?

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...

Categories