-1

I tried to follow this Change private static final field using Java reflection

But for some reason i get java.lang.IllegalAccessException: Can not set static final java.lang.Long field DataRepositoryTests.Item.id to java.lang.Integer

for (Field field : Table.getDeclaredFields()){

                    System.out.println(Table.getSimpleName()); //prints "Item"
                    
                    field.setAccessible(true);

                    if (field.getName().equals(GeneratedValueFields.get(i).getName())) { 

                        System.out.println(field.getName()); //prints "id"

                        Field modifiersField = Table.getDeclaredField(GeneratedValueFields.get(i).getName()); 

                        System.out.println(modifiersField.getName()); //prints "id" as expected

                        modifiersField.setAccessible(true);
                        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL); //error here

                        //data = 9 (Long)

                        field.set(null,data);


                    };

Now if i remove the line modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);

I get java.lang.IllegalAccessException: Can not set static final java.lang.Long field DataRepositoryTests.Item.id to java.lang.Long

If i change the field to just private final and specify a Object

field.set(TableModel,data);

It works properly

1 Answers1

0

The code in Change private static final field using Java reflection works in Java 1.8 but not in Java 17.

In Java 17 the jdk.internal.reflect.Reflection class contains a map of classes which should have some or all of their members made invisible to reflection:


    /** Used to filter out fields and methods from certain classes from public
        view, where they are sensitive or they may contain VM-internal objects.
        These Maps are updated very rarely. Rather than synchronize on
        each access, we use copy-on-write */
    private static volatile Map<Class<?>, Set<String>> fieldFilterMap;
    ...
    private static final String WILDCARD = "*";
    public static final Set<String> ALL_MEMBERS = Set.of(WILDCARD);

    static {
        fieldFilterMap = Map.of(
            Reflection.class, ALL_MEMBERS,
            ...
        );
        ...
    }

So the example will not work on newer JDKs.

This has been the case since Java 12: https://bugs.java.com/bugdatabase/view_bug.do?bug_id=8210496

tgdavies
  • 10,307
  • 4
  • 35
  • 40