Skip to content

Commit 1ad869f

Browse files
committed
8322706: AnnotationTypeMismatchException in javac with annotation processing
Reviewed-by: vromero
1 parent 7ffad35 commit 1ad869f

File tree

2 files changed

+168
-11
lines changed

2 files changed

+168
-11
lines changed

src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Annotate.java

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -187,17 +187,22 @@ public void flush() {
187187

188188
startFlushing();
189189
try {
190-
while (q.nonEmpty()) {
191-
q.next().run();
192-
}
193-
while (typesQ.nonEmpty()) {
194-
typesQ.next().run();
195-
}
196-
while (afterTypesQ.nonEmpty()) {
197-
afterTypesQ.next().run();
198-
}
199-
while (validateQ.nonEmpty()) {
200-
validateQ.next().run();
190+
while (q.nonEmpty() ||
191+
typesQ.nonEmpty() ||
192+
afterTypesQ.nonEmpty() ||
193+
validateQ.nonEmpty()) {
194+
while (q.nonEmpty()) {
195+
q.next().run();
196+
}
197+
while (typesQ.nonEmpty()) {
198+
typesQ.next().run();
199+
}
200+
while (afterTypesQ.nonEmpty()) {
201+
afterTypesQ.next().run();
202+
}
203+
while (validateQ.nonEmpty()) {
204+
validateQ.next().run();
205+
}
201206
}
202207
} finally {
203208
doneFlushing();
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/**
25+
* @test
26+
* @bug 8322706
27+
* @summary Verify that annotation values are de-proxies after loading from a classfile.
28+
* @library /tools/lib
29+
* @modules jdk.compiler/com.sun.tools.javac.api
30+
* jdk.compiler/com.sun.tools.javac.main
31+
* @build toolbox.JavacTask toolbox.ToolBox toolbox.Task
32+
* @run main TestAnnotationValuesResolved
33+
*/
34+
35+
import com.sun.source.tree.ClassTree;
36+
import com.sun.source.util.TaskEvent;
37+
import com.sun.source.util.TaskEvent.Kind;
38+
import com.sun.source.util.TaskListener;
39+
import com.sun.source.util.TreePathScanner;
40+
import com.sun.source.util.Trees;
41+
import java.nio.file.Files;
42+
import toolbox.*;
43+
44+
import java.nio.file.Path;
45+
import java.nio.file.Paths;
46+
import javax.lang.model.element.AnnotationMirror;
47+
import javax.lang.model.element.AnnotationValue;
48+
import javax.lang.model.element.Element;
49+
import javax.lang.model.util.Elements;
50+
import javax.lang.model.util.SimpleAnnotationValueVisitorPreview;
51+
52+
53+
public class TestAnnotationValuesResolved extends TestRunner {
54+
final toolbox.ToolBox tb = new ToolBox();
55+
56+
public TestAnnotationValuesResolved() {
57+
super(System.err);
58+
}
59+
60+
public static void main(String[] args) throws Exception {
61+
new TestAnnotationValuesResolved().runTests();
62+
}
63+
64+
protected void runTests() throws Exception {
65+
runTests(m -> new Object[] { Path.of(m.getName()) });
66+
}
67+
68+
@Test
69+
public void test(Path base) throws Exception {
70+
Path lib = Paths.get("lib");
71+
Path libSrc = lib.resolve("src");
72+
Path libClasses = lib.resolve("classes");
73+
74+
tb.writeJavaFiles(libSrc,
75+
"""
76+
package org.example;
77+
78+
public @interface MyFirstAnnotation {
79+
MySecondAnnotation secondAnnotation() default @MySecondAnnotation;
80+
}
81+
""",
82+
"""
83+
package org.example;
84+
85+
public @interface MySecondAnnotation {
86+
String[] stringArray() default "";
87+
}
88+
"""
89+
);
90+
Files.createDirectories(libClasses);
91+
new toolbox.JavacTask(tb)
92+
.outdir(libClasses)
93+
.files(tb.findJavaFiles(libSrc))
94+
.run();
95+
96+
Path test = Paths.get("test");
97+
Path testSrc = test.resolve("src");
98+
Path testClasses = test.resolve("classes");
99+
tb.writeJavaFiles(testSrc,
100+
"""
101+
package org.example;
102+
103+
@MyFirstAnnotation
104+
public class AnnotatedClass {
105+
}
106+
""");
107+
Files.createDirectories(testClasses);
108+
new toolbox.JavacTask(tb)
109+
.classpath(libClasses)
110+
.outdir(testClasses)
111+
.files(tb.findJavaFiles(testSrc))
112+
.callback(task -> {
113+
task.addTaskListener(new TaskListener() {
114+
@Override
115+
public void finished(TaskEvent e) {
116+
if (e.getKind() == Kind.ENTER) {
117+
new TreePathScanner<>() {
118+
@Override
119+
public Object visitClass(ClassTree node, Object p) {
120+
Trees trees = Trees.instance(task);
121+
Element el = trees.getElement(getCurrentPath());
122+
verifyAnnotationValuesResolved(task, el);
123+
return super.visitClass(node, p);
124+
}
125+
}.scan(e.getCompilationUnit(), null);
126+
}
127+
}
128+
});
129+
})
130+
.run()
131+
.writeAll();
132+
}
133+
134+
private void verifyAnnotationValuesResolved(com.sun.source.util.JavacTask task,
135+
Element forElement) {
136+
Elements elements = task.getElements();
137+
138+
class SearchAnnotationValues extends SimpleAnnotationValueVisitorPreview {
139+
@Override
140+
public Object visitAnnotation(AnnotationMirror a, Object p) {
141+
for (AnnotationValue av : elements.getElementValuesWithDefaults(a).values()) {
142+
av.accept(this, null);
143+
}
144+
return super.visitAnnotation(a, p);
145+
}
146+
}
147+
148+
for (AnnotationMirror mirror : forElement.getAnnotationMirrors()) {
149+
new SearchAnnotationValues().visitAnnotation(mirror, null);
150+
}
151+
}
152+
}

0 commit comments

Comments
 (0)