javac should emit a warning if an annotation processor generates a class that overwrites/overrides a class that is present on the classpath or sourcepath.
Using annotation processing to redefine a symbol on the classpath or sourcepath allows other annotation processors to see different well-formed definitions of the same symbol during different processing rounds of a single compilation.
Related:
* TODO in JavacFiler: http://hg.openjdk.java.net/jdk/jdk/file/a9405d9ca8a8/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java#l715
* compiler-dev thread: http://mail.openjdk.java.net/pipermail/compiler-dev/2017-December/011403.html
Demo:
=== ./P.java
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOError;
import java.io.IOException;
import java.io.OutputStream;
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.TypeElement;
@SupportedAnnotationTypes("*")
public class P extends AbstractProcessor {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
private int round = 0;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
round++;
TypeElement a = processingEnv.getElementUtils().getTypeElement("A");
System.err.println(
"round " + round + ", a has annotations: [" + a.getAnnotationMirrors() + "]");
if (round == 1) {
try (OutputStream os = processingEnv.getFiler().createSourceFile("A").openOutputStream()) {
os.write("class A {}".getBytes(UTF_8));
} catch (IOException e) {
throw new IOError(e);
}
}
return false;
}
}
=== ./A.java
@Deprecated
class A {}
=== ./B.java
class B {
A a;
}
===
$ javac A.java
$ javac -sourcepath : -processor P B.java -s gensource
round 1, a has annotations: [@java.lang.Deprecated]
round 2, a has annotations: []
round 3, a has annotations: []
Using annotation processing to redefine a symbol on the classpath or sourcepath allows other annotation processors to see different well-formed definitions of the same symbol during different processing rounds of a single compilation.
Related:
* TODO in JavacFiler: http://hg.openjdk.java.net/jdk/jdk/file/a9405d9ca8a8/src/jdk.compiler/share/classes/com/sun/tools/javac/processing/JavacFiler.java#l715
* compiler-dev thread: http://mail.openjdk.java.net/pipermail/compiler-dev/2017-December/011403.html
Demo:
=== ./P.java
import static java.nio.charset.StandardCharsets.UTF_8;
import java.io.IOError;
import java.io.IOException;
import java.io.OutputStream;
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.TypeElement;
@SupportedAnnotationTypes("*")
public class P extends AbstractProcessor {
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latestSupported();
}
private int round = 0;
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
round++;
TypeElement a = processingEnv.getElementUtils().getTypeElement("A");
System.err.println(
"round " + round + ", a has annotations: [" + a.getAnnotationMirrors() + "]");
if (round == 1) {
try (OutputStream os = processingEnv.getFiler().createSourceFile("A").openOutputStream()) {
os.write("class A {}".getBytes(UTF_8));
} catch (IOException e) {
throw new IOError(e);
}
}
return false;
}
}
=== ./A.java
@Deprecated
class A {}
=== ./B.java
class B {
A a;
}
===
$ javac A.java
$ javac -sourcepath : -processor P B.java -s gensource
round 1, a has annotations: [@java.lang.Deprecated]
round 2, a has annotations: []
round 3, a has annotations: []
- csr for
-
JDK-8193576 Filer should warn if processors redefine symbols from the classpath or sourcepath
-
- Closed
-