Skip to content

Commit bcf27ae

Browse files
author
Christian Wimmer
committed
Remove GuardedAnnotationAccess and DirectAnnotationAccess
1 parent 7eb73c1 commit bcf27ae

File tree

15 files changed

+104
-364
lines changed

15 files changed

+104
-364
lines changed

sdk/mx.sdk/suite.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -437,7 +437,7 @@
437437
"org.graalvm.word",
438438
"org.graalvm.polyglot.impl to org.graalvm.truffle, com.oracle.graal.graal_enterprise",
439439
"org.graalvm.word.impl to jdk.internal.vm.compiler",
440-
"org.graalvm.nativeimage.impl to org.graalvm.nativeimage.builder,org.graalvm.nativeimage.configure,com.oracle.svm.svm_enterprise",
440+
"org.graalvm.nativeimage.impl to org.graalvm.nativeimage.base,org.graalvm.nativeimage.builder,org.graalvm.nativeimage.configure,com.oracle.svm.svm_enterprise",
441441
"org.graalvm.nativeimage.impl.clinit to org.graalvm.nativeimage.builder",
442442
],
443443
"uses" : [

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/AnnotationAccess.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
import java.lang.reflect.AnnotatedElement;
4545
import java.util.Arrays;
4646

47-
import org.graalvm.nativeimage.impl.ImageBuildtimeCodeAnnotationAccessSupport;
47+
import org.graalvm.nativeimage.impl.AnnotationExtracter;
4848

4949
/**
5050
* This class provides methods to query annotation information on {@link AnnotatedElement}s while
@@ -79,7 +79,7 @@ public final class AnnotationAccess {
7979
*/
8080
public static boolean isAnnotationPresent(AnnotatedElement element, Class<? extends Annotation> annotationClass) {
8181
if (ImageInfo.inImageBuildtimeCode()) {
82-
return ImageSingletons.lookup(ImageBuildtimeCodeAnnotationAccessSupport.class).isAnnotationPresent(element, annotationClass);
82+
return ImageSingletons.lookup(AnnotationExtracter.class).hasAnnotation(element, annotationClass);
8383
} else {
8484
return element.isAnnotationPresent(annotationClass);
8585
}
@@ -93,7 +93,7 @@ public static boolean isAnnotationPresent(AnnotatedElement element, Class<? exte
9393
@SuppressWarnings("unchecked")
9494
public static <T extends Annotation> T getAnnotation(AnnotatedElement element, Class<T> annotationType) {
9595
if (ImageInfo.inImageBuildtimeCode()) {
96-
return (T) ImageSingletons.lookup(ImageBuildtimeCodeAnnotationAccessSupport.class).getAnnotation(element, annotationType);
96+
return ImageSingletons.lookup(AnnotationExtracter.class).extractAnnotation(element, annotationType, false);
9797
} else {
9898
return element.getAnnotation(annotationType);
9999
}
@@ -107,7 +107,7 @@ public static <T extends Annotation> T getAnnotation(AnnotatedElement element, C
107107
@SuppressWarnings("unchecked")
108108
public static Class<? extends Annotation>[] getAnnotationTypes(AnnotatedElement element) {
109109
if (ImageInfo.inImageBuildtimeCode()) {
110-
return ImageSingletons.lookup(ImageBuildtimeCodeAnnotationAccessSupport.class).getAnnotationTypes(element);
110+
return ImageSingletons.lookup(AnnotationExtracter.class).getAnnotationTypes(element);
111111
} else {
112112
return Arrays.stream(element.getAnnotations()).map(Annotation::annotationType).toArray(Class[]::new);
113113
}
Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,12 +43,14 @@
4343
import java.lang.annotation.Annotation;
4444
import java.lang.reflect.AnnotatedElement;
4545

46-
public interface ImageBuildtimeCodeAnnotationAccessSupport {
47-
// needed as Annotation Access-specific ImageSingletons key
46+
import org.graalvm.nativeimage.Platform;
47+
import org.graalvm.nativeimage.Platforms;
4848

49-
boolean isAnnotationPresent(AnnotatedElement element, Class<? extends Annotation> annotationClass);
49+
@Platforms(Platform.HOSTED_ONLY.class)
50+
public interface AnnotationExtracter {
51+
boolean hasAnnotation(AnnotatedElement element, Class<? extends Annotation> annotationType);
5052

51-
Annotation getAnnotation(AnnotatedElement element, Class<? extends Annotation> annotationType);
53+
<T extends Annotation> T extractAnnotation(AnnotatedElement element, Class<T> annotationType, boolean declaredOnly);
5254

5355
Class<? extends Annotation>[] getAnnotationTypes(AnnotatedElement element);
5456
}

substratevm/src/com.oracle.svm.core/.checkstyle_checks.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,15 @@
66
<module name="TreeWalker">
77

88
<!-- Disallows direct calls to "AnnotatedElement.get(Declared)Annotation(s)". This check can yield false positives,
9-
i.e., it will match any ".get(Declared)Annotation(s)" calls that are not preceded by "GuardedAnnotationAccess"
9+
i.e., it will match any ".get(Declared)Annotation(s)" calls that are not preceded by "AnnotationAccess"
1010
since checkstyle relies only on pattern matching and it cannot determine the type of the call's receiver object.
1111
-->
1212
<module name="RegexpSinglelineJava">
1313
<property name="id" value="annotationAccess"/>
1414
<metadata name="net.sf.eclipsecs.core.comment" value="Disallow calls to AnnotatedElement.get(Declared)Annotation(s)."/>
1515
<property name="severity" value="error"/>
1616
<property name="format" value="(?&lt;!AnnotationAccess)\.(getAnnotation|getAnnotations|getDeclaredAnnotation|getDeclaredAnnotations|isAnnotationPresent)\b"/>
17-
<property name="message" value="Direct calls to java.lang.reflect.AnnotatedElement.get(Declared)Annotation(s) are restricted. Use either com.oracle.svm.util.GuardedAnnotationAccess or com.oracle.svm.util.DirectAnnotationAccess methods. (Use &quot;// Checkstyle: allow direct annotation access... // Checkstyle: disallow direct annotation access&quot; to disable this check.)"/>
17+
<property name="message" value="Direct calls to java.lang.reflect.AnnotatedElement.get(Declared)Annotation(s) are restricted. Use org.graalvm.nativeimage.AnnotationAccess methods. (Use &quot;// Checkstyle: allow direct annotation access... // Checkstyle: disallow direct annotation access&quot; to disable this check.)"/>
1818
<property name="ignoreComments" value="true"/>
1919
</module>
2020
<module name="SuppressionCommentFilter">

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/ImageClassLoader.java

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@
5151

5252
import com.oracle.svm.core.SubstrateOptions;
5353
import com.oracle.svm.core.TypeResult;
54-
import com.oracle.svm.util.GuardedAnnotationAccess;
5554
import com.oracle.svm.util.ReflectionUtil;
5655

5756
public final class ImageClassLoader {
@@ -143,7 +142,7 @@ private void findSystemElements(Class<?> systemClass) {
143142

144143
private boolean isInPlatform(AnnotatedElement element) {
145144
try {
146-
Platforms platformAnnotation = GuardedAnnotationAccess.getAnnotation(classLoaderSupport.annotationExtracter, element, Platforms.class);
145+
Platforms platformAnnotation = classLoaderSupport.annotationExtracter.extractAnnotation(element, Platforms.class, false);
147146
return NativeImageGenerator.includedIn(platform, platformAnnotation);
148147
} catch (Throwable t) {
149148
handleClassLoadingError(t);
@@ -176,7 +175,7 @@ void handleClass(Class<?> clazz) {
176175
do {
177176
Platforms platformsAnnotation;
178177
try {
179-
platformsAnnotation = GuardedAnnotationAccess.getAnnotation(classLoaderSupport.annotationExtracter, cur, Platforms.class);
178+
platformsAnnotation = classLoaderSupport.annotationExtracter.extractAnnotation(cur, Platforms.class, false);
180179
} catch (Throwable t) {
181180
handleClassLoadingError(t);
182181
return;
@@ -374,7 +373,7 @@ public List<Class<?>> findAnnotatedClasses(Class<? extends Annotation> annotatio
374373

375374
private void addAnnotatedClasses(EconomicSet<Class<?>> classes, Class<? extends Annotation> annotationClass, ArrayList<Class<?>> result) {
376375
for (Class<?> systemClass : classes) {
377-
if (GuardedAnnotationAccess.isAnnotationPresent(classLoaderSupport.annotationExtracter, systemClass, annotationClass)) {
376+
if (classLoaderSupport.annotationExtracter.hasAnnotation(systemClass, annotationClass)) {
378377
result.add(systemClass);
379378
}
380379
}
@@ -383,7 +382,7 @@ private void addAnnotatedClasses(EconomicSet<Class<?>> classes, Class<? extends
383382
public List<Method> findAnnotatedMethods(Class<? extends Annotation> annotationClass) {
384383
ArrayList<Method> result = new ArrayList<>();
385384
for (Method method : systemMethods) {
386-
if (GuardedAnnotationAccess.isAnnotationPresent(classLoaderSupport.annotationExtracter, method, annotationClass)) {
385+
if (classLoaderSupport.annotationExtracter.hasAnnotation(method, annotationClass)) {
387386
result.add(method);
388387
}
389388
}
@@ -395,7 +394,7 @@ public List<Method> findAnnotatedMethods(Class<? extends Annotation>[] annotatio
395394
for (Method method : systemMethods) {
396395
boolean match = true;
397396
for (Class<? extends Annotation> annotationClass : annotationClasses) {
398-
if (!GuardedAnnotationAccess.isAnnotationPresent(classLoaderSupport.annotationExtracter, method, annotationClass)) {
397+
if (!classLoaderSupport.annotationExtracter.hasAnnotation(method, annotationClass)) {
399398
match = false;
400399
break;
401400
}
@@ -410,7 +409,7 @@ public List<Method> findAnnotatedMethods(Class<? extends Annotation>[] annotatio
410409
public List<Field> findAnnotatedFields(Class<? extends Annotation> annotationClass) {
411410
ArrayList<Field> result = new ArrayList<>();
412411
for (Field field : systemFields) {
413-
if (GuardedAnnotationAccess.isAnnotationPresent(classLoaderSupport.annotationExtracter, field, annotationClass)) {
412+
if (classLoaderSupport.annotationExtracter.hasAnnotation(field, annotationClass)) {
414413
result.add(field);
415414
}
416415
}
@@ -432,13 +431,13 @@ public List<Class<? extends Annotation>> allAnnotations() {
432431
public <T extends Annotation> List<T> findAnnotations(Class<T> annotationClass) {
433432
List<T> result = new ArrayList<>();
434433
for (Class<?> clazz : findAnnotatedClasses(annotationClass, false)) {
435-
result.add(GuardedAnnotationAccess.getAnnotation(classLoaderSupport.annotationExtracter, clazz, annotationClass));
434+
result.add(classLoaderSupport.annotationExtracter.extractAnnotation(clazz, annotationClass, false));
436435
}
437436
for (Method method : findAnnotatedMethods(annotationClass)) {
438-
result.add(GuardedAnnotationAccess.getAnnotation(classLoaderSupport.annotationExtracter, method, annotationClass));
437+
result.add(classLoaderSupport.annotationExtracter.extractAnnotation(method, annotationClass, false));
439438
}
440439
for (Field field : findAnnotatedFields(annotationClass)) {
441-
result.add(GuardedAnnotationAccess.getAnnotation(classLoaderSupport.annotationExtracter, field, annotationClass));
440+
result.add(classLoaderSupport.annotationExtracter.extractAnnotation(field, annotationClass, false));
442441
}
443442
return result;
444443
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageClassLoaderSupport.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@
7676
import org.graalvm.collections.Pair;
7777
import org.graalvm.compiler.options.OptionKey;
7878
import org.graalvm.compiler.options.OptionValues;
79+
import org.graalvm.nativeimage.impl.AnnotationExtracter;
7980

8081
import com.oracle.svm.core.SubstrateOptions;
8182
import com.oracle.svm.core.option.LocatableMultiOptionValue;
@@ -87,7 +88,6 @@
8788
import com.oracle.svm.core.util.VMError;
8889
import com.oracle.svm.hosted.annotation.SubstrateAnnotationExtracter;
8990
import com.oracle.svm.hosted.option.HostedOptionParser;
90-
import com.oracle.svm.util.AnnotationExtracter;
9191
import com.oracle.svm.util.ModuleSupport;
9292
import com.oracle.svm.util.ReflectionUtil;
9393

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/NativeImageGenerator.java

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -125,8 +125,8 @@
125125
import org.graalvm.nativeimage.c.struct.RawStructure;
126126
import org.graalvm.nativeimage.hosted.Feature;
127127
import org.graalvm.nativeimage.hosted.Feature.OnAnalysisExitAccess;
128+
import org.graalvm.nativeimage.impl.AnnotationExtracter;
128129
import org.graalvm.nativeimage.impl.CConstantValueSupport;
129-
import org.graalvm.nativeimage.impl.ImageBuildtimeCodeAnnotationAccessSupport;
130130
import org.graalvm.nativeimage.impl.RuntimeClassInitializationSupport;
131131
import org.graalvm.nativeimage.impl.SizeOfSupport;
132132
import org.graalvm.nativeimage.impl.clinit.ClassInitializationTracking;
@@ -251,7 +251,6 @@
251251
import com.oracle.svm.hosted.analysis.SVMAnalysisMetaAccess;
252252
import com.oracle.svm.hosted.analysis.SubstrateUnsupportedFeatures;
253253
import com.oracle.svm.hosted.annotation.AnnotationSupport;
254-
import com.oracle.svm.hosted.annotation.ImageBuildtimeCodeAnnotationAccessSupportSingleton;
255254
import com.oracle.svm.hosted.c.CAnnotationProcessorCache;
256255
import com.oracle.svm.hosted.c.CConstantValueSupportImpl;
257256
import com.oracle.svm.hosted.c.NativeLibraries;
@@ -300,7 +299,6 @@
300299
import com.oracle.svm.hosted.substitute.AnnotationSubstitutionProcessor;
301300
import com.oracle.svm.hosted.substitute.DeletedFieldsPlugin;
302301
import com.oracle.svm.hosted.substitute.UnsafeAutomaticSubstitutionProcessor;
303-
import com.oracle.svm.util.AnnotationExtracter;
304302
import com.oracle.svm.util.ClassUtil;
305303
import com.oracle.svm.util.ImageBuildStatistics;
306304
import com.oracle.svm.util.ReflectionUtil;
@@ -527,7 +525,6 @@ public void run(Map<Method, CEntryPointData> entryPoints,
527525
ImageSingletons.add(TimerCollection.class, timerCollection);
528526
ImageSingletons.add(ImageBuildStatistics.TimerCollectionPrinter.class, timerCollection);
529527
ImageSingletons.add(AnnotationExtracter.class, loader.classLoaderSupport.annotationExtracter);
530-
ImageSingletons.add(ImageBuildtimeCodeAnnotationAccessSupport.class, new ImageBuildtimeCodeAnnotationAccessSupportSingleton());
531528
ImageSingletons.add(BuildArtifacts.class, (type, artifact) -> buildArtifacts.computeIfAbsent(type, t -> new ArrayList<>()).add(artifact));
532529
ImageSingletons.add(HostedOptionValues.class, new HostedOptionValues(optionProvider.getHostedValues()));
533530
ImageSingletons.add(RuntimeOptionValues.class, new RuntimeOptionValues(optionProvider.getRuntimeValues(), allOptionNames));

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/ImageBuildtimeCodeAnnotationAccessSupportSingleton.java

Lines changed: 0 additions & 57 deletions
This file was deleted.

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/annotation/SubstrateAnnotationExtracter.java

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,11 @@
4141
import java.util.concurrent.ConcurrentHashMap;
4242

4343
import org.graalvm.compiler.debug.GraalError;
44+
import org.graalvm.nativeimage.AnnotationAccess;
45+
import org.graalvm.nativeimage.impl.AnnotationExtracter;
4446

4547
import com.oracle.svm.hosted.annotation.AnnotationMetadata.AnnotationExtractionError;
46-
import com.oracle.svm.util.AnnotationExtracter;
4748
import com.oracle.svm.util.AnnotationWrapper;
48-
import com.oracle.svm.util.GuardedAnnotationAccess;
4949
import com.oracle.svm.util.ReflectionUtil;
5050

5151
import jdk.internal.reflect.ConstantPool;
@@ -71,8 +71,8 @@
7171
* subclass of {@link AnnotationMemberValue}. The actual annotation can then be created using the
7272
* {@link AnnotationMemberValue#get(Class)} method.
7373
*
74-
* The {@link SubstrateAnnotationExtracter} is tightly coupled with {@link GuardedAnnotationAccess},
75-
* which provides implementations of {@link AnnotatedElement#isAnnotationPresent(Class)} and
74+
* The {@link SubstrateAnnotationExtracter} is tightly coupled with {@link AnnotationAccess}, which
75+
* provides implementations of {@link AnnotatedElement#isAnnotationPresent(Class)} and
7676
* {@link AnnotatedElement#getAnnotation(Class)}. {@link AnnotatedElement#getAnnotations()} should
7777
* in principle not be used during Native Image generation.
7878
*/
@@ -163,22 +163,43 @@ public class SubstrateAnnotationExtracter implements AnnotationExtracter {
163163
@SuppressWarnings("unchecked")
164164
@Override
165165
public <T extends Annotation> T extractAnnotation(AnnotatedElement element, Class<T> annotationType, boolean declaredOnly) {
166-
for (AnnotationValue annotation : getAnnotationData(element, declaredOnly)) {
167-
if (annotation.type != null && annotation.type.equals(annotationType)) {
168-
return (T) resolvedAnnotationsCache.computeIfAbsent(annotation, value -> (Annotation) value.get(annotationType));
166+
try {
167+
for (AnnotationValue annotation : getAnnotationData(element, declaredOnly)) {
168+
if (annotation.type != null && annotation.type.equals(annotationType)) {
169+
return (T) resolvedAnnotationsCache.computeIfAbsent(annotation, value -> (Annotation) value.get(annotationType));
170+
}
169171
}
172+
return null;
173+
} catch (LinkageError e) {
174+
/*
175+
* Returning null essentially means that the element doesn't declare the annotationType,
176+
* but we cannot know that since the annotation parsing failed. However, this allows us
177+
* to defend against crashing the image builder if the user code references types
178+
* missing from the classpath.
179+
*/
180+
return null;
170181
}
171-
return null;
182+
172183
}
173184

174185
@Override
175186
public boolean hasAnnotation(AnnotatedElement element, Class<? extends Annotation> annotationType) {
176-
for (AnnotationValue annotation : getAnnotationData(element, false)) {
177-
if (annotation.type != null && annotation.type.equals(annotationType)) {
178-
return true;
187+
try {
188+
for (AnnotationValue annotation : getAnnotationData(element, false)) {
189+
if (annotation.type != null && annotation.type.equals(annotationType)) {
190+
return true;
191+
}
179192
}
193+
return false;
194+
} catch (LinkageError e) {
195+
/*
196+
* Returning false essentially means that the element doesn't declare the
197+
* annotationType, but we cannot know that since the annotation parsing failed. However,
198+
* this allows us to defend against crashing the image builder if the user code
199+
* references types missing from the classpath.
200+
*/
201+
return false;
180202
}
181-
return false;
182203
}
183204

184205
@SuppressWarnings("unchecked")

0 commit comments

Comments
 (0)