Adding code to a Java class w/ Instrumentation: ASM or BCEL? - java

I am writing a game engine/library in which I have an event dispatcher class which dispatches events by calling listener methods of "registered" event handler classes. One can register an event handler/listener with the event dispatcher by calling the appropriate dispatcher method.
This obviously leads to some boilerplate code for registering every event handler(and also other aspects of my engine have similar bolierplate code), so I was wondering - how about just using Instrumentation to add in all of the necessary code during loading of the event handler class, so that no explicit registration with the event dispatcher is necessary while coding - the call to the dispatcher's register method is added in automatically when the program is run.
It is my understanding that in order to use Instrumentation one should use some bytecode modifier API. I know of two - ASM and BCEL. Which one should I use? Obviously, this is a somewhat simple task I am trying to do, so I want the one which is easier to learn and better documented.
EDIT: Here is a specific example.
Original event handler class:
#Handler //indicates this this class should be transformed
public class MouseEventHandler implements EventHandler<MouseEvent>
{
//hidden default constructor
public void handleEvent(MouseEvent event)
{ ... }
}
After transformation:
#Handler
public class MouseEventHandler implements EventHandler<MouseEvent>
{
public MouseEventHandler()
{
//add this line of code to default constructor
Game.getEventDispatcher().addEventHandler(this);
}
public void handleEvent(MouseEvent event)
{ ... }
}

Java bytecode libraries:
ASM is fast and actively developed.
BCEL is comparatively slow.
Javassist is probably easiest to get started with if you're not familiar with Java bytecode.
cglib builds on top of ASM, providing some higher level abstractions.
Byte Buddy generates classes via a DSL. Actively maintained and seeing increasing usage.
I would however consider other options before jumping into bytecode manipulation.

Adding the logic to a few classes might be boring, but unless you've thoushands of handlers, that's the way I would go. Keep it simple.
That said,
Game.registerHandler( this );
would be more object-oriented.
An alternative to adding the logic in each class is to introduce a factory that is responsible to instantiate the handlers.
HandlerFactory.createMouseHandler();
And method createMouseHandler contains something like
Handler mh = new MousheHandler();
registerHandler(mh);
return mh;
If you don't want either of these options, I would consider either an aspect framework (maybe AspectJ) or a container for Invertion of Control (maybe Spring IoC). Aspects allow you to annotate your source, and "weave" code at the selected places. An IoC container allows you to control the lifecycle of object (e.g. instantiation). Both use bytecode instrumentation behind the scene.
But if you want to do the instrumentation yourself, I can only compare Javassist and ASM that I used personally.
ASM is low-level, and operates really at the level of java bytecode. You must be familiar with it. The framework is very well designed, the manual is excellent, and it is a great library. One one side it can be complicate to replace patterns of bytecode, because it requires a so-called "stateful" transformation. One the other side, you have full control over the bytecode.
Javassist is more high-level. You do not operate at the raw level of bytecode, a slight higher level, e.g. fields read/write, message send, constructors. Also, it allows you to specify changes using regular java syntax, that is then compiled by the framework. The API is a bit confused, because the project grew over the years. There is documentation about the framework, but not so well centralized as with ASM.

Related

Sending events via code generation with annotations

I have a bunch of methods that must send events when called, i.e. something like this
public void someMethod(){
sendEvent("someMethod was called");
// the method does something
}
public void someOtherMethod(){
sendEvent("someOtherMethod was called");
// the method does something
}
I would like to avoid the sendEvent method call by doing something like
#SendsEvent("someMethod was called")
public void someMethod(){
// do something
}
I have heard of annotation processing as a way of generating code at build time. Would this be possible to do? if so could you point me in the right direction (tutorial or docs).
PS: I have searched on the net for tutorials on annotation processing by they all seem to focus on using the reflections API for runtime annotation processing. This is NOT what I want.
I think for this feature, annotation processing is not worth the additional effort and complexity. Annotation processors are often used for code generation but it doesn't seems you need to generate any dynamic code for this use case. You would have to:
Learn the annotation processor and mirror apis (similar to the reflection api but more complex)
Integrate the processor in your build system
Let the processor generate classes that monitor the annotated methods.
How to do this? There are many ways. You could generate a class that extends your class, adds the event call and then executes the original implementation. Other solution probably involve run-time handling of everything and could be done using reflections
Find a way to load the generated classes instead of you own implementations (DI or something)
Unless you actually really need to generate code for this and do everything at compile time, you should probably just do everything at runtime when the application starts. Checking for annotations once in the beginning using reflections should not impact performance in any way. Use a Proxy to intercept method invocations and add your event calls.

