How to make annotation deprecated only on one target
annotations, deprecated, java
Solution
You could use an annotation Processor.
For example, the annotation and its processor would be placed in its own `.jar` file and added as a dependency of the sources that use the annotation.
The custom `.jar` would have the following structure:
src/main/
java/com/company/annotations/
RequiredStore.java
RequiredStoreProcessor.java
resources/META-INF/services
javax.annotation.processing.Processor
`RequiredStore.java` stays as you have it above.
`RequiredStoreProcessor.java` could look something like this:
package com.company.annotations;
import java.util.Set;
import javax.annotation.processing.AbstractProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.annotation.processing.SupportedAnnotationTypes;
import javax.lang.model.SourceVersion;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.Diagnostic;
@SupportedAnnotationTypes("com.company.annotations.RequiredStore")
public class RequiredStoreProcessor extends AbstractProcessor {
@Override
public boolean process(
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
for (Element element
: roundEnv.getElementsAnnotatedWith(RequiredStore.class)) {
if (element.getKind().equals(ElementKind.METHOD)) {
processingEnv.getMessager().printMessage(
Diagnostic.Kind.WARNING,
"Using @RequiredStore on methods has been deprecated\n"
+ "Class: " + element.getEnclosingElement() + "\n"
+ "Method: " + element.getSimpleName() + "\n");
}
}
// Other processing...
return false;
}
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
}
}
The `javax.annotation.processing.Processor` file allows `javac` to pickup the Processor via SPI and simply contains
com.company.annotations.RequiredStoreProcessor
Finally, compile this into a `.jar` and add it to the classpath where the annotations are being used. Any methods that have the `@RequiredStore` will produce a compiler warning. For example, for this class,
package com.company.business;
import com.company.annotations.RequiredStore;
@RequiredStore
public interface Business {
@RequiredStore
public void someMethod();
}
The compiler warning would be this:
warning: Using @RequiredStore on methods has been deprecated
Class: com.company.business.Business
Method: someMethod
As for an indication in the IDE, you might have to write a custom inspection and unfortunately this depends on the IDE used.
Notes:
Decent custom annotations reference: Code Generation using Annotation Processors in the Java language
Problem
I have an annotation that can be added on `METHOD` and `TYPE` and is used in thousands of places in our project. ``` @Retention(java.lang.annotation.RetentionPolicy.RUNTIME) @Target({METHOD, TYPE}) @Inherited public @interface RequiredStore{ Store value(); } ``` Is it possible to make the annotation deprecated only on methods while keeping it non-deprecated on types? I want other developers to be notified by IDE that it should not be used on methods any more, until we'll refactor all existing usages and finally remove the `METHOD` part. If it's not possible, is there any Way to handle such case beside creating new annotation only for types and deprecating the old one?