Can I use annotation to call method after the annotated one? - java

I am wondering if I can use custom annotation to call some method right after annotated one. For example I have a class that holds some settings that can also notify objects that something has changed (for example user changed something in settings panel). Not all listeners are interested in all types of events, so MyEvent is enum. Now I have structure like this:
class Settings
{
private ArrayList<Listeners> listeners;
private void notifyListeners(MyEvent e)
{
// notify all listeners that something was changed
}
public void setSomeOption(int value)
{
// validate parameter, store it etc.
notifyListeners(MyEvent.SOME_INTEGER_SETTING_CHANGED);
}
}
Of course listening object has to check type of event and ignore it or perform some action, but it is not the case here.
I am interested if I can achieve this with annotations, like this
#NotifyAnnotation(MyEvent.SOME_INTEGER_SETTING_CHANGED)
public void setSomeOption(int value)
{
// validate parameter, store it etc.
// NO NEED TO CALL NOTIFY HERE - WILL BE HANDLED BY ANNOTATION
}
In JUnit for example, we have #Before or #After annotations, and I am wondering if JUnit has own annotations parser that handles method annotated this way, or this kind of behavior can be done simpler, since annotations can be #Retention(value=RUNTIME).
I know that in this example it might look over-complicated and calling notifyListeners() is much simper, but I wan't to know if annotation can be used the way I described, and if yes, can i get some tips? I don't expect ready solution, just a hint if this is possible and what should I take in consideration.

yes, you can do it but you have to use a framework or write one by yourself. you can use for example spring aspects and #After advice (or any other proxy mechanism). you can also use full aspectj for this. another option is to write it by yourself using reflection api. in last case you will need some kind of inversion of control - some mechanism that will launch your method and then the other method

In annotations you need a class that checks for it. they don't work on themselves.
The way systems check for them are with reflection.
Annotation<NotifyAnnotation> a = method.getAnnotation();
And explicitly call their methods
a.notifyListeners(a.evt);
I can't see any advantage with your case. but I see full of disadvantages. They should not be used in actual coding, just for test systems or similar scenarios, where an external system has control on your class.

It could be do that using bytecode manipulation (JAssist, Asm, Java Rocks ...). All the classes would be instantiated thru a Factory that would identify annotated methods and would inject in the first line of this method a call to the method specified in its annotation.

Related

Intercept method declaration

I have the following method:
#OnEvent
public void onEvent(Event event) {
}
Now, I am puzzled whether AspectJ can intercept the method "declaration", i.e. neither its call nor its execution, in order to provide functionality somewhere else.
The objective is to "take" that method and register it as a handler of events into the OSGi service registry:
public void start(BundleContext bc) {
bc.registerService(EventHandler.class, new EventHandler() {
#Override
public void handleEvent(Event event) {
// TODO get a "reference" of the onEvent(...) method and call it here
onEventJoinPoint.proceed(event);
}
}, null);
}
No, this is conceptually impossible in AspectJ and probably also in any other AOP framework. But you have several alternatives:
How about putting marker annotations in all places where the aspect should kick in? There you could parametrise the annotation so as to mention which method to call.
Or if you really want to have it all in one place and avoid config files, use a configuration class similar to Spring. The class or one of its methods which you call when booting up your component, would carry all config annotations which would thus be interceptable by AspectJ.
You could also keep the annotation where it is and call the annotated method once after loading the class, intercept the method execution and take note of the method from an aspect, then re-use this information later.
There are other, similar options. But in each case, please note that
class loading / initialisation order is important,
if you just have a method and class name, you will need reflection in order to call it, unless the method is either static or the class is a singleton and the method does not rely on any object state, i.e. an instance can easily be obtained and the method be called as often as needed. Then you could maybe even tweak the solution into calling proceed() multiple times.
If you have follow-up questions which are too complex for simple comments, please update the main question and notify me. I cannot be any more concrete now because I do not know enough about your use case. Thus, I am not providing any sample code (yet).

Java: How to listen on methods invocation without registering each object explicitely?

I want to listen on method calls in order to attach additional behavior dynamically around the call. I've already done it on JUnit methods with a custom annotation and runner. I'm trying to do it on a standard java application.
The main idea is to do:
#Override
public void beforeInvoke (Object self, Method m, Object[] args){
Object[] newargs = modifyArgs (args);
m.invoke (self, newargs);
}
It's just an abstract idea, I don't have any concrete example, but I'm curious if it's possible in java.
I've found some approaches:
java.lang.reflect.Proxy.newProxyInstance(...)
where a proxy is defined for an interface only (but not used to decorate concrete classes). It seems similar to injection pattern and it's a different concern.
Another approach here using a factory pattern with the ProxyFactory class. This other solution requires explicit calls to create() method to produce object proxies listening on method invocations. So, if you bypass it by using natural constructors of your classes, it's not working. It's very constraining if you must explicit a call to a factory each time you have to create an object.
There is a way to do it with transparency ?
Like Proxy.newProxyInstance() but working also on concrete classes ?
Thanks.
Well,this is commonly seen with Spring Framework and Aspect Oriented Programming. Since you delegate your constructor calls to Spring, it is quite easy for Spring to put a proxy in place to intercept calls to the actual objects.
As far as I can tell, the only way to intercept calls is to use a proxy. Either in the way you mentioned or using Spring and AOP.
I think cglib let you instrument concrete classes.
As far as I know there is no easy way to intercept method calls that are called on a concrete class.
As mentioned you could manipulate the bytecode during compilation (as Used in AOP) or at class loading time (as used from cglib).
Another product to instrument Classes would be jmockit (http://jmockit.org/). Usually I would use this special kind of black magic only in testing environments and not in an productive environment.
Another way you could go is Annotation Processing. It work's during compiling process. You have to write a Processor which will walk through your source code and generate source-code that contains the original code plus the enhanced method-calls you need.
Depending on how much source-code you have to enhance, this method might be a good idea, but in general it is a lot of work.
Here's a link (https://deors.wordpress.com/2011/10/08/annotation-processors/).
Despite usually it's used in combination with annotations, this is not a strict requirement.

How to control object's lifecycle with Guice

I have Guice-injected objects which have two lifecycle methods bind() and unbind(). The method bind() is called automatically after the object is instantiated by Guice using following annotated method:
#Inject
final void autoBind() {
bind();
}
What I want to do is to call the method unbind() on the old (current) object before a new instance of the object is created by Guice. How do I do that?
Thanks in advance!
First of all, I would not advise that you just annotate arbitrary methods with #Inject. Keep it to constructors, and occasionally for optional injection and/or field injection.
What you are trying to do does sound a bit weird, and I'm not sure it's exactly what you want. Can you please provide more background on what you're trying to do because maybe a different approach is better. There are definitely some concerns here with thread safety and how you manage references.
Based on what you described, an approach like what #meverett mentioned would probably work. If the objects you have are Foos, it would look something like this.
// Later on be sure to bind(Foo.class).toProvider(FooProvider.class);
final class FooProvider implements Provider<Foo> {
private final Provider<Foo> unboundFooProvider;
private Foo currentInstance;
#Inject FooProvider(#Unbound Provider<Foo> unboundFooProvider) {
this.unboundFooProvider = unboundFooProvider;
}
#Override public Foo get() {
if (currentInstance != null) {
currentInstance.unbind();
}
currentInstance = unboundFooProvider.get();
currentInstance.bind();
return currentInstance;
}
}
NOTE that your #Unbound Foo provider would generate Foos without invoking any special methods. The regular FooProvider keeps track of state and deciding when to bind() and unbind() the instances. Please be careful with how you manage multiple instances and use them with multiple threads.
Also, just to be clear: I'm using #Unbound since the methods you want to invoke are called bind() and unbind(). I'm not using "bound" in the Guice sense.
Also note... off the top of my head I'm pretty sure Providers are treated as singletons, so maintaining state like this will work. If it didn't, you could obviously just create a level of indirection with some kind of singleton factory (but that shouldn't be necessary).
Previous responses address other concerns nicely, so to just answer the question:
Netflix introduced governator in github in 2012 to "enhance Google Guice to provide ... lifecycle management". It provides annotations (#PreConfiguration, #PostConstruct, #PreDestroy, and others), classpath scanning & auto binding, and other features. Bootstrapping is straight forward.
I suppose you could have a provider that keeps a reference to the current object. When you call get on the provider it would unbind the last object, construct the new one and save the reference to it.
though I'm not really sure why you would want to do something like this since other objects can in theory still be referencing it

Designing Constructors for Testability

I'm working with some existing code, trying to add to it and increase the unit tests for it. But running into some problems with getting the code testable.
Original Constructor:
public Info() throws Exception
{
_ServiceProperties = new ServiceProperties();
_SshProperties = new SshProperties();
}
I'm aware that this is bad, and obviously not testable. In a junit environment, this class will fail to create every time since it wont be able to find the necessary properties to construct itself. Now, I'm aware this class would be a lot more testable with the simple change of moving anything prefaced with 'new' as a parameter.
So I end up with:
New Constructor:
public Info(ServiceProperties srvProps, SshProperties sshProps) throws Exception
{
_ServiceProperties = srvProps;
_SshProperties = sshProps;
}
Which allows me to properly unit test this Info class. The problem though, is now all that work is pushed to some other class:
Some Other Class' Method:
public void useInfo() throws Exception
{
ServiceProperties srvProps = new ServiceProperties();
SshProperties sshProps = new SshProperties();
Info info = new Info(srvProprs, sshProprs);
doStuffWithInfo(info);
}
Now this method isn't testable. All I've managed to do is push off where the constructions of these Property objects are occurring, and somewhere else some piece of code is going to be stuck actually having to call "new".
Here's the rub for me: I can't figure out how to break this chain of events of simply pushing these "new" calls somewhere else. What am I missing?
Look at using a Dependency Injection framework such as Spring. This application of Inversion of Control means that each of your types can avoid the pitfall you've seen, leaving the configuration to "wire" components together.
This introduction to Spring (pdf) gives a comprehensive overview of Spring. The first chapter or two should be sufficient to explain the concepts.
Also see Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler
You have the right idea. Perhaps this will help you. I recommend you follow two rules for all your classes of significance, where "of significance" means if you don't follow the steps it will be more difficult to test, reuse, or maintain the class. Here are the rules:
never instantiate or self-acquire a dependency
always program to interfaces
You have a start at rule #1. You changed your Info class to no longer create its dependencies. By "dependency" I mean other classes, configuration data loaded from property files or whatever, etc. When you depend on how something is instantiated you are tying your class to it and making it more difficult to test, reuse and maintain. So, even if a dependency is created via a factory or a singleton, don't have your class create it. Have something else call create() or getInstance() or whatever and pass it in.
So you chose the "something else" to be the class that uses your class, and realized there is a bad smell to it. The remedy is to instead have the entry-point to your application instantiate all dependencies. In a traditional java app, this is your main() method. if you think about it, instantiating classes and hooking them up to each other, or "wiring" them together, is a special kind of logic: "application assembly" logic. Is it better to spread this logic throughout your code, or to collect it in one place to more easily maintain it? The answer is that collecting it in one place is better - not only for maintainance, but the act of doing so turns all your classes of significance into more useful and flexible components.
In your main() or equivalent of main() you should create all the objects you need, passing them into each others' setters and constructors to "wire" them together. Your unit tests would then wire them differently, passing in mock objects or similar things. The act of doing all this is called "dependency injection". After doing as I say, you will likely have a big ugly main() method. This is where a dependency injection tool can help you out and in fact make your code infinitely more flexible. The tool I would suggest when you get to this point, as others have also suggested, is Spring.
The less important rule #2 - always program to interfaces, is still very important because it eliminates all dependencies on implementation, making reuse much easier, not to mention leveraging other tools like mock object frameworks, ORM frameworks, etc. easier as well.
Even dependency injection frameworks like Spring, Guice, PicoContainer etc. need some sort of boostrap so you always have to build something up.
I would suggest you to use a provider/factory that returns a configured instance of you class. This would allow you to exit the "creation"-hierarchy.
Your constructors aren't incorrect and the problem isn't about when/where code is executed, it's about what everyone else mentioned: Dependency Injection. You need to create mock SshProperties objects to instantiate your object. The simplest way (assuming the class isn't marked as final) is to extend the class:
public class MockSshProperties extends SshProperties {
// implemented methods
}
You can you use mock frameworks like Mockito:
public class Info {
private final sshProps;
private final serviceProps;
public Info() {
this(new SshProperties(), new ServiceProperties());
}
public Info(SshProperties arg1, ServiceProperties arg2) {
this.sshProps = arg1;
this.serviceProps = arg2
}
}
public class InfoTester
{
private final static SshProperties sshProps = mock(SshProperties.class);
private final static ServiceProperties serviceProps = mock(ServiceProperties.class);
static {
when(sshProps.someGetMethod("something")).thenReturn("value");
}
public static void main(String[] args) {
Info info = new Info(sshProps, serviceProps);
//do stuff
}
}
The easiest answer is Spring. However another answer is to put your config stuff into JNDI.
Spring in some ways is a better answer, especially if you don't have anything that changes depending on environment.
You let the some-other-class have too much knowledge about the Info class and its dependencies. A dependency injection framework would use a provider class. Using generic types one can make a Provider of Info objects:
interface Provider<T> {
T get();
}
If your some-other-class take a Provider<Info> in its constructor your method would look like:
public void useInfo() throws Exception
{
Info info = infoProvider.get();
doStuffWithInfo(info);
}
This has removed construction of concrete classes from your code. Next step is to make Info into an interface to make it easier to create a mock for the specific unit-test case.
And yes, this will push and push all the object construction code further and further up. It will lead to some module that only describes how to wire things together. The "rules" for such code is that it should be free of conditional statements and loops.
I recommend reading Misko Heverys blog. All the presentations are useful and printing out the guide to writing testable code as little rulebook once you understand the rules is a good thing.

How to mock object construction?

Is there a way to mock object construction using JMock in Java?
For example, if I have a method as such:
public Object createObject(String objectType) {
if(objectType.equals("Integer") {
return new Integer();
} else if (objectType.equals("String") {
return new String();
}
}
...is there a way to mock out the expectation of the object construction in a test method?
I'd like to be able to place expectations that certain constructors are being called, rather than having an extra bit of code to check the type (as it won't always be as convoluted and simple as my example).
So instead of:
assertTrue(a.createObject() instanceof Integer);
I could have an expectation of the certain constructor being called. Just to make it a bit cleaner, and express what is actually being tested in a more readable way.
Please excuse the simple example, the actual problem I'm working on is a bit more complicated, but having the expectation would simplify it.
For a bit more background:
I have a simple factory method, which creates wrapper objects. The objects being wrapped can require parameters which are difficult to obtain in a test class (it's pre-existing code), so it is difficult to construct them.
Perhaps closer to what I'm actually looking for is: is there a way to mock an entire class (using CGLib) in one fell swoop, without specifying every method to stub out?
So the mock is being wrapped in a constructor, so obviously methods can be called on it, is JMock capable of dynamically mocking out each method?
My guess is no, as that would be pretty complicated. But knowing I'm barking up the wrong tree is valuable too :-)
The only thing I can think of is to have the create method on at factory object, which you would than mock.
But in terms of mocking a constructor call, no. Mock objects presuppose the existence of the object, whereas a constructor presuppose that the object doesn't exist. At least in java where allocation and initialization happen together.
jmockit can do this.
See my answer in https://stackoverflow.com/questions/22697#93675
Alas, I think I'm guilty of asking the wrong question.
The simple factory I was trying to test looked something like:
public Wrapper wrapObject(Object toWrap) {
if(toWrap instanceof ClassA) {
return new Wrapper((ClassA) toWrap);
} else if (toWrap instanceof ClassB) {
return new Wrapper((ClassB) toWrap);
} // etc
else {
return null;
}
}
I was asking the question how to find if "new ClassAWrapper( )" was called because the object toWrap was hard to obtain in an isolated test. And the wrapper (if it can even be called that) is kind of weird as it uses the same class to wrap different objects, just uses different constructors[1]. I suspect that if I had asked the question a bit better, I would have quickly received the answer:
"You should mock Object toWrap to match the instances you're testing for in different test methods, and inspect the resulting Wrapper object to find the correct type is returned... and hope you're lucky enough that you don't have to mock out the world to create the different instances ;-)"
I now have an okay solution to the immediate problem, thanks!
[1] opening up the question of whether this should be refactored is well out of the scope of my current problem :-)
Are you familiar with Dependency Injection?
If no, then you ceartanly would benefit from learning about that concept. I guess the good-old Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler will serve as a good introduction.
With Dependency Injection (DI), you would have a DI container object, that is able to create all kinds of classes for you. Then your object would make use of the DI container to instanciate classes and you would mock the DI container to test that the class creates instances of expected classes.
Dependency Injection or Inversion of Control.
Alternatively, use the Abstract Factory design pattern for all the objects that you create. When you are in Unit Test mode, inject an Testing Factory which will tell you what are you creating, then include the assertion code in the Testing Factory to check the results (inversion of control).
To leave your code as clean as possible create an internal protected interface, implement the interface (your factory) with the production code as an internal class. Add a static variable type of your interface initialized to your default factory. Add static setter for the factory and you are done.
In your test code (must be in the same package, otherwise the internal interface must be public), create an anonymous or internal class with the assertion code and the test code. Then in your test, initialize the target class, assign (inject) the test factory, and run the methods of your target class.
I hope there is none.
Mocks are supposed to mock interfaces, which have no constructors... just methods.
Something seems to be amiss in your approach to testing here. Any reason why you need to test that explicit constructors are being called ?
Asserting the type of returned object seems okay for testing factory implementations. Treat createObject as a blackbox.. examine what it returns but dont micromanage how it does it. No one likes that :)
Update on the Update: Ouch! Desperate measures for desperate times eh? I'd be surprised if JMock allows that... as I said it works on interfaces.. not concrete types.
So
Either try and expend some effort on getting those pesky input objects 'instantiable' under the test harness. Go Bottom up in your approach.
If that is infeasible, manually test it out with breakpoints (I know it sucks). Then stick a "Touch it at your own risk" comment in a visible zone in the source file and move ahead. Fight another day.

Categories