java annotations - automated use at runtime - java

So I have a question in relation to using custom annotations at runtime.
Let me fill you in on what I am trying to achieve. I have created a custom annotation and applied it to a method in a service class.
public class MyService
{
#MyCustomAnnotation
public String connect()
{
return "hello";
}
}
Now I can go and use reflection to process methods and apply some kind of logic to methods which have my custom annotation applied to them.
for(Method method : obj.getClass().getDeclaredMethods())
{
// Look for #MyCustomAnnotation annotated method
if(method.isAnnotationPresent(MyCustomAnnotation.class))
{
// Do something...
}
}
However, I seem to be missing a piece of the puzzle as I can't figure out how to apply the reflection processing step automatically at runtime.
For example if I have the following main method in my application, how/where do I automatically apply the reflection processing step when I run the following?
public static void main(String[] args)
{
MyService service = new MyService();
service.connect();
}
Obviously this is possible as other frameworks such as spring are able to achieve it but I can't find an example of how they do this.

Credit to #Beri
I used aspects to create a solution.

Reflection is useful if you need to do something at compile time, if you want to do something when the method is called, you should use Aspect Oriented Programming. The most common framework for Java is AspectJ.
I have a multimodule example here. It's an example with scala, but you can omit the scala dependencies and classes and implement it with Java.
If you want to use the aspect in more than one place you must implement it in a separate module in order to include it and avoid repeating logic.

Related

How are subclasses of an interface get called

This is a question that has been bothering me for a while.
In frameworks like Jersey we have interface(s) that we can subclass to add some functionality to our program. for example to add request filtering in a RESt application we can implement ContainerRequestFilter then Voila we got authentication.
My question is how does the framework/library know that we have subclass one of its interfaces?
as per my understanding you can't instantiate an interface, only its subclass such as:
public interface Greeter{
void sayHi();
}
public class SpanishGreeter implements Greeter{
#override
void sayHi(){
System.out.println("Hola");
}
}
public class Controller{
public void main(String[] args){
//We must know the name of subclass to instantiate?
Greeter spanishG = new SpanishGreeter();
}
}
What you're looking for is classpath scanning.
This isn't a trivial task, and it's pretty much what the name says: you basically need to scan the classpath and load every class you find (although the typical implementation will allow you to limit your search to certain packages and its subpackages only, to stop from things going really crazy).
There are no special tricks in the Java language that would make this task easy.
The good news is that you don't need to write it from scratch, as frameworks like Spring already have it built in, or if you want to have complete low-level control, you can use a dedicated library like Reflections.
I think instanceof keyword helps in it.
System.out.println(spanishG instanceof Greeter); // true
That happens due to Polymorphism. The code you mentioned
Greeter spanishG = new SpanishGreeter();
That has reference of parent(in you case interface). On run time it checks weather there is a child class implementing the method if yes then it calls child class behaviour. And in your class you are instantiating with child class on run time JVM knows you have provided implementation.

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

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.

Intellij/ Java - identify calls to annotated methods

I need to be able to identify calls to methods with specific annotations in Intellij Idea 13, during compile time or by using static code analysis, like calls to #Deprecated methods are identified.
I have looked into doing a structural search in idea, these are supported in static code analysis, and am able to identify method calls from there, but I can't find a way to limit these to calls to method with annotations.
For example
public class A {
#Foo
public void foo(){
// do something...
}
public void bar() {
// do something else....
}
}
public class main {
public static void main(String... args){
A a = new A();
a.foo(); // <---- should be highlighted
a.bar();
}
}
You can by defining your own structural search template like this:
#Foo
$ReturnType$ $Method$($ParameterType$ $Parameter$);
save it e.g. as "methods annotated with #Foo"
and then do a structural search for
$expression$
with the filter reference=methods annotated with #Foo
(to add filter to $Expression$ hover with the mouse over it and then there will be a popup asking you if you want to edit filters and then you add a reference filter)
You could do this in IDEA (which would involve using IDEA's internal interfaces; I don't know offhand which ones give access to annotations).
Depending on your use case, another alternative would be to use an external tool such as the Checker Framework. The advantage is that it is externally supported and has a lot of existing functionality, so there would be less of your own code to write and maintain. Additionally, other people who don't use IDEA would be able to run the analysis. The disadvantage is that there would be less tight integration with the IDE; you would need to configure IDEA to run the analysis, which is straightforward.

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.

Java Unit tests on methods that use third parties libs that don't use Interfaces

I'd like to know how do you test your methods if the libs you are using don't use Interfaces
My class is like
private ThirdParyClass thirdPartyClass;
void myMethod() {
AnotherThirdPartyClass param = "abc";
...
thirdPartyClass.execute(param);
}
I want to test that execute is called with the "abc" param.
I was thinking in creating MyInterface with an implementation that wraps the ThirdPartyClass and then change the class attribute to refer MyInterface. Quite boring stuff but I don't see any other way to be able to successfully test my class.
If ThirdParyClass was an Interface I could mock it, but in this case how do you procede?
i do not know which mock implementation you use it. But EasyMock has an extension available at the EasyMock home page that generate mock Objects for classes. See your mock implementation whether it does not support mock Objects for classes.
regards,
You can use JMockit. It goes far beyond what is possible with EasyMock Class Extension or with jMock and its ClassImposteriser. You actually get all the power of AspectJ, but with a much easier to use, mocking-specific, API.
As long as the third party class you're using isn't final and you don't need to mock final methods you can use JMock and the ClassImposteriser to mock it and carry on as normal.
private Mockery context = new Mockery() {{
setImposteriser(ClassImposteriser.INSTANCE);
}};
AnotherThirdPartyClass mockThirdParty = context.mock(AnotherThirdPartyClass.class);
Note you'll need to add some additional dependencies (jmock-legacy-2.5.1.jar, cglib-nodep-2.1_3.jar and objenesis-1.0.jar)
Why not just use AspectJ (AOP) for the unit testing.
By using an around aspect you can then control what gets passed into the method and better monitor it.
If you need to have it extend an interface, you can modify the class through aspects to give it more functionality, such as turning logging on/off or getting performance information.
Then, when you are done, you remove the aspects before putting this into production by just not including the aspect class files in the build.

Categories