Skip to content

Commit f0cf82f

Browse files
committed
Fix reflection metadata-related test failures
1 parent dbbe854 commit f0cf82f

File tree

10 files changed

+289
-80
lines changed

10 files changed

+289
-80
lines changed

sdk/src/org.graalvm.nativeimage/src/org/graalvm/nativeimage/impl/RuntimeReflectionSupport.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,11 @@ public interface RuntimeReflectionSupport extends ReflectionRegistry {
5656
Object getAccessor(Executable method);
5757

5858
/*
59-
* Returns the methods that shadow a superclass method registered for reflection, to be excluded
60-
* from reflection queries.
59+
* Returns the methods and fields that shadow a superclass element registered for reflection, to
60+
* be excluded from reflection queries.
6161
*/
62+
Set<?> getHidingReflectionFields();
63+
6264
Set<?> getHidingReflectionMethods();
6365

6466
Object[] getRecordComponents(Class<?> type);

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/hub/DynamicHub.java

Lines changed: 61 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import java.lang.reflect.Field;
4040
import java.lang.reflect.GenericDeclaration;
4141
import java.lang.reflect.InvocationTargetException;
42+
import java.lang.reflect.Member;
4243
import java.lang.reflect.Method;
4344
import java.lang.reflect.Modifier;
4445
import java.lang.reflect.Type;
@@ -49,6 +50,7 @@
4950
import java.util.Arrays;
5051
import java.util.Collection;
5152
import java.util.List;
53+
import java.util.Objects;
5254
import java.util.Optional;
5355
import java.util.StringJoiner;
5456

@@ -899,8 +901,20 @@ public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)
899901
@KeepOriginal
900902
private native Constructor<?>[] getConstructors();
901903

902-
@KeepOriginal
903-
private native Field getField(@SuppressWarnings("hiding") String name) throws NoSuchMethodException;
904+
@Substitute
905+
public Field getField(String fieldName) throws NoSuchFieldException, SecurityException {
906+
Objects.requireNonNull(fieldName);
907+
@SuppressWarnings("removal")
908+
SecurityManager sm = System.getSecurityManager();
909+
if (sm != null) {
910+
checkMemberAccess(sm, Member.PUBLIC, Reflection.getCallerClass(), true);
911+
}
912+
Field field = getField0(fieldName);
913+
if (field == null || ImageSingletons.lookup(ReflectionMetadataDecoder.class).isHiding(field.getModifiers())) {
914+
throw new NoSuchFieldException(fieldName);
915+
}
916+
return getReflectionFactory().copyField(field);
917+
}
904918

905919
@KeepOriginal
906920
private native Method getMethod(@SuppressWarnings("hiding") String name, Class<?>... parameterTypes) throws NoSuchMethodException;
@@ -923,8 +937,23 @@ public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)
923937
@KeepOriginal
924938
private native Constructor<?>[] getDeclaredConstructors();
925939

926-
@KeepOriginal
927-
private native Field getDeclaredField(@SuppressWarnings("hiding") String name);
940+
/**
941+
* @see #filterHidingFields(Field...)
942+
*/
943+
@Substitute
944+
public Field getDeclaredField(String fieldName) throws NoSuchFieldException, SecurityException {
945+
Objects.requireNonNull(fieldName);
946+
@SuppressWarnings("removal")
947+
SecurityManager sm = System.getSecurityManager();
948+
if (sm != null) {
949+
checkMemberAccess(sm, Member.DECLARED, Reflection.getCallerClass(), true);
950+
}
951+
Field field = searchFields(privateGetDeclaredFields(false), fieldName);
952+
if (field == null || ImageSingletons.lookup(ReflectionMetadataDecoder.class).isHiding(field.getModifiers())) {
953+
throw new NoSuchFieldException(fieldName);
954+
}
955+
return getReflectionFactory().copyField(field);
956+
}
928957

929958
@KeepOriginal
930959
private native Method getDeclaredMethod(@SuppressWarnings("hiding") String name, Class<?>... parameterTypes);
@@ -1009,8 +1038,19 @@ private static Method searchMethods(Method[] allMethods, String name, Class<?>[]
10091038
@KeepOriginal
10101039
private static native boolean arrayContentsEq(Object[] a1, Object[] a2);
10111040

1012-
@KeepOriginal
1013-
private static native Field[] copyFields(Field[] arg);
1041+
/**
1042+
* @see #filterHidingFields(Field...)
1043+
*/
1044+
@Substitute
1045+
private static Field[] copyFields(Field[] original) {
1046+
Field[] arg = filterHidingFields(original);
1047+
Field[] out = new Field[arg.length];
1048+
ReflectionFactory fact = getReflectionFactory();
1049+
for (int i = 0; i < arg.length; i++) {
1050+
out[i] = fact.copyField(arg[i]);
1051+
}
1052+
return out;
1053+
}
10141054

10151055
/**
10161056
* @see #filterHidingMethods(Method...)
@@ -1463,14 +1503,24 @@ private Class<?>[] getPermittedSubclasses0() {
14631503
private native boolean isDirectSubType(Class<?> c);
14641504

14651505
/*
1466-
* We need to filter out hiding methods at the last moment. This ensures that the JDK internals
1467-
* see them as regular methods and ensure the visibility of methods is correct, but they should
1468-
* not be returned to application code.
1506+
* We need to filter out hiding elements at the last moment. This ensures that the JDK internals
1507+
* see them as regular methods and fields and ensure their visibility is correct, but they
1508+
* should not be returned to application code.
14691509
*/
1510+
private static Field[] filterHidingFields(Field... fields) {
1511+
List<Field> filtered = new ArrayList<>();
1512+
for (Field field : fields) {
1513+
if (!ImageSingletons.lookup(ReflectionMetadataDecoder.class).isHiding(field.getModifiers())) {
1514+
filtered.add(field);
1515+
}
1516+
}
1517+
return filtered.toArray(new Field[0]);
1518+
}
1519+
14701520
private static Method[] filterHidingMethods(Method... methods) {
14711521
List<Method> filtered = new ArrayList<>();
14721522
for (Method method : methods) {
1473-
if (!ImageSingletons.lookup(ReflectionMetadataDecoder.class).isHidingMethod(method.getModifiers())) {
1523+
if (!ImageSingletons.lookup(ReflectionMetadataDecoder.class).isHiding(method.getModifiers())) {
14741524
filtered.add(method);
14751525
}
14761526
}
@@ -1687,7 +1737,7 @@ Method getMostSpecific() {
16871737
}
16881738
}
16891739
/* Filter out hiding methods after the retursive lookup is done */
1690-
return ImageSingletons.lookup(ReflectionMetadataDecoder.class).isHidingMethod(m.getModifiers()) ? null : m;
1740+
return ImageSingletons.lookup(ReflectionMetadataDecoder.class).isHiding(m.getModifiers()) ? null : m;
16911741
}
16921742
}
16931743

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/reflect/ReflectionMetadataDecoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ public interface ReflectionMetadataDecoder {
5151

5252
byte[] parseByteArray(int index);
5353

54-
boolean isHidingMethod(int modifiers);
54+
boolean isHiding(int modifiers);
5555

5656
long getMetadataByteLength();
5757
}

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/image/NativeImageCodeCache.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
import org.graalvm.word.WordFactory;
6161

6262
import com.oracle.graal.pointsto.BigBang;
63+
import com.oracle.graal.pointsto.meta.AnalysisField;
6364
import com.oracle.graal.pointsto.meta.AnalysisMethod;
6465
import com.oracle.objectfile.ObjectFile;
6566
import com.oracle.svm.core.SubstrateOptions;
@@ -282,6 +283,21 @@ public void buildRuntimeMetadata(CFunctionPointer firstMethod, UnsignedWord code
282283
}
283284
}
284285

286+
for (Object field : reflectionSupport.getHidingReflectionFields()) {
287+
AnalysisField hidingField = (AnalysisField) field;
288+
HostedField hostedField = hUniverse.optionalLookup(hidingField);
289+
if (hostedField == null || !includedFields.contains(hostedField)) {
290+
HostedType declaringType = hUniverse.lookup(hidingField.getDeclaringClass());
291+
String name = hidingField.getName();
292+
HostedType type = hUniverse.lookup(hidingField.getType());
293+
int modifiers = hidingField.getModifiers();
294+
reflectionMetadataEncoder.addHidingFieldMetadata(hidingField, declaringType, name, type, modifiers);
295+
if (hostedField != null) {
296+
includedFields.add(hostedField);
297+
}
298+
}
299+
}
300+
285301
for (Object method : reflectionSupport.getHidingReflectionMethods()) {
286302
AnalysisMethod hidingMethod = (AnalysisMethod) method;
287303
HostedMethod hostedMethod = hUniverse.optionalLookup(hidingMethod);
@@ -624,6 +640,8 @@ public interface ReflectionMetadataEncoder {
624640

625641
void addHeapAccessibleObjectMetadata(MetaAccessProvider metaAccess, AccessibleObject object);
626642

643+
void addHidingFieldMetadata(AnalysisField analysisField, HostedType declType, String name, HostedType type, int modifiers);
644+
627645
void addHidingMethodMetadata(AnalysisMethod analysisMethod, HostedType declType, String name, HostedType[] paramTypes, int modifiers, HostedType returnType);
628646

629647
void addReachableFieldMetadata(HostedField field);

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/lambda/LambdaSubstitutionType.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -399,7 +399,10 @@ public <T extends Annotation> T[] getAnnotationsByType(Class<T> annotationClass)
399399

400400
@Override
401401
public <T extends Annotation> T getDeclaredAnnotation(Class<T> annotationClass) {
402-
return original.getDeclaredAnnotation(annotationClass);
402+
if (annotationClass == LambdaFormHiddenMethod.class) {
403+
return annotationClass.cast(LambdaFormHiddenMethod.Holder.INSTANCE);
404+
}
405+
return null;
403406
}
404407

405408
@Override
@@ -409,7 +412,7 @@ public <T extends Annotation> T[] getDeclaredAnnotationsByType(Class<T> annotati
409412

410413
@Override
411414
public Annotation[] getDeclaredAnnotations() {
412-
return original.getDeclaredAnnotations();
415+
return LambdaFormHiddenMethod.Holder.ARRAY;
413416
}
414417

415418
public ResolvedJavaType getOriginal() {

substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/substitute/SubstitutionReflectivityFilter.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
import com.oracle.graal.pointsto.meta.AnalysisMethod;
3434
import com.oracle.graal.pointsto.meta.AnalysisUniverse;
3535
import com.oracle.svm.core.annotate.Delete;
36+
import com.oracle.svm.core.annotate.InjectAccessors;
3637
import com.oracle.svm.core.annotate.TargetClass;
3738

3839
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -86,7 +87,7 @@ public static boolean shouldExclude(Field field, AnalysisMetaAccess metaAccess,
8687
if (!universe.hostVM().platformSupported(aField)) {
8788
return true;
8889
}
89-
if (aField.isAnnotationPresent(Delete.class)) {
90+
if (aField.isAnnotationPresent(Delete.class) || aField.isAnnotationPresent(InjectAccessors.class)) {
9091
return true; // accesses would fail at runtime
9192
}
9293
} catch (UnsupportedFeatureException ignored) {

0 commit comments

Comments
 (0)