#SuppressWarnings annotation on Application Level - java

I was reading this question, where #SuppressWarnings annotation is used on class level.
Suppose I have multiple classes in my application, so is there a way that I can use #SuppressWarnings on application level? As applying #SuppressWarnings on every class is redundant for me.

this is what javadoc says for #SupressWarnings
#Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
#Retention(value=SOURCE)
public #interface SuppressWarnings
#Target clearly mentions places where #SupressWarnings can be applied. So you can not apply at application level. Even doc go ahead and says
As a matter of style, programmers should always use this annotation on the most deeply nested element where it is effective. If you want to suppress a warning in a particular method, you should annotate that method rather than its class.
So its discouraged to do at parent level where it is not applicable.

Related

How to target methods declared in a controller subclass whilst avoiding ambigous mapping?

I am trying to use AspectJ for logging in a Spring Boot project. The latter has been set up with a controller class that handles the initial request for a particular document through a related REST controller. This controller class is extended by specific classes for each document, which assemble the end product; inheritance was not my idea.
To measure performance I want to log execution time for individual methods by using an #Around advice. However, even when the functions are individually annotated, those in the subclass are not advised. Methods further in the call stack that are not inherited from the initial controller class are not ignored. The relevant subclass methods are public and they are not inherited from the superclass.
Logging the execution time of the controller method is meant to provide the overall duration. Information with respect to subsequent functions is supposed to indicate possible bottlenecks. How can I include the methods declared in the subclass?
Confidentiality precludes sharing specifics, but the relevant aspects of the class structure can be conveyed using generic names:
[
To follow best practices I always intended to implement custom annotations to be used in pointcuts. Nevertheless, initially, I used signature based pointcuts and their combinations. Ignoring package elements of the pointcut declaration:
#Pointcut("execution(public String Controller.*(..)")
public void controllerPointcut() {}
This approach captures the controller methods, as do similar declarations for the reader classes. However such pointcuts are simply ignored in the case of the subclass. Using the + symbol to target child classes does not help. The documentation indicates that inherited or declared methods in a subclass can be targeted by signature. In the specific case this results in an IllegalStateException due to ambiguous mapping, as does the use of a class level annotation, unsurprisingly.
I only need to log two methods in the child classes, so I hoped to target them directly with a common annotation, which I also added to the controller and reader methods. The pattern, excluding package elements is:
#Pointcut("#annotation(LoggableDuration)")
public void readerControllerPointcut() {}
The functions in the latter two are being advised, so the annotation itself is not the problem. Nevertheless, the implementation has been added below. For thoroughness, I used a combined approach as well. The controller methods were targeted with the kind of signature approach shown above and for the rest an annotation was used. The result is the same. The problem seems to be some element of how AspectJ deals with inheritance that I have not been able to discover. However, I did expect that annotating individual methods could possibly allow me to avoid any such considerations.
#Component
#Target(ElementType.METHOD)
#Retention(RetentionPolicy.RUNTIME)
public #interface LoggableDuration {}
Edit: It seems that Spring Boot was not picking up the subclass. Adding the #Component annotation allows AspectJ to advise the desired methods as does a class level custom annotation with ElementType.Type as the #Target value. However, both lead to an IllegalStateException: ambiguous mapping, presumably because of the inheritance of the Rest controllers. I managed to target the subclass methods with execution based pointcuts, which were not ignored. But, this caused the aforementioned exception to appear again.

Is it possible to have a Java annotation that doesn't apply to any class, method, field, etc. Just the annotation itself generating code

Are there such things as Java annotations that aren't tied to any class, method, field, etc.?
Like just writing
#MyAnnotation(someParameter=value, ...)
by itself, and it generates code.
It seems like ExecutableType might define what kinds of "elements" an annotation can annotate, but I'm not sure. If that's true, then ExecutableType derives from TypeMirror, one of whose members are NoType. So maybe it's possible? But I cannot find an example of this.
You cannot have a stand-alone annotation in Java.
Annotations can be applied to different things, for example: types, methods, fields, local variables, packages, method parameters and also on annotation definitions.
One annotation that is meant to be used on annotation definitions (therefore it's called a "meta-annotation") is #Target, which you use to indicate on what things the annotation you are defining is allowed to be used. You do this by specifying one or more element types as an argument to the #Target annotation - see the API docs of java.lang.annotation.ElementType.
The Java Language Specification paragraph 9.6.4.1 explains what annotations can be used on in more detail.

What is a deprecated annotation target - implementation, interface or both?

Hi i wonder if i have to annotate a deprecated method at all their occurrences like, Interface, Base (Abstract Class) and all the Implementation Classes or is one annotation in the Interface sufficient?
Actually depends of how deprecated classes are used. Deprecate an interface (methods or attributes) is enough if you use good practices (instantiating the interface to use the implementation).
Anyway,
you cannot ensure / force this practice in other users
not all compilers/parsers will throw a warning or show javadoc #deprecated tag
Using the #Deprecated annotation to deprecate a class, method, or field ensures that all compilers will issue warnings when code uses that program element. In contrast, there is no guarantee that all compilers will always issue warnings based on the #deprecated Javadoc tag, though the Sun compilers currently do so. Other compilers may not issue such warnings. Thus, using the #Deprecated annotation to generate warnings is more portable that relying on the #deprecated Javadoc tag.
Resuming: if you want to deprecate a method implementation you must deprecate both, interface and implementation.
SOURCES 1 2 3

Does #SuppressWarnings work with warnings generated by annotations?

Assume that I have an annotation that generates a warning. The annotation is on a method.
e.g.
#AnnotationThatGeneratesAWarning
public void doSomething() {
//stuff
}
Can I use #SuppressWarnings to suppress it? Does #SuppressWarnings work with warnings generated by annotations, or just on warnings generated by the method itself?
What IDE are you using? What's the code that generates the warning?. A good IDE will generally suggest the String to use in the #SuppressWarnings, but it's better to first try to fix the warning, if that's not possible and as a last resource use #SuppressWarnings.
EDIT :
You can tell that #SuppressWarnings won't work with other annotations looking at its documentation. As you can see:
#Target(value={TYPE,FIELD,METHOD,PARAMETER,CONSTRUCTOR,LOCAL_VARIABLE})
The targets do not include ANNOTATION_TYPE, meaning that #SuppressWarnings can not be applied to other annotations.
I have tested the following in Eclipse. The annotations are from Spring MVC.
#SuppressWarnings("all")
#RequestMapping("/{foo}/somepage.do")
public void serveAPage() {
}
The {foo} in the #RequestMapping generates a warning as it's not being assigned to a variable*. The warning description is "URI template variable "foo" is not defined".
#SuppressWarnings("all") should suppress all warnings for the method. Eclipse still shows a warning, despite this.
As far as I can tell, you can't use #SuppressWarnings to suppress warnings caused by an annotation.
*This was the code that originally prompted the question. Fixing the code so it doesn't cause an exception is trivial and not the point of the question.

Ignore Deprecated Type Warnings on import Statement

I'm importing a class which has been deprecated, which I'm forced to use.
I want to suppress the deprecated error using the #SuppressWarnings("deprecation") annotation.
As per the comment on that annotation:
As a matter of style, programmers should always use this annotation on
the most deeply nested element where it is effective. If you want to
suppress a warning in a particular method, you should annotate that
method rather than its class.
So I clearly don't want to annotate the class and thus suppress deprecation warnings on any type my class uses, but I also would like to use the import statement to avoid typing out the fully qualified type name, which spans my entire monitor, on each use of the deprecated class.
I think I want to do something like annotating the import statement with #SuppressWarnings (NOT POSSIBLE) or specifying in the #SuppressWarnings annotation which type to ignore warnings for (e.g. #SuppressWarnings("deprecation", "fully.qualified.type.name").
I want to indicate to the compiler "it's okay if I use this one, and only this one, deprecated class, referenced by its Simple Name, anywhere within this other class, and any other deprecated classes I reference you should let me know about".
Is there anything like this available?
A way to work around this would be to do the following, assuming you can extend the Deprecated class.
import comp.DeprecatedClass;
#SuppressWarnings("deprecation") public class MyDeprecatedClass extends DeprecatedClass{ }
Then you can use your version without having to worry about warnings.

Categories