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 :).
Related
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...
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 :-(
I want to define a method interceptor in a Java program in other words I want to have a behaviour which is executed at each method call.
This application isn't executed in an application server and therefore I can't use the EJB around invoke interceptors.
I have found a nice Proxy API in the standard Java libraries but its limited because it needs an interface in the proxy creation:
Foo f = (Foo) Proxy.newProxyInstance(Foo.class.getClassLoader(),
new Class[] { Foo.class },
handler);
Is there a similar API which doesn't force Foo.class to be declared as an interface?
Why not use CGLIB ? See this article for more information.
What if you want to proxy legacy classes that do not have interfaces?
You can use CGLIB. CGLIB is a powerful, high-performance code
generation library. Under the cover, it uses ASM, a small but fast
bytecode manipulation framework, to transform existing byte code to
generate new classes. CGLIB is faster than the JDK dynamic proxy
approach. Essentially, it dynamically generates a subclass to override
the non-final methods of the proxied class and wires up hooks that
call back to the user-defined interceptors.
Unfortunately there is no such API for classes. Many frameworks are using bytecode generation libraries like CGLIB to achieve this.
You can try one of the mocking classes. The simplest approach may be to sub-class, your class. Or you could use AOP to inject the logging code you want.
sun.misc.ProxyGenerator can be used to generate proxy classes and doesn't check that their "interfaces" are all interfaces. Its generateClassFile method gives you the bytecode as a byte array, which you can save to link into future builds or alter with third-party tools.
Note that if any of the "interfaces" has a final method, you'll get an error when you try to load the class.
I know that Javassist is a Java library providing a means to manipulate the Java bytecode of an application.
Ok, but why we need manipulate bytecode?
Any real example?
Any real app, where javassist used?
A common application is to generate proxy classes at runtime, i.e. to create a subclass at runtime that intercepts all method invocations. Examples:
Hibernate uses Proxies to intercept method invocations on entities to implement lazy loading, i.e. fetching the object from the database when it is first accessed.
The Spring Framework uses Proxies to implement its AOP support, which among other things powers its support for declarative transactions. It also uses proxies to enforce proper scoping.
EJB uses proxies to implement container managed transactions, authorization checking, and to apply user-defined interceptors.
CDI implementations must also proxy the managed beans to ensure proper scoping. I suspect they use a byte code engineering library, too.
I recently used Javassist to implement a transparent cache for method return values, by intercepting all method invocations and only delegating to the super implementation on the first invocation.
Note that java.lang.reflect.Proxy can generate proxy classes at runtime, but can only implement interfaces, not extend a class. All of the above use cases require the proxying of classes.
Bytecode manipulation is useful and necessary, especially when you do not have source code for certain projects. Say you only have the bytecode (like a jar file) for some project, but you want somehow change the behavior of the code, the bytecode manipulation library can help in such cases. The advantage of bytecode manipulation is that you don't need to recompile your code and can directly execute it after manipulation.
I have used bytecode manipulation to do some program analysis. Given a library, I want to know during the runtime what methods in the library have been invoked. I can use bytecode manipulation to insert a System.out.println("method_name"); statement in the beginning of a method. So during the runtime, it will print out what methods have been invoked.
Some bytecode manipulation libraries are:
ASM
ByteBuddy
BCEL
To extend Meriton answer and to provide a real example of use :
Hibernate-core (5.2.8.Final) use javaassit (3.20.0-GA):
https://mvnrepository.com/artifact/org.hibernate/hibernate-core/5.2.8.Final
Users page of the ASM project lists several dozen widely used Java projects and frameworks using ASM for bytecode analysis and manipulation. http://asm.ow2.org/users.html
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.