Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8085321 | emb-9 | Jan Lahoda | P4 | Resolved | Fixed | team |
FULL PRODUCT VERSION :
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) Client VM (build 25.25-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
If an annotation processor call Messager.printMessage with the kind Diagnostic.Kind.ERROR more than once for the same source position only the first message is reported. This occurs only if both messages have the same source location, as determined by the Element and other arguments to printMessage.
It appears that it was intended to allow multiple messages because in the source code of JavacMessager.java I have observed this at line 112:
log.multipleErrors = true;
try {
log.error(pos, "proc.messager", msg.toString());
} finally {
log.multipleErrors = prev;
}
It appears that this is ineffective because the diagnostics are deferred and the multipleErrors flag is false when the diagnostics are replayed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Write code that will call printMessage with an error for the same element more than once. In the output, only the first message is reported. This also applies if invoking javac through the ToolProvider interface using a DiagnosticCollector.
Option 1: Using javac through tools API:
1.1. Compile Proc.java
1.2. Execute Proc using JDK
Option 2: Using javac through command line:
2.1. javac Proc.java
2.2. javac -processor Proc Proc.java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
oops 1
oops 2
ACTUAL -
oops 1
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.annotation.processing.*;
import javax.tools.Diagnostic.Kind;
import javax.lang.model.SourceVersion;
import java.util.Set;
import javax.lang.model.element.TypeElement;
import javax.tools.*;
import java.util.Arrays;
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class Proc extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> ann, RoundEnvironment re) {
TypeElement procTe = processingEnv.getElementUtils().getTypeElement("Proc");
processingEnv.getMessager().printMessage(Kind.ERROR, "oops 1", procTe);
processingEnv.getMessager().printMessage(Kind.ERROR, "oops 2", procTe);
return false;
}
public static void main(String[] args) {
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileman = javac.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> sourceFiles = fileman.getJavaFileObjects("Proc.java");
DiagnosticCollector<JavaFileObject> diagCollector = new DiagnosticCollector<JavaFileObject>();
JavaCompiler.CompilationTask task = javac.getTask(null, fileman, diagCollector, null, null, sourceFiles);
task.setProcessors(Arrays.asList(new Proc()));
task.call();
for (Diagnostic<?> diag : diagCollector.getDiagnostics()) {
System.out.println(diag.getMessage(null));
}
}
}
---------- END SOURCE ----------
java version "1.8.0_25"
Java(TM) SE Runtime Environment (build 1.8.0_25-b18)
Java HotSpot(TM) Client VM (build 25.25-b02, mixed mode, sharing)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
If an annotation processor call Messager.printMessage with the kind Diagnostic.Kind.ERROR more than once for the same source position only the first message is reported. This occurs only if both messages have the same source location, as determined by the Element and other arguments to printMessage.
It appears that it was intended to allow multiple messages because in the source code of JavacMessager.java I have observed this at line 112:
log.multipleErrors = true;
try {
log.error(pos, "proc.messager", msg.toString());
} finally {
log.multipleErrors = prev;
}
It appears that this is ineffective because the diagnostics are deferred and the multipleErrors flag is false when the diagnostics are replayed.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Write code that will call printMessage with an error for the same element more than once. In the output, only the first message is reported. This also applies if invoking javac through the ToolProvider interface using a DiagnosticCollector.
Option 1: Using javac through tools API:
1.1. Compile Proc.java
1.2. Execute Proc using JDK
Option 2: Using javac through command line:
2.1. javac Proc.java
2.2. javac -processor Proc Proc.java
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
oops 1
oops 2
ACTUAL -
oops 1
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import javax.annotation.processing.*;
import javax.tools.Diagnostic.Kind;
import javax.lang.model.SourceVersion;
import java.util.Set;
import javax.lang.model.element.TypeElement;
import javax.tools.*;
import java.util.Arrays;
@SupportedAnnotationTypes("*")
@SupportedSourceVersion(SourceVersion.RELEASE_8)
public class Proc extends AbstractProcessor {
public boolean process(Set<? extends TypeElement> ann, RoundEnvironment re) {
TypeElement procTe = processingEnv.getElementUtils().getTypeElement("Proc");
processingEnv.getMessager().printMessage(Kind.ERROR, "oops 1", procTe);
processingEnv.getMessager().printMessage(Kind.ERROR, "oops 2", procTe);
return false;
}
public static void main(String[] args) {
JavaCompiler javac = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileman = javac.getStandardFileManager(null, null, null);
Iterable<? extends JavaFileObject> sourceFiles = fileman.getJavaFileObjects("Proc.java");
DiagnosticCollector<JavaFileObject> diagCollector = new DiagnosticCollector<JavaFileObject>();
JavaCompiler.CompilationTask task = javac.getTask(null, fileman, diagCollector, null, null, sourceFiles);
task.setProcessors(Arrays.asList(new Proc()));
task.call();
for (Diagnostic<?> diag : diagCollector.getDiagnostics()) {
System.out.println(diag.getMessage(null));
}
}
}
---------- END SOURCE ----------
- backported by
-
JDK-8085321 Messager.printMessage cannot print multiple errors for same source position
-
- Resolved
-
- duplicates
-
JDK-8168043 JavacTrees never allows multiple error messages on the same tree
-
- Closed
-
- relates to
-
JDK-8068512 Enhance Messager.printMessage API to allow positioning within annotation value
-
- Open
-