Reputation: 3036
I have a custom Java annotation which generates a file when test sources are compiled. But when I import this annotation into a Scala class and I use it in the same way that in Java, Scala is not processing it.
Java Annotation
@Retention(RetentionPolicy.SOURCE)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Trace {
public String key() default "";
public byte step() default 0;
public String url() default "";
}
@SupportedAnnotationTypes("com.custom.annotations.Trace")
@SupportedSourceVersion(SourceVersion.RELEASE_6)
@AutoService(Processor.class)
public class TraceProcessor extends AbstractProcessor {
public static final String DEFAULT_FILE_PATH = "target/";
public static final String DEFAULT_FILE_NAME = "trazability.txt";
private Messager messager;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
Set<? extends Element> annotatedElements = getTraceAnnotatedElements(roundEnv);
if(annotatedElements.size() == 0) {
return true; // If there is not annotation, fast exist.
}
System.out.println("Processing @Trace annotations...");
try {
generateTraceFile(annotatedElements);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return true;
}
@Override
public void init(ProcessingEnvironment processingEnvironment) {
super.init(processingEnvironment);
// get messager for printing errors
messager = processingEnvironment.getMessager();
}
private Set<? extends Element> getTraceAnnotatedElements(RoundEnvironment roundEnv) {
return roundEnv.getElementsAnnotatedWith(Trace.class);
}
private void generateTraceFile(Set<? extends Element> annotatedElements) throws FileNotFoundException {
PrintWriter out = new PrintWriter(DEFAULT_FILE_PATH + DEFAULT_FILE_NAME);
System.out.println("Annotated elements with @Trace: " + annotatedElements.size());
for (Element element : annotatedElements) {
if (element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.METHOD) {
String key = element.getAnnotation(Trace.class).key();
int step = element.getAnnotation(Trace.class).step();
if(element.getKind() == ElementKind.METHOD) {
String className = ((TypeElement) element.getEnclosingElement()).getQualifiedName().toString();
String methodName = element.getSimpleName().toString();
System.out.println("Add " + element.getKind().name() + " with key: " + key + " step: " + step + " class: " + className + " method: " + methodName);
out.print(key + ";" + step + ";" + className + "." + methodName);
} else {
String packageName = ((Symbol) element).getQualifiedName().toString();
String className = packageName + "." + element.getSimpleName().toString();
System.out.println("Add " + element.getKind().name() + " with key: " + key + " step: " + step + " class: " + className);
out.print(key + ";" + step + ";" + className);
}
out.println();
}
}
out.println();
out.close();
System.out.println("File trazability generated into target folder");
}
private void printError(Element element, String message) {
messager.printMessage(Diagnostic.Kind.ERROR, message, element);
}
}
Scala
import com.custom.annotations.Trace
@Trace(key = "ECI-12")
class Simulation1 extends Simulation {}
When I use the java annotation into a Java source then the Trace annotation is processed by TraceProcessor and a file is generated. But when I do the same with Scala it doesn't work.
Upvotes: 1
Views: 1967
Reputation: 962
Usage of java annotations in scala code can lead to unpredictable results, most of them just simply won't work. Please don't use them in your Scala code, because by doing so you draw hate from both Java and Scala guys. Fusing your favorite libraries from java world with scala not yields you the best you can get from scala but raises a bunch of problems that are rarely considered on different resources. Scala has its own ecosystem, and it is better to avoid using java libraries as long you can solve problem with scala library even if you super proficient with java.
Java annotations commonly used to shave off boilerplate that is enforced by java verbose syntax and poor type system. Scala has own metaprogramming framework (blackbox macro, whitebox macro, macro annotations and implicit macro) and many other abstraction stuff such as potent type system with HKT and omnipotent implicit search mechanism. So, you definitely don't need macro annotations for most of the cases.
Moreover for your problem could exist a scala solution. Someone can find it for you if you decide to describe the problem rather than bring a wall of code instead.
Upvotes: 2
Reputation: 7604
The Java annotation will only work with Java compilers since the processor needs to work with the Java AST. You must write your own macro annotation for Scala, which uses a compiler incompatible with Java's annotation processors. See here: https://docs.scala-lang.org/overviews/macros/annotations.html
Upvotes: 0