I would like to add some dynamic behavior to an application, preferably without resorting to reflection, so I am looking at object registration.
The approach I am thinking is simple: in a class (say Base) which gets to be loaded early enough, a registry (e.g., a HashMap) of plugin objects will be maintained, each of which will later on be used for invoking some of their methods.
The question is, how to register those plugins in Base without any prior knowledge of their existence (so that the application can be dynamically extended via more such plugins). Not knowing them beforehand means a ClassLoader or any reference to their classes cannot be used, thus even with static initialization, registration code cannot be added (since the plugin classes will not be loaded early enough, so the Base class will start executing without knowing them).
Is there any simple solution to the above scenario?
There's several ways of implementing plugin mechanisms, ultimately you need to either scan for implementations of an interface or annotations. Is it important to you that you implement this yourself? There's already libraries that do this (jspf for example).
If you're not interested in reflection, then the code must either adhere to a known interface. Otherwise you'll need to use reflection somewhere to map between what the plugin class(es) provide, and what the "base" code knows how to call.
could you use something like spring and dependency injection ? if you can, each plug in could be a initializing bean so its loaded on start up and in its init method call back to the base to register itself, if not through a direct dependency injection. that obviously uses reflection in background so not sure if that excludes this as your preferred solution...
on another note, typically, looking for classes is not fool proof esp if you could have multiple class loaders :-(
Related
Is there a way to perform (more or less) "automatic" JSR-303 java bean validation without runtime modification of a class?
Usually I see people using AspectJ to accomplish this, but we have had so many complications when using runtime code weaving (like with cofoja) that I'd like to avoid it. It makes a lot of our build tools fail because the runtime class files were different than the class files on disk.
I've looked at dynamic proxies via reflection which can only proxy interfaces (public methods) AND if you call anything annotated inside "this", you don't go through the proxy anymore so you lose that validation.
I'v also looked at ByteBuddy for a way to possibly intercept method calls by wrapping/redefining a class. There might be something here but I can't figure out how to intercept private methods or accomplish the above without getting back into modifying the original class.
Any ideas?
In theory, you can enforce bean validation by reflection only. But I assume that by automatic, you mean without an explicit call to a validation method.
In this case, instrumentation is probably your only option. With Byte Buddy, you can instrument existing methods, by using redefinition or rebasing. The easiest way to do so is a Java agent using an agent builder or using the Gradle or Maven plugins for build time instrumentation. The documentation provides an example of how to implement an agent and the build instrumentations have a lot of javadoc (documentation in progress).
I have a whole bunch of framework modules that work fine on OSGi, all the services and components are finding one another and running just fine.
There is however one framework that does some dynamic stuff regarding classes. Basically at some point you give it a class name and it performs Class.forName() and then reflection magic happens.
This works great when running in a standard jvm and using SPI to wire together the frameworks but it fails in OSGi because of course that random class "test.MyTest" that you are trying to approach via the framework is not visible to said framework.
It will throw a "java.lang.ClassNotFoundException: test.MyTest not found by framework"
So my question: how can I solve this lack of visibility for the framework that needs to see all? Import-Package: *?
UPDATE
Assuming OSGi hasn't changed much since 2010 on this front, the article http://njbartlett.name/2010/08/30/osgi-readiness-loading-classes.html is very interesting. I have currently added support for both actively registering classes and a domain factory to be injected via OSGi.
Apart from that the default resolving uses context classloader anyway so if all else fails that will be used to try and load the class.
UPDATE
I have added support for the suggested DynamicImport-Package as well which is easier for small projects.
You can use DynamicImport-Package:*. This will allow the bundle to see all classes. The problem is that you have no real control over what exactly is exposed. So this is normally a last resort and not the recommended way.
You should first try to use Thread.currentThread().setContextClassLoader() and set it to the classloader of the class you provide to the framework. Sometimes the frameworks also consult this classloader.
The even better way is to find a method in the framework that allows to provide the user classloader.
If you have control over the code then avoid Class.forName(). Instead let the user either give you a class object instead of a class name or let the user give you the combination of a class name and the classloader to use. Both ways work perfectly in and outside OSGi.
I'm working on a project, where it is needed to load some classes at runtime. The classes to load are parts of CDI-Containers and have to be able to inject some stuff. The "loading class" itself is a part of a CDI-Container as well.
Now comes my problem. It is possible to load and instantiate any class via reflection, but in this case it would not be possible for the classes to be loaded to get anything injected. So it is needed to get an instance of these classes as it would be internally done by the server like when we would use the annotation #javax.inject.Inject.
Is there any way to load the classes of another CDI-container in a way that they can still work with Injections (otherwise it would not make any sense^^)? Maybe there is any kind of Class which is responsible for for handling all of these classes so that I can simply tell it the name of the class to load (as I would do it with reflections)... ?
Thanks
You can use the BeanManager API to query and laod contextual references based on bean types.
Review your design carefully, as it sounds like you're entering into "procedural style" programming rather than OO. This is likely the first of many problems with your design you're likely to encounter.
I have an idea that might work though; can you make these classes implement a certain interface? If they do, you can use normal #Inject annotations in your code with the interface, then stuff the class implementation into a /lib directory on a server. This, combined with CDI alternatives may be able to get you what you want.
A better approach may be to use reflection and some kind of factory...
Starting with one Java base-interface, I want others to be able to extend this interface, directly or indirectly, and add bean properties and behavior to it, as a plugin system.
Then, at runtime, on the user computer, I would find all those interfaces and generate a single big class that implements them all. The fields required for the bean properties would be generated automatically, while the behavior defined in the interfaces would be implemented as static methods of an helper class (created by the plugin developers) that take the appropriate interface as first parameter, so the implementation of the interface method would delegate to a static method, passing "this" as first parameter.
This is similar to how Scala implements it's traits.
I see 3 ways of doing this:
Use Java's dynamic proxies, which are based on reflection.
Generate the source-code as a string, and compile it at runtime.
Use some bytecode manipulation library to generate the class at runtime.
Option 1 is the easiest, but least efficient, and therefore I want a better solution. Option 2 would give me an efficient implementation, but is rather ugly.
While I have seen several libraries that can do option 3, they all seem to require that I learn Java's assembler language first, which I take as a very time-consuming activity, with little benefits in the end..
Since I don't want to learn any assembler, JVM or otherwise, is option 2 my best bet, or are there libraries that can generate dynamic proxies without me using JVM assembler?
Have a look at Javassist. With it, you can make runtime changes to classes using a straight-forward API. You don't need to know about java "black magic" to use it.
When using BCEL you don't have to know java assembler. Lok at this proxy.
I am current using Seasar2 Framework on a project that I am in. The framework is quite popular here in Japan but I am having problem in finding English documentations. Even on their official English translation site, they just discuss that the framework use Dependency Injection and AOP.
I was intrigued with the way they use it in one of their component S2Dao. Basically you only need to create interface DAO class and the framework automatically, changes the code on runtime and creates intermediate class that get called in the middle. Hence DB transactions codes are automatically added to the class. I was wondering, is there any step by step explanation on how this is done? Can java change code on runtime and change the method on runtime?
Are good reference on how this is done? I just want to know how the framework is doing this.
Yes, it is possible to do dynamic implementations of an interface at runtime, and to manipulate the compiled bytecode also.
Java provides a built-in mechanism to implement interfaces at run-time, called dynamic proxy classes.
There are also good libraries like cglib or javassist, that allow you not only to implement interfaces, but also to extend classes and to manipulate bytecode at run-time (to change the behavior of a method, for example). Frameworks like Spring and Hibernate use libraries like these to make their magic, so your framework may be using some of these also.
NOTE: If you are curious, these libraries can "tweak" the bytecode because instead of using the default ClassLoader of the JVM, they load your classes using their own ClassLoader, so they have total control of every single byte of the loaded class, and they can do whatever they want with them :).