I want to make my program initialization a bit "smarter".
I have several classes which represent commands. All these classes are immutable (i.e. creating only one instance of each should be enough for the whole application). All these classes implement Command interface.
I think that the fact that some classes are placed in the same jar with a class with the main method (maybe even in 1 predefined package) and that these classes implement one known interface should give enough information to make it possible to automate creation of their instances.
How can I implement this feature? (Obviously, it's something tightly connected with reflection, and maybe, with java class loading mechanisms, but I'm not an expert in these fields).
I want to have something like this:
public static void init() {
...
Map<String, Command> commands = Maps.newHashMap();
for (Class clazz : findCommandImplementationsInThisJarFile()) {
//some try/catch stuff is ommited
Command command = clazz.newInstance();
commands.put(command.getName(), command);
}
...
}
How to implement the tricky method findCommandImplementationsInThisJarFile()?
You need extcos:
select(javaClasses()).from("your.package").returning(allAnnotatedWith(YourAnnotation.class))
Also supports thoseImplementing and thoseExtending etc...
See: http://sourceforge.net/projects/extcos/
Spring also contains similar code for it's component scanning that is easily adapted.
Related
I have a class Main.java in which I need to instantiate a bunch of other classes say C1.java ... C50.java. I am not able to think of an elegant way to instantiate these 50 classes in Main class. If I simply put all instantiating code in one place it looks so crowded and ugly. Today I have 50 classes to instantiate, tomorrow this count can increase to 100, then this situation will get worse. Can you please suggest an elegant way of instantiating all these classes without making Main class crowded with instantiation code. I am not aware of any design pattern to do this.
I am thinking to create an array of classes that needs to be instantiated and use reflection to instantiate them.
The answer depends on what purpose the classes would serve. However, if you don't mind to end up with an unordered collection of instantiated classes, there is a way to go using Reflections library and I guess also a shorted one in the matter of lines of code:
// find out all the classes implementing MyInterface
Set<Class<? extends MyInterface>> subTypes = reflections.getSubTypesOf(MyInterface.class);
// iterate those classes and instntinate them
List<MyInterface> objects = new ArrayList<>();
for (Class<? extends MyInterface> clazz: subtypes) {
objects.add(clazz.newInstance());
}
In any case, the whole design should be rethough.
The recommended solution is to use the service loader architecture.
Instantiating all registered implementations of MyInterface can be done as simple as
for(MyInterface my: ServiceLoader.load(MyInterface.class)) {
/* do something with <my> */
}
To make this work, its not enough to just implement the interface, these implementations must be declared as service providers, either via an entry in META-INF/services/ of your jar file (as described in the linked class documentation) or via provides declaration within a Java module declaration when using Java 9 or newer.
The advantage of this is not only a higher performance, compared to searching the entire class path with a reflection library, it also ensures that the necessary access rights are established when using Java’s module system in the future.
See also Java 9’s version of the class documentation.
I have a fairly large Java code base (~15k files) that I do not have access to the source for, however, I would like to modify certain classes at runtime and inject code into certain methods to also call my code.
Due to technical issues, I can't decompile/recompile and go from there. The class files are loaded by native code and are extracted from a custom archive format and loaded using a custom class loader. I can however execute Java code in the context of their JVM instance fairly easily.
My goal is to do something like below:
For example, say in there code there is a class:
class Theirs {
public Theirs() {
//....
}
public String getName() {
return "Theirs";
}
}
And in my code I have:
class Mine
{
public static Theirs theirs_ = null;
public static void myMethod(Theirs theirs) {
theirs_ = theirs;
}
}
I would like to modify every instance of Theirs to behave as such:
class Theirs {
public Theirs() {
Mine.myMethod(this);
}
}
So that I can then do something like:
System.out.println(Mine.theirs_.getName());
I thought that CGLib Proxies would enable this, but with Proxies, the overhead is high due to string comparisons for methods that may be called hundreds thousands of times a second and anyways, I discovered that in order to have an instance of an enhanced object, you need to instantiate them yourself.. IE: not all instances of the class you enhanced are actually enhanced such as:
public static void main( String[] args )
{
Object proxy = Enhancer.create(Object.class, new HashCodeAlwaysZeroMethodInterceptor());
System.out.println(new Object().hashCode());
System.out.println(proxy.hashCode());
}
The first println prints a real objects hash, not 0 as intended.
So now I am thinking that what I need to do is write my own (or modify theirs) ClassLoader that looks for the classes I am interested in modifying, inject my modifications and go from there using something like ASM. (I've done something similar using JVMTI and C++, but the compile/debug process for that is extremely time consuming)
Before I do that however, I was hoping that there was something that worked similar to how CGLib proxies work, in that the library takes care of the required bytecode modifications, but that doesn't require me to actually instantiate an instance of said enhanced class.
I don't know if CGLIB is ideal for injecting Java code into Java classes - but there are a couple of framework like f.e. javassist available which provide a Java centric way to inject code into non-sealed Java classes: http://www.csg.ci.i.u-tokyo.ac.jp/~chiba/javassist/
For example, I had to create a Plugin mechanism for a university course once where I used javassist therefore. Hope the code example is helpful: https://github.com/RovoMe/PluginApplication/blob/master/PluginFramework/PluginCore/src/main/java/at/rovo/core/classloader/InjectionLoaderStrategyDecorator.java
I'm attempting to write a framework to handle an interface with an external library and its API. As part of that, I need to populate a header field that exists with the same name and type in each of many (70ish) possible message classes. Unfortunately, instead of having each message class derive from a common base class that would contain the header field, each one is entirely separate.
As as toy example:
public class A
{
public Header header;
public Integer aData;
}
public class B
{
public Header header;
public Long bData;
}
If they had designed them sanely where A and B derived from some base class containing the header, I could just do:
public boolean sendMessage(BaseType b)
{
b.header = populateHeader();
stuffNecessaryToSendMessage();
}
But as it stands, Object is the only common class. The various options I've thought of would be:
A separate method for each type. This would work, and be fast, but the code duplication would be depressingly wasteful.
I could subclass each of the types and have them implement a common Interface. While this would work, creating 70+ subclasses and then modifying the code to use them instead of the original messaging classes is a bridge too far.
Reflection. Workable, but I'd expect it to be too slow (performance is a concern here)
Given these, the separate method for each seems like my best bet, but I'd love to have a better option.
I'd suggest you the following. Create a set of interfaces you'd like to have. For example
public interface HeaderHolder {
public void setHeader(Header header);
public Header getHeader();
}
I'd like your classes to implement them, i.e you's like that your class B is defined as
class B implements HeaderHolder {...}
Unfortunately it is not. Now problem!
Create facade:
public class InterfaceWrapper {
public <T> T wrap(Object obj, Class<T> api) {...}
}
You can implement it at this phase using dynamic proxy. Yes, dynamic proxy uses reflection, but forget about this right now.
Once you are done you can use your InterfaceWrapper as following:
B b = new B();
new IntefaceWrapper().wrap(b, HeaderHolder.class).setHeader("my header");
As you can see now you can set headers to any class you want (if it has appropriate property). Once you are done you can check your performance. If and only if usage of reflection in dynamic proxy is a bottleneck change the implementation to code generation (e.g. based on custom annotation, package name etc). There are a lot of tools that can help you to do this or alternatively you can implement such logic yourself. The point is that you can always change implementation of IntefaceWrapper without changing other code.
But avoid premature optimization. Reflection works very efficiently these days. Sun/Oracle worked hard to achieve this. They for example create classes on the fly and cache them to make reflection faster. So probably taking in consideration the full flow the reflective call does not take too much time.
How about dynamically generating those 70+ subclasses in the build time of your project ? That way you won't need to maintain 70+ source files while keeping the benefits of the approach from your second bullet.
The only library I know of that can do this Dozer. It does use reflection, but the good news is that it'll be easier to test if it's slow than to write your own reflection code to discover that it's slow.
By default, dozer will call the same getter/setters on two objects even if they are completely different. You can configure it in much more complex ways though. For example, you can also tell it to access the fields directly. You can give it a custom converter to convert a Map to a List, things like that.
You can just take one populated instance, or perhaps even your own BaseType and say, dozer.map(baseType, SubType.class);
I was hoping to use groovy's invokeMethod to do this, but it turns out that when you call from Java to Groovy, invokeMethod isn't called, but otherwise it would have worked perefectly.
I have a case where I'm submitting a Groovy class to a Java class (Which I can't edit). The Groovy class is annotated and the Java class scans for the annotations and saves the annotated methods as listeners for it's events.
When the event is issued I'd like to grab some information from the event object, use it to retrieve data and inject that data into the event handler in the script (Via annotated variables inside that method).
The things I have control over--I instantiate the scripts, set a base class for them, and pass them to the other system to be registered. The scripts will be written by others--I have control over the script's design but my goal is simplicity.
I could probably create an adapter class, but that seems quite difficult and fragile since I'd have to manually register all those methods instead of using the annotations like it does now--there are a lot of different events to listen to.
I'm wondering if there are groovy tricks I'm not considering. I'm still pretty new to groovy meta-programming. Perhaps there is a way to create the adapter class automatically, or when I compile the scripts, replace the methods with forwarding methods that forward to my code before calling their real method--anything like that possible?
Requested source code:
Source code--well let's see, this process is spread across a few classes...
This is how I set up the Groovy Class Loader with a ScriptBase
cconfig.setScriptBaseClass("tv.kress.bill.minecraft.ezplugin.ScriptBase");
GroovyClassLoader gcl = new GroovyClassLoader(getClass().getClassLoader(), cconfig);
Then I pass it to the Groovy Scripting Engine (I'm leaving out some stuff here)
gse = new GroovyScriptEngine(cpString, gcl);
Then I instantiate the script
scriptClass = gse.loadScriptByName(file.getAbsolutePath());
instance = (GroovyObject) scriptClass.newInstance();
Then, if it's a "Listener" which is the marker interface that the "canned" java library uses to identify java classes it should scan for annotations, I pass it off to that class so that any annotated methods can be registered (Somewhere along the line "instance" became "script", same object though:
if (script instanceof Listener)
pm.registerEvents((Listener) script, this);
The interesting part of the script itself looks like this:
#EventHandler
public void userEvent(UserInteractEvent event) {
What I'd like to add is the ability to, inside the userEvent, add an annotated local variable like this:
#Persist int persistedPerUserData // Or #PersistPerUser? or #Persist(User=true)?
so that just before userEvent is called, I can intercept it. I'd grab the user name from the UserInteractionEvent, combine it with the script, variable and method name to get a unique signature like "MyScript:UserEvent:Bill:persistedPerUserData" and use that to retrieve an int I can place into persistedPerUserData.
Later after the method returns grab the value from persistedPerUserData and store it back into "MyScript:UserEvent:Bill:persistedPerUserData" (Currently a hash but I expect to make it a database eventually).
In this way, the script never has to consider the fact that it's dealing with different users, it just has to have a single set of variables and all the persistence just works.
There are other events this will work for, but I believe they all extend the same event and that root event has the "user" field.
EDIT: Just as another thing NOT to try, I tried to use the ProxyMetaClass/interceptor like this:
// Attempt (and fail) to intercept calls to an instance of clazz
class Slicer {
public static Object slice(Class clazz) {
Object instance;
def proxy = ProxyMetaClass.getInstance(clazz);
proxy.interceptor = new MyInterceptor();
proxy.use {
instance = clazz.newInstance();
}
return instance;
}
}
With the same results, every call from a groovy class was instrumented fine, but no calls from Java were intercepted. Back to the drawing board. I guess this is why Aspects use bytecode manipulation.
I really haven't figured out an answer to this, but I came up with something that I think will work--I suppose nobody mentioned it because it was so obvious, but I'm still "Thinking in Java" More than groovy.
Okay, where I was hoping for the script implementation to look something like this:
#EventHandler
public void userEvent(UserInteractEvent event) {
#Persist int persisteData
// At this point persistedData contains data different depending on which user was passed in
...
I think that if I use a closure I think I can do something close:
#EventHandler
public void userEvent(UserInteractEvent event) {
persistScope(event.user) {
#Persist int persistedPerUserData // Or #PersistPerUser? or #Persist(User=true)?
...
and that way within persistScope I can scan the closure for #Persist annotations and do my thing. This may not work exactly because that int hasn't been created until the closure starts, but I think I can fix that using the methods I mentioned in the question as long as I'm calling from groovy to groovy. Either that or I'll just make "it" a hash with the persisted user data.
It's slightly more awkward but I think it will work, and I like the fact that it's a little more explicit (In fact before I was just assuming that the "event" passed in had a .getUser() method, now I can scope persistence to anything I want).
I'll go try to implement this and give it a few days to see if anyone comes up with an answer to the original question I asked before accepting this.
EDIT: I'm unhappy with this solution. Since the variables are declared inside that scope I couldn't use the #Persist annotation, so i passed in a hash that the module can use as a data container, then I persist it after the closure returns.
Still looking for better answers...
Let's say I have a labyrinth with AI characters, where the users define the characters. Each user provide the classes for their individual characters. All the characters/classes extend some class/type C which has method control().
I want to do call each user's control() method, but I don't know how many users there will be or what classes they will provide. How do I resolve this problem?
EDIT: I wanted to convey that I do not know how many subclasses there are, or what their names are. Therefore, I am not able to place those subclasses in the code statically.
EDIT 2: Is there a way of doing this WITHOUT using reflection? I am aware that reflection solves the problem, but I hoped there was a cleaner implementation.
EDIT 3: It completely necessary to have the users create the different classes, as the point of the program is to test competing AIs.
btw, I am writing this in Java.
First of all, you need to decide if the different characters' behavior is really going to be as differentiated as to need Java code to implement the particular behaviors. Perhaps the behavior can be expressed with a single class and only modified by setting different values for parameters such as speed, health, attack strength etc. In this case you would get rid of the inheritance problem altogether and use a single class while users would only provide different configurations.
Now, if you really need very custom behavior and load custom Java classes, I see two main solutions.
First is the standard one. It uses just a tiny bit of reflection. You define an interface, for example:
public interface C {
void control(); //Params skipped for brevity
}
Now, your users create classes which implement this interface. The only problem is how to create an instance of the player's class. Once you have it, you call its control() or other methods via the interface. First, users need to make this class loadable. Thiscan be done through the network or in other complex ways but the simplest is that they put their .class or .jar file in their classpath when they run your application. Now all you need is to create an instance of the class. Assuming you specify the requirement that the class have a zero-argument constructor (you can define a method in your interface to load some configuration and perform initialization later on), you would be doing something like:
C gameCharacter = (C)Class.forName("your.fully.qualified.ClassName").newInstance();
Apart from error handling, that's all the reflection you need. You can now call all methods of interface C on your gameCharacter object - without knowing who or how wrote it and what exactly the methods do.
The other solution would be to use Groovy or another similar language to compile and run code on the fly. In this case you don't need the custom JAR in the classpath and you can even get around the need to know the name of the class to be loaded. Your user can provide the Java code of control() method in the form of text, and you can have a stub class whose control() method only compiles and executes the Groovy code the user provided. This may be more convenient, but requires the custom character code to be provided to you as source code, not compiled JAR, which may be a problem for some users. Also, this solution is more convenient if the implementations are going to be short and self-contained while the separate JAR and loading via reflection is better if the loaded code is more complex, uses helper classes apart from the main class etc.
The whole thing about inheritance is that you don't need to know the exact type.
If you have a reference to an object that is of type C or a subclass of C, you can call your "control()" method on them and it will call the right method, i.e. the one implemented by the child class.
Not knowing how many users means you'll have to use a list or something and loop over it.
public class AIGame {
public static void main(String[] args) {
List<AICharacter> characters = new ArrayList<AICharacter>();
characters.add( new ReallySmartAICharacter() );
characters.add( new ReallyDumbAICharacter() );
for ( AICharacter c : characters ) {
c.control();
}
}
}
interface AICharacter {
public void control();
}
class ReallySmartAICharacter implements AICharacter {
#Override
public void control() {
// TODO do something clever here
}
}
class ReallyDumbAICharacter implements AICharacter {
#Override
public void control() {
// TODO do something stupid here
}
}
If all the characters extend some common class, for convenience let's call it Character, then you can use polymorphism to dynamically call each of the control() methods.
In other words, if each subclass of Character overrides control(), then all you need to do is call it normally and Java will figure out which control() method to call.
e.g.
Character[] characters = new Character[2];
characters[0] = new Man(); // Man is a subclass of Character
characters[1] = new Woman(); // same with Woman
character[0].control(); // <- this will call the control() method as defined in Man
The mechanism for this is called late (or dynamic) binding, which you can read more about here: http://en.wikipedia.org/wiki/Late_binding
If the subclasses are not known at compile-time (i.e. they are specified at run-time), then you will need to use reflection to load them.
To keep track of each user, use a dynamically sized List type like a LinkedList or ArrayList. This way you don't need to know how many users there are beforehand.