Using Proxy pattern to write a server a good idea?

For a school project, I need to write a simple Server in Java that continuously listens on an incoming directory and moves files from this directory to some place else. The server needs to log info and error messages, so I thought I could use the Proxy pattern for this. Thus, I created the following ServerInterface:
public interface ServerInterface extends Runnable {
public void initialize(String repPath, ExecutorInterface executor, File propertiesFile) throws ServerInitException;
public void run();
public void terminate();
public void updateHTML();
public File[] scanIncomingDir();
public List<DatasetAttributes> moveIncomingFilesIfComplete(File[] incomingFiles);
}
Then I've created an implementation Server representing the real object and a class ProxyServer representing the proxy. The Server furthermore has a factory method that creates a ProxyServer object but returns it as a ServerInterface.
The run-method on the proxy-object looks like this:
#Override
public void run(){
log(LogLevels.INFO, "server is running ...");
while( !stopped ){
try {
File[] incomingContent = scanIncomingDir();
moveIncomingFilesIfComplete(incomingContent);
updateHTML();
pause();
} catch (Exception e) {
logger.logException(e, new Timestamp(timestampProvider.getTimestamp()));
pause();
}
}
log(LogLevels.INFO, "server stopped");
}
The functions that are called within the try statement simply log something and then propagate the call to the real object. So far, so good. But now that I've implemented the run-method this way in the proxy object, the run-method in the real object becomes obsolete and thus, is just empty (same goes for the terminate-method).
So I ask my-self: is that ok? Is that the way the proxy pattern should be implemented?
The way I see it, I'm mixing up "real" and "proxy"-behaviour ... Normally, the real-server should be "stuck" in the while-loop and not the proxy-server, right? I tried to avoid mixing this up, but neither approaches were satisfying:
I could implement the run-method in the real object and then hand over the proxy object to the real object in order to still be able to log during the while-loop. But then the real object would do some logging, which is I tried to avoid by writing a proxy in the first place.
I could say, only Proxy-Server is Runnable, thus deleting run and terminate from the Interface, but this would break up the Proxy pattern.
Should I may be use another design? Or I am seeing a problem where there is none?
You're definitely thinking in the right way. You've hit upon an interesting notion.
Features like logging, as you've described, are an example of what we call cross-cutting concerns in Aspect Oriented programming.
A cross-cutting concern is a requirement that will be used in many objects.
. . therefore, they have the tendency to break object oriented programming. What does this mean?
If you try to create a class that is all about moving files from place A to place B, and the implementation of a method to do that first talks about logging (and then transactions, and then security) then that isn't very OO is it? It breaks the single responsibility principle.
Enter Aspect Oriented Programming
This is the reason we have AOP - it exists to modularize and encapsulate these cross-cutting concerns. It works as follows:
Define all the places where we want the cross-cutting feature to be applied.
Use the intercept design pattern to "weave" in that feature.
Ways we can "weave" in a requirement with AOP
One way is to use a Java DynamicProxy as you've described. This is the default in for example the Spring Framework. This only works for interfaces.
Another way is to use a byte-code engineering library such as asm, cglib, Javassist - these intercept the classloader to provide a new sub-class at runtime.
A 3rd way is to use compile-time weaving - to change the code (or byte-code) at compile-time.
One more way is to use a java agent (an argument to the JVM).
The latter two options are supported in AspectJ.
In Conclusion:
It sounds as though you're moving towards Aspect Oriented Programming (AOP), so please check this out. Note also that the Spring Framework has a lot of features to simplify the application of AOP, though in your case, given this is a school assignment, its probably better to delve into the core concepts behind AOP itself.
NB: If you're building a production-grade server, logging may be a full-blown feature, and thus worth using AOP. . in other cases its probably simple enough to just in-line.
You should use Observer pattern in this case:
The observer pattern is a software design pattern in which an object,
called the subject, maintains a list of its dependents, called
observers, and notifies them automatically of any state changes,
usually by calling one of their methods.
Your Observable will observe changes in directory, by time pooling, or as already was suggested here, with WatchService. Changes of directory will notify Observer which will take action of moving files. Both Observable and Observer should log their actions.
You shold also know that Observer pattern became a part of Java JDK by implementing java.util.Observable and java.util.Observer.
You can make your proxy aware of the real object. Basically your proxy will delegate the call to run method to the real implementation.
Before the delegation, the proxy first logs the startup. After delegation, the proxy logs the "shutdown":
// Snapshot from what should look like the run method implementation
// in your proxy.
public ServerInterfaceProxy(ServerInterface target){
this.proxiedTarget = target;
}
public void run(){
log(LogLevels.INFO, "server is running ...");
this.proxiedTarget.run();
log(LogLevels.INFO, "server is running ...");
}
This implementation can also be perceived as a Decorator pattern implementation. IMHO, I believe that to some extent (when it comes to implementation) Proxy and Decorator are equivalent : Both intercept/capture behavior of a target.
Look at Java 7's WatchService class.
Using Proxy behaviour for this is almost certainly overkill.

How to decouple a module which listens on a hibernate event from the entities themselves?

I have a layered web-application driven by spring-jpa-hibernate and I'm now trying to integrate elasticsearch (search engine).
What I Want to do is to capture all postInsert/postUpdate events and send those entities to elasticsearch so that it will reindex them.
The problem I'm facing is that my "dal-entities" project will have a runtime dependency on the "search-indexer" and the "search-indexer" will have a compile dependency on "dal-entities" since it needs to do different things for different entities.
I thought about having the "search-indexer" as part of the DAL (since it can be argued it does operations on the data) but even still it should be as part of the DAO section.
I think my question can be rephrased as: How can I have logic in a hibernate event listener which cannot be encapsulated solely in an entities project (since it's not its responsibility).
Update
The reason the dal-entities project is dependant on the indexer is that I need to configure the listener in the spring configuration file which is responsible for the jpa context (which obviousely resides in the dal-entities).
The dependency is not a compile time scope but a runtime scope (since at runtime the hibernate context will need that listener).
The answer is Interfaces.
Rather than depend on the various classes directly (in either direction), you can instead depend on Interfaces that surface the capabilities you need. This way, you are not directly dependent on the classes but instead depend on the interface, and you can have the interfaces required by the "dal-entities", for example, live in the same package as the dal-entities and the indexer simply implements that interface.
This doesn't fully remove the dependency, but it does give you a much less tight of a coupling and makes your application a bit more flexible.
If you are still worried about things being too tightly coupled or if you really don't want the two pieces to be circularly dependent at all, then I would suggest you re-think your application design. Asking another question here on SO with more details about some of your code and how it could be better structured would be likely to get some good advice on how to improve the design.
Hibernate supports PostUpdateEventListener and PostInsertEventListener.
Here is a good example that might suite your case
The main concept is being able to locate when your entity was changed and act after it as shown here.
public class ElasticSearchListener implements PostUpdateEventListener {
#Override
public void onPostUpdate(PostUpdateEvent event) {
if (event.getEntity() instanceof ElasticSearchEntity ) {
callSearchIndexerService(event.getEntity());
Or
InjectedClass.act(event.getEntity());
Or
callWebService(InjectedClassUtility.modifyData(event.getEntity()));
........
}
}
Edit
You might consider Injecting the class that you want to isolate from the project (that holds the logic) using spring.
Another option might be calling an outside web service that is not dependent on your code.
passing to it either the your original project object or one that is modified by a utility, to fit elasticsearch.

How can I run my code upon class load?

Is there a feasible way to get my own code run whenever any class is loaded in Java, without forcing the user explicitly and manually loading all classes with a custom classloader?
Without going too much into the details, whenever a class implementing a certain interface read its annotation that links it with another class, and give the pair to a third class.
Edit: Heck, I'll go to details: I'm doing an event handling library. What I'm doing is having the client code do their own Listener / Event pairs, which need to be registered with my library as a pair. (hm, that wasn't that long after all).
Further Edit: Currently the client code needs to register the pair of classes/interfaces manually, which works pretty well. My intent is to automate this away, and I thought that linking the two classes with annotations would help. Next, I want to get rid of the client code needing to keeping the list of registrations up to date always.
PS: The static block won't do, since my interface is bundled into a library, and the client code will create further interfaces. Thus, abstract classes won't do either, since it must be an interface.
If you want to base the behavior on an interface, you could use a static initializer in that interface.
public interface Foo{
static{
// do initializing here
}
}
I'm not saying it's good practice, but it will definitely initialize the first time one of the implementing classes is loaded.
Update: static blocks in interfaces are illegal. Use abstract classes instead!
Reference:
Initializers (Sun Java Tutorial)
But if I understand you right, you want the initialization to happen once per implementing class. That will be tricky. You definitely can't do that with an interface based solution. You could do it with an abstract base class that has a dynamic initializer (or constructor), that checks whether the requested mapping already exists and adds it if it doesn't, but doing such things in constructors is quite a hack.
I'd say you cleanest options are either to generate Code at build time (through annotation processing with apt or through bytecode analysis with a tool like asm) or to use an agent at class load time to dynamically create the mapping.
Ah, more input. Very good. So clients use your library and provide mappings based on annotations. Then I'd say your library should provide an initializer method, where client code can register classes. Something like this:
YourLibrary.getInstance().registerMappedClasses(
CustomClass1.class,
CustomClass2.class,
CustomClass3.class,
CustomClass4.class
)
Or, even better, a package scanning mechanism (example code to implement this can be found at this question):
YourLibrary.getInstance().registerMappedClassesFromPackages(
"com.mycompany.myclientcode.abc",
"com.mycompany.myclientcode.def"
)
Anyway, there is basically no way to avoid having your clients do that kind of work, because you can't control their build process nor their classloader for them (but you could of course provide guides for classloader or build configuration).
If you want some piece of code to be run on any class loading, you should:
overwrite the ClassLoader, adding your own custom code at the loadClass methods (don't forget forwarding to the parent ClassLoader after or before your custom code).
Define this custom ClassLoader as the default for your system (here you got how to do it: How to set my custom class loader to be the default?).
Run and check it.
Depending on what kind of environment you are, there are chances that not all the classes be loaded trouugh your custom ClassLoader (some utility packages use their own CL, some Java EE containers handle some spacific areas with specific classLoaders, etc.), but it's a kind of aproximation to what you are asking.

Java equivalent of Cocoa NSNotification?

I am writing a Java application using SWT widgets. I would like to update the state of certain widgets upon a certain event happening (for example, updating the data model's state).
Is there something in Java similar to Cocoa's NSNotificationCenter, where I can register an object to listen for notification events and respond to them, as well as have other objects "fire off" a notification?
Ok, suppose that for example, you want parts of your program to be notified when your Loader starts a scan, and when it finishes a scan (don't worry about what a Loader is, or what a scan is, these are examples from some code I have lying around from my last job). You define an interface, call it "ScanListener", like
public interface ScanListener
{
public void scanStarted();
public void scanCompleted();
}
Now the Loader defines a method for your other code to register for callbacks, like
public void addScanListener(ScanListener listener)
{
listeners.add(listener);
}
The Loader, when it starts a scan, executes the following code
for (ScanListener listener : listeners)
{
listener.scanStarted();
}
and when it finishes, it does the same thing with listener.scanCompleted();
The code that needs to be notified of these events implements that interface (either themselves, or in an internal class), and calls "loader.addScanListener(this)". Its scanStarted() and scanCompleted() methods are called at the appropriate times. You can even do this with callbacks that take arguments and/or return results. It's all up to you.
What sort of notifications are you looking for? If all you want is for one object to be able to tell anybody else "hey, I've changed, update accordingly", the easiest way is to use the existing Observer interface and Observable class. Or write your own with an interface that defines what you want to get called on the listeners from the one that's changed.
There's no pre-existing per-process service that dispatches events in java that's equivalent to the default NSNotificationCenter. In java, the type of the event is specified by the event object being a particular type (which also means that the notification method depends on that type) rather than using a string. Prior to generics, writing a general event dispatcher and receiver that is also typesafe isn't really possible (witness the proliferation of *Event classes and *EventListener interfaces in the AWT and Spring libraries).
There are some facilities for event dispatch. As Paul mentioned, there's java.util.Observable, which as you point out, requires subclassing. There's also java.beans.PropertyChangeSupport, which could be useful depending on your situation.
You could also write one yourself. The source for PropertyChangeSupport is likely available in the openjdk, and you could look at the abandoned Apache Commons Event project. Depending on your needs, you may have to worry about stuff like threading, seralization, memory leaks (ensuring deregistration or using weak references), and concurrent modification (iterate over a copy of your list of listeners, as a listener may decide to unregister itself in response to a change).
Now that generics exist in Java, a generic event dispatch library would be possible; however, I haven't come across any. Anyone?
There's actually a facility built in to Java that does exactly what you want, but it's not something you may have considered, and, to be honest, it is likely a bit heavyweight for what you want.
That said, however, it does exist.
It's JMX.
You create MBeans, and then others can register for events from those MBeans. The MBean can then send of a Notification.
I personally wouldn't consider using it for this case (I'd just pound out my own), but the facility is there and it well defined and documented.
Not Java, but the IPython project has a notification center written in Python here that you could use as a template for a Java version.
In Java this would be a provider firing notifications to its listeners. But Java does not offer the loose coupling you get with Cocoa's NSNotification because in Java providers and subscribers must have references to each other. Compare for this chapter 18 in "Learn Objective-C for Java Developers".
There is an implementation of IOS NSNotificationCenter in Java.
You can find sources code in :
This Github project

Categories

Resources