I'm making a small project and I'm currently stuck on a way to achieve one of the capabilities I need.
Basically I want a method to execute when I'm calling an annotated method.For example
#PrintAnnotation
public void print(){
System.out.println("inside method");
The print annotation would just print extra test, so on calling the above method I would like to get
"Used print annotation"
"Inside method"
That's all.
I'm looking into the annotation processor API but there is no documentation anywhere except reading the javadoc which is crazy, and if I understand correctly its compile only so you cant change the original classes, only add.
I also found answers suggesting to use reflection, but to use reflection I need code triggered that checks if the method is annotated, but to do that I have to add an extra method to every method in the program, like
public void print(){
checkAnnotation();
System.out.println("test");
}
But I need it to work with only adding the annotation, not hundreds of one lines in every method of every class.
It is not possible through "only annotation" with no third party libraries and no custom code.
Annotation is only an annotation and nothing else.
It means you have to have those print and checkAnnotation methods which will detect presence of your Annotation on desired Target (Class,Method, Field...) and do what you'd like to. System.out.println("test"); definitely will not do that.
If you go with those print and checkAnnotation methods - create an utility with those methods and call print from anywhere instead of System.out.println.
But actually, what you try to achieve is about AOP. Your custom annotation can be used with it.
Then, you tagged question with spring tag, do you use Spring? It is a set of third party libraries and has AOP.
Related
I want to restrict the usage of some library methods in my project (so I get a warning when I use these methods). Is there a list of custom deprecated methods in IDEA?
Example: I should never use PrimitiveIterator.OfInt.next(). I should use nextInt() instead. I want to see a warning every time I use next().
Put the text cursor on a method or a call to a method you want to deprecate and type Alt+Enter, invoke Annotate method '<name>' and choose java.lang.Deprecated. If the method you are annotating is located in a library, IntelliJ IDEA will automatically store the annotation "externally" (i.e. in an xml file, the location of which you will be asked for).
Another option is to create a pattern for the Structural Search Inspection to highlight any call to an undesirable method with a warning.
I want to check if it returns with same value by using EasyMock's andReturn method. Unfortunately, I come across with "java.lang.IllegalStateException: missing behavior definition for the preceding method call:" when I use EasyMock. I guess it is not possible to test by EasyMock when I try expect method. You will understand question better in the code.
Regards
Alper
Menu menu = EasyMock.createMock(Menu.class)
menu.setName("name");
EasyMock.expect(XmlParseUtility.createLinesToParse(menu).toString()).andReturn(angularLines.toString());
Error Message :
java.lang.IllegalStateException: missing behavior definition for the preceding method call:
Menu.getName()
Usage is: expect(a.foo()).andXXX()
I'm not sure what you wanted to do. To comment one of the comment, EasyMock isn't strict. It is whatever you want.
If you want a Mockito style mock, you will use niceMock.
Then, about your code. I feel like you want to record a call to setName. And then want to make sure the XmlParseUtility.createLinesToParse is working as expected. If I'm right, you want this code:
Menu menu = EasyMock.createNiceMock(Menu.class); // unrecorded methods will return null
menu.setName("name"); // recording a call to setName
replay(menu); // done with recording, going in replaying
assertEquals(angularLines.toString(), XmlParseUtility.createLinesToParse(menu).toString());
verify(menu); // if you want to make sure setName was called
If you are actually trying to stub the static XmlParseUtility.createLinesToParse() method call, then the PowerMock library is what you are looking for.
// instantiate angularLines and menu
PowerMock.mockStatic(XmlParseUtility.class);
EasyMock.expect(XmlParseUtility.createLinesToParse(menu)).andReturn(angularLines);
PowerMock.replay(XmlParseUtility.class);
// invoke test subject
PowerMock.verify(XmlParseUtility.class);
PowerMock also requires that the test be run using their runner and that the class containing the static method be "prepared". For more information, check out their documentation
I know I can do this in python pretty easily using decorators and I was wondering if it was possible in java. Perhaps annotations aren't even the correct way to go for this, but after reading around I can't find anything about a way to do what I want to.
Let's say that, for example, I have some code that looks like this:
public class AnnotationHelp {
public static void exampleMethod() {
System.out.println("example method");
}
}
So calling AnnotationHelp.exampleMethod() should print example method.
I want something like this:
public class AnnotationHelp {
#MysteryAnnotation
public static void exampleMethod() {
System.out.println("example method");
}
}
Calling this should hopefully call code before and after exampleMethod's main code, resulting in something like:
Printed before main code
example method
Printed after main code
I might be going about this completely wrong, but the gist of it is that I want to be able to quickly add code before and after a bunch of methods (30+) and I think annotations are the way to do it, but I don't know how.
I looked at guice, but I don't think I can add it to the project I'm working on for complicated reasons. I'd much rather go for another solution.
What you're looking for is Aspect Oriented Programming (AOP).
It's not supported out of the box in Java, you have to use 3rd party libraries for this.
Most common framework for accomplishing this is Spring
An alternative to a full AOP solution such as AspectJ, which can lead to hard to maintain code as it almost seems to be "too" powerful, is going for a lightweight approach like the one taken by Java EE interceptors.
You basically need a container which calls the methods. If the method is annotated with an interceptor annotation, call the corresponding code before and/ or after doing the method call.
I have a method in java class file like
public void SIMPLE_METHOD(some params){
...code here...
}
Is there annotation I can use above this method so, a method will be ran before SIMPLE_METHOD, if that pre-method returns true this SIMPLE_METHOD will run other wise this method will be ignored and control will be shifted to next execution point.
I guess the best way to do something like that in your case (since you're already using spring) is to use Spring AOP and #Around advice.
See 6.2.4.5. Around advice:
Around advice runs "around" a matched method execution. It has the
opportunity to do work both before and after the method executes, and
to determine when, how, and even if, the method actually gets to
execute at all.
UPDATE: Also, if you need this for implementing cache on method call it might be a good idea to take a look on Cache Abstraction and #Cacheable.
I'm really rolling up my sleeves and trying to understand Java annotations for the first time, and have read the Sun, Oracle and Wikipedia articles on the subject. They're easy to understand conceptually, but am finding it difficult putting all the pieces of the puzzle together.
The following example is probably terrible engineering, but just humor me (it's an example!).
Let's say I have the following class:
public Widget
{
// ...
public void foo(int cmd)
{
switch(cmd)
{
case 1:
function1();
break;
case 2:
function2();
break;
case 3:
default:
function3();
break;
}
}
}
Now, somewhere else in my project, I have another class, SpaceShuttle, that has a method called blastOff():
public class SpaceShuttle
{
// ...
public void blastOff()
{
// ...
}
}
Now then, I want to configure an annotation called Widgetize so that any methods annotated with #Widgetize will have Widget::foo(int) invoked prior to their own call.
#interface Widgetize
{
int cmd() default 2;
}
So now let's revisit SpaceShuttle:
public class SpaceShuttle
{
// ...
#Widgetize(3)
public void blastOff()
{
// Since we pass a cmd of "3" to #Widgetize,
// Widget::function3() should be invoked, per
// Widget::foo()'s definition.
}
}
Alas, my questions!
I assume that somewhere I need to define an annotation processor; a Java class that will specify what to do when #Widgetize(int) annotations are encountered, yes? Or does this happen in, say, XML config files that get fed into apt (like the way ant reads build.xml files)?
Edit: If I was correct about these annotation processors in question #1 above, then how do I "map"/"register"/make known these processors to the apt?
In buildscripts, is apt typically ran before javac, so that annotation-based changes or code generation takes place prior to the compile? (This is a best practices-type question).
Thanks and I apologize for my code samples, they turned out a lot bulkier than I intended them to (!)
This sounds more like AOP (Aspect oriented programming) than annotations. The topics are often confused since AOP uses annotations to achieve it's goals. Rather than reinvent AOP from scratch, I would recommend looking up and existing AOP library such as AspectJ.
However, to answer your specific question, there are two possible approaches to achieve your goal.
Runtime Approach
This is the approach typically taken by container frameworks (like Spring). The way it works is that instead of instantiating your classes yourself, you ask a container for an instance of your class.
The container has logic to examine the class for any RuntimeAnnotations (like #Widgetize). The container will then dynamically create a proxy of your class that calls the correct Widgetize method first and then calls the target method.
The container will then return that proxy to the original requester. The requester will still thing he got the class (or interface) that he asked for and be completely unaware of the proxying behavior added by the container.
This is also the behavior used by AspectJ.
Enhancement Approach
This is the approach taken by AspectJ. To be honest, I don't know a lot of the details of how it works. Somehow, AspectJ will scan your class files (the byte code), figure out where the annotations are, and then modify the byte code itself to call the proxy class instead of the actual class.
The benefit of this approach is that you don't need to use a container. The drawback is that you now have to do this enhancement step after you compile your code.
I assume that somewhere I need to
define an annotation processor; a Java
class that will specify what to do
when #Widgetize(int) annotations are
encountered, yes? Or does this happen
in, say, XML config files that get fed
into apt (like the way ant reads
build.xml files)?
In Java 1.6, the standard way to define annotation processors its through the ServiceLoader SPI.
In buildscripts, is apt typically ran
before javac, so that annotation-based
changes or code generation takes place
prior to the compile? (This is a best
practices-type question).
APT must take place before compilation, as it operates on source files (actually on syntax trees).
I use method interceptors often with Hibernate. Hibernate requires that a transaction be started and committed round every query. Rather than have lots of duplicate code I intercept every Hibernate method and start the transaction in the interceptor.
I use AOP Alliance method interceptors in conjunction with Google Guice for this. Using these you use your Widgetise annotation and then use Guice to say where you see this annotation use this method interceptor. The following Guice snippet does this.
bindInterceptor(Matchers.any(), Matchers.annotatedWith(Transactional.class), new TransactionalInterceptor);
The interceptor catches the method, you can then call foo and then the tell the method interceptor to proceed with invocation of the original method. For example (in a simplified form):
public class Interceptor implements MethodInterceptor {
//PUT ANY DEPENDENCIES HERE IN A CONSTRUCTOR
public Object invoke(MethodInvocation invocation) throws Throwable {
//DO FOO HERE
result = invocation.proceed();
return result;
}
}
This might be a little confusing and it took me a while to get my head around but it is quite simple once you understand it.
It seems that the basis of your confusion is an incorrect belief that Annotations are something more than just Metadata. Check out this page from the JSE 1.5 language guide. Here is a relevant snippet:
Annotations do not directly affect
program semantics, but they do affect
the way programs are treated by tools
and libraries, which can in turn
affect the semantics of the running
program. Annotations can be read from
source files, class files, or
reflectively at run time.
In your code
#Widgetize(3)
public void blastOff()
does not cause Widget::function3() to execute (asside: in java we reference a member as Widget.function3()) The annotation is just the equivalent of a machine-readable comment (i.e. metadata).
Annotations can be processed both at compile time and at runtime. To process them at runtime requires using the reflection API, which will have a performance impact if it's not done smartly.
It's also possible to process annotations at compile time. The goal is to generate a class which can then be used by your code. There is a specific interface annotation processors have to satisfy, and they have to be declared in order to be executed.
Take a look at the following article for an example which is structurally simple to your use case:
Annotation processing 101