How to run relevant methods using annotation? - java

Maybe this question title is not up to my queries but I am searching for the answers for so long.
After adding Lombok to a project, we can use getter, setter, Slf4j, etc. Like
#Getter
#Setter
public class Example {}
My query is After adding #Slf4j we can access an instance of a class "log".Like
#Slf4j
#Getter
#Setter
public class Example {
public void do() {
log.debug("doing");
}
}
So how can I build this kind of annotation that will provide "log" like implementation in java?

Lombok developer here: Lombok is a bit more complicated than that.
Lombok is a unique kind of tool. Yes, it is an annotation processor in the sense that you can specify lombok as being one and lombok then runs as as annotation processor and sets itself up during the init() call (javac will, once its ready to run the processors, first initialize them all).
Lombok is not an annotation processor in the sense that other than the init() step and interacting with the 'rounds' system (specifically: Causing another round to fire in certain cases, in order to ensure javac 'sees' the stuff lombok made. Usually this isn't needed, as it takes a little bit of extra time so we don't do it unless absolutely neccessary) – lombok doesn't use the annotation API at all.
If you are asking how to make your own: That's very complicated. Best route is to fork lombok on github, and have a look at e.g. both HandleSetter.java files in the source to know what to do (there's one for ecj/eclipse and one for javac). Then, you'll be ready to write your own.
Note that intellij support is done via a separate intellij plugin so if you're interested in having lombok work there, you'd also need to fork that plugin and add support there. You only need to mess with intellij if you want new 'signatures' to be visible (you want to add or remove fields or methods, or you want to change the signature parts of one of those: The name, return type, field type, parameter type, or throws line, or you want to add a new type, though that last part can be done with a simple annotation processor).

Related

How to properly use Lombok #Data with interfaces

I'm using quite a bit of native queries in my spring book application since Hibernate won't allow me to write Join queries using Join Tables that are not mapped. I came across this article which helped me to project Native Queries into DTOs beautifully. As mentioned in the article I'm using a DTO interface with an #Data (Lombok) annotation. It worked like a charm while I was running it locally inside eclipse via "Run as Spring Boot Application". But when I'm trying to mvn package it in order to deploy the JAR, I'm getting a compilation error, stating
myDTO.java:[8,1] #Data is only supported on a class.
I don't understand how it works so well while I'm running it in eclipse and maven gives me a compilation error.
Edit: It works in the Java 8 (used in eclipse) and throws a compilation error in Java 11 (Global path version).
You found a lombok 'bug', in that the eclipse variant should also have generated that error instead of doing nothing. Because.. it's doing nothing.
The reason the appropriate response is that error is because #Data on an interface makes no sense. #Data does 4 things. Before I enumerate them, just to be clear, interfaces cannot have (non-static) fields. You can write it, but java will silently upgrade them to public static final.
#Data:
Makes a constructor. (Not legal to do to an interface, so, it can't do that).
Makes a getter and setter for each non-static field. (There can't be any, in an interface, so this does nothing).
It makes a toString that prints the type, and each non-static field (There CAN be one, even with an impl using the default feature, but all it would do is print the type's name; not a very useful toString!)
It makes an equals and hashCode impl (Here too it can exist, but all it would do is return a constant value for hashcode and return a convoluted mess for equals and canEqual which doesn't make much sense as the point is to compare the non-static fields and there aren't any). None of this makes any sense because any classes that implement this interface are effectively forced into overriding these methods for them to work anyway, at which point these implementations will not be used.
I think you're a bit confused, or at least, I am, so, let's take a step back and talk about what problem you're trying to solve / what you think would be happening if you put #Data on an interface.
NB: Java11 vs. Java8 difference is a red herring; that's not the problem here.
NB2: Disclaimer - I'm a core maintainer of project lombok.

Java Annotations and apt (fundamentals)

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

Why java annotations?

i want to ask why are the java annotations used so much... I know that they replaced xml configuration in for example jpa, but why is this kind configuration used at all?
Consider this piece of code:
#Entity
class Ent{
// some fields
}
//... somewhere in the other file far far away
class NonEnt{
// whatever here
}
Now, when I try to put this in persistence context, with EntityManager's persist method, I get runtime error(better would be to get compile error) with trying to persist NonEnt instance. There is obvious solution for me, force the entities to implement some no-method interface instead of using #Annotations. But this isn't popular among framework designer, what is the drawback of this solution?
Thanks for answering...
When compared to marker interfaces, annotations have some advantages:
they can be parameterized
they are more fine grained - you can attach them not only to classes but also to other class elements (fields, methods, method arguments, etc)
Annotations are also supposedly less intrusive, but this point is matter of taste and debatable.
See also:
Annotations (official JDK documentation)
What is the use of marker interfaces in Java?
The use of annotations is a lot less invasive than forcing the client to implement a interface or extend a class.
There is obvious solution for me,
What you describe is called a "marker interface" and it's an abuse of the interface concept. I suspect the only reason why you consider it obvious is because of Serializable - which only exists because there were no annotations at that time.
force the entities to implement some
no-method interface instead of using
#Annotations. But this isn't popular
among framework designer, what is the
drawback of this solution?
What are its advantages? Annotations have the huge advantage that they can have parameters, and they are much more fine-grained. Marker interfaces only work at the class level.
Citing the java tutorial:
Annotations provide data about a
program that is not part of the
program itself. They have no direct
effect on the operation of the code
they annotate.
Annotations have a number of uses,
among them:
Information for the compiler — Annotations can be used by the
compiler to detect errors or suppress
warnings.
Compiler-time and deployment-time processing — Software tools can
process annotation information to
generate code, XML files, and so
forth.
Runtime processing — Some annotations are available to be
examined at runtime.
As you can see, annotations are a way of specifying meta-data about your types in java, including interfaces, they are in no way a replacement for them.
Java annotation are really helpful when you want to add some additional information to your class, method or instance variable. There are a lot of libraries which use these annotations heavily. These annotations keep the code simple and readable with the power of making changes to the code at runtime.
For example if you have used lombok library, which creates setter, getter and constructor at compile time and saves you lines of code and time.
When compiler executes the code, lomok searches for all the fields marked with #Setter or #Getter annotation and add setter and getter for that field in the class.
One other example is Junit test runner. How junit differentiates between normal helper method in test class and a test. To differentiate between the two it uses #Test annotation.
This tutorial explains how you can use java annotations to create you own test runner.

Useful Java Annotations

I'm interested in finding out exactly which Java annotations people think are most useful during development. This doesn't necessarily have to limited to the core Java API, you may include annotations you found in third party libraries or annotations you've developed yourself (make sure you include a link to the source).
I'm really interested in common development tasks rather than knowing why the #ManyToOne(optional=false) in JPA is awesome...
Include the annotation and a description of why it's useful for general development.
I doled out a bunch of upvotes for other users, but just to give my two cents the only three annotations I use with any regularity in development are the main annotations used directly by the compiler:
#Override - Great for making it explicit in your code when you're overriding another method. Also has the extra benefit of being flagged as a compilation error if you don't override a method the way you think you are (see this other SO post). This flag informs the compiler that you're intending to override something, so if you don't (e.g. you forget an argument in the method signature), the compiler will catch it.
#Deprecated - Indicate whatever you're marking as something that should not be used from this point forward. The compiler will generate warnings for use of any code elements you've marked as deprecated. In general, deprecation says "this was in here in the past, but it may go away in a future version." Make sure you also use the associated "#deprecated" Javadoc flag in conjunction with this too to tell people what they should use instead.
#SuppressWarnings - Tell the compiler to suppress specific warnings it would otherwise generate. This can be useful for things like when you intentionally want to use deprecated methods, you can block out the deprecation warning. I tend to use it a lot to block out everyone's favorite "Serialization UID" warning on serializable classes (whether or not you should do that is another debate for another time). Just handy for those cases where you know something you're doing is generating a warning, but you're 100% sure it's the proper behavior you want.
Look at the Sun Annotations Guide and check out the section "Annotations Used by the Compiler". These three are given a fairly lengthy discussion.
The Java Concurrency in Practice annotations
Very useful for describing exactly how your code is or isn't thread safe...
I find the he concurrency-related annotations defined by Brian Goetz in his book "Java Concurrency In Practice" to be very useful:
#GuardedBy
#Immutable
#NotThreadSafe
#ThreadSafe
They're particularly useful as FindBugs has patterns that use them.
A jar and documentation is freely available at http://www.javaconcurrencyinpractice.com/
#Override has my vote. It makes it instantly clear what your method is about and makes your code more readable.
#Test
(JUnit 4) It's made writing and understanding test files quite a bit cleaner. Plus, the ability to add the expected attribute has saved a few lines of code here and there.
#Deprecated
Introduced in Java 5.
It helps developers see what's deprecated in IDEs. (Prior to this, most IDEs could still pull a #deprecated out of the javadoc comments for a particular method, but this annotation was a nice way to make it meta-information about the method itself, rather than a comment in documentation.)
It's also used by the compiler to print out warnings when you're using deprecated methods.
Personally I've been looking at the JSR303 Bean Validation and the annotations it provides, I imagine these will become more commonplace, there's only a few implementations of the JSR so far, but they provide annotations such as:
#NotNull private String name;
#NotNull #Size(min = 5, max = 30) private String address;
More info here: http://jcp.org/en/jsr/detail?id=303
these should be useful, you can define them in your projects to better communicate intentions:
#ThreadSafe
#Immutable
#ValueObject
#BagOfFunctions (e.g. java.util.Collections)
etc
Here are some Annotations I use in day to day development
Spring:
#Autowired - used to Auto wire beans
#Rollback - If set to true it will rollback all DB operations done inside the test case
JUnit:
#Test - Tell that a method is a test case
#Ignore - If you want to ignore any of the test cases
#Before - Code that should run before each test case
JPA:
#Entity - To tell that a POJO is a JPA Entity
#Column - Map the property to DB column
#Id - tell that a java property is Primary key
#EmbeddedId - Used for Composite Primary Keys
#Transient - This property should not be persisted
#Version - Used to manage optimistic locking
#NamedQuery - Used to declare Native SQLs
#OneToMany - One to Many relationship
#ManyToOne - Many to one Relationship
I have included only the most essential ones.You can find details about all the JPA annotations from the following links.
http://www.oracle.com/technology/products/ias/toplink/jpa/resources/toplink-jpa-annotations.html
http://www.hiberbook.com/
We started using a compile time tool called lombok (http://projectlombok.org/). You annotate classes, members, etc. and methods are automatically generated at compile time. It's a great productivity boost and saves hundreds of lines of tedious coding.
Do you want a toString() method to be automatically generated? Just annotate your class with #ToString.
Tired of having to define getters and setters for your members? Annotate your class with #Getter and / or #Setter and they're automatically added.
Want to have an SLF4J logger to log stuff? #Slf4j creates a private static final logger for you.
#Data
public class MyBean {
// Getters for x and y, setter for y and constructor with x as arg automatically created!
// toString() and hashCode() methods are there too!
private final int x;
private int y;
}
.
#Slf4j
public class SomeClass {
public void doSomething() {
log.info("I've got log.");
}
}
Setting it up is very easy: just add a provided maven dependency. There's also a tiny Eclipse / IntelliJ plugin.
Check out the full list of features there: http://projectlombok.org/features/index.html
Junit 4 provides very useful annotations. Here's a tutorial illustrating the usage of annotations to define tests.
e.g.
#Test(expected= IndexOutOfBoundsException.class) public void empty() {
new ArrayList<Object>().get(0);
}
As Dan pointed out below, TestNG did this originally.
#Given
allows one JUnit test to build upon the return value of another test. Requires JExample.
#FunctionalInterface
Useful to communicate that a particular interface is meant to be functional. If the single abstract method is removed, it'll throw a compilation error.
I started a weekend project to implement a Programming By Contract framework using method and parameter annotations e.g.
//...
myMethod (#NotNull String a, #NotNullOrEmpty String b){
if ( !validate() ){
//raiseException
}
}
I got stuck at the point of getting param values automatically. Java reflection does not have it. never understood several people's ranting on Java till I came across this limitation.

Java Annotations

What is the purpose of annotations in Java? I have this fuzzy idea of them as somewhere in between a comment and actual code. Do they affect the program at run time?
What are their typical usages?
Are they unique to Java? Is there a C++ equivalent?
Annotations are primarily used by code that is inspecting other code. They are often used for modifying (i.e. decorating or wrapping) existing classes at run-time to change their behavior. Frameworks such as JUnit and Hibernate use annotations to minimize the amount of code you need to write yourself to use the frameworks.
Oracle has a good explanation of the concept and its meaning in Java on their site.
Also, are they unique to Java, is there a C++ equivalent?
No, but VB and C# have attributes which are the same thing.
Their use is quite diverse. One typical Java example, #Override has no effect on the code but it can be used by the compiler to generate a warning (or error) if the decorated method doesn't actually override another method. Similarly, methods can be marked obsolete.
Then there's reflection. When you reflect a type of a class in your code, you can access the attributes and act according to the information found there. I don't know any examples in Java but in .NET this is used by the compiler to generate (de)serialization information for classes, determine the memory layout of structures and declare function imports from legacy libraries (among others). They also control how the IDE form designer works.
/EDIT: Attributes on classes are comparable to tag interfaces (like Serializable in Java). However, the .NET coding guidelines say not to use tag interfaces. Also, they only work on class level, not on method level.
Anders gives a good summary, and here's an example of a JUnit annotation
#Test(expected=IOException.class)
public void flatfileMissing() throws IOException {
readFlatFile("testfiles"+separator+"flatfile_doesnotexist.dat");
}
Here the #Test annotation is telling JUnit that the flatfileMissing method is a test that should be executed and that the expected result is a thrown IOException. Thus, when you run your tests, this method will be called and the test will pass or fail based on whether an IOException is thrown.
Java also has the Annotation Processing Tool (apt) where not only you create annotations, but decide also how do these annotations work on the source code.
Here is an introduction.
To see some cool stuff you can do with Annotations, check out my JavaBean annotations and annotation processor.
They're great for generating code, adding extra validations during your build, and I've also been using them for an error message framework (not yet published -- need to clear with the bosses...).
The first thing a newcomer to annotations will ask about annotations is: "What is an annotation?" It turns out that there is no answer to this question, in the sense that there is no common behavior which is present in all of the various kinds of java annotations. There is, in other words, nothing that binds them together into an abstract conceptual group other than the fact that they all start with an "#" symbol.
For example, there is the #Override annotation, which tells the compiler to check that this member function overrides one in the parent class. There is the #Target annotation, which is used to specify what kinds of objects a user defined annotation (a third type of construct with nothing in common with other kinds of annotation) can be attached to. These have nothing to do with one another except for starting with an # symbol.
Basically, what appears to have happened is that some committee responsible for maintaining the java language definition is gatekeeping the addition of new keywords to the java language, and therefore other developers are doing an end run around that by calling new keywords "annotations". And that's why it is hard to understand, in general what an annotation is: because there is no common feature linking all annotations that could be used to put them in a conceptual group. In other words, annotations as a concept do not exist.
Therefore I would recommend studying the behavior of every different kind of annotation individually, and do not expect understanding one kind of annotation to tell you anything about the others.
Many of the other answers to this question assume the user is asking about user defined annotations specifically, which are one kind of annotation that defines a set of integers or strings or other data, static to the class or method or variable they are attached to, that can be queried at compile time or run time. Sadly, there is no marker that distinguishes this kind of annotation from other kinds like #interface that do different things.
By literal definition an annotation adds notes to an element. Likewise, Java annotations are tags that we insert into source code for providing more information about the code. Java annotations associate information with the annotated program element. Beside Java annotations Java programs have copious amounts of informal documentation that typically is contained within comments in the source code file. But, Java annotations are different from comments they annotate the program elements directly using annotation types to describe the form of the annotations. Java Annotations present the information in a standard and structured way so that it could be used amenably by processing tools.
When do you use Java's #Override annotation and why?
The link refers to a question on when one should use the override annotation(#override)..
This might help understand the concept of annotation better.Check out.
Annotations when it comes to EJB is known as choosing Implicit middle-ware approach over an explicit middle-ware approach , when you use annotation you're customizing what you exactly need from the API
for example you need to call transaction method for a bank transfer :
without using annotation :
the code will be
transfer(Account account1, Account account2, long amount)
{
// 1: Call middleware API to perform a security check
// 2: Call middleware API to start a transaction
// 3: Call middleware API to load rows from the database
// 4: Subtract the balance from one account, add to the other
// 5: Call middleware API to store rows in the database
// 6: Call middleware API to end the transaction
}
while using Annotation your code contains no cumbersome API calls to use the middle-
ware services. The code is clean and focused on business logic
transfer(Account account1, Account account2, long amount)
{
// 1: Subtract the balance from one account, add to the other
}

Categories