jOOQ / jOOR

jOOR - Fluent Reflection in Java jOOR is a very simple fluent API that gives access to your Java Class structures in a more intuitive way. The JDK's reflection APIs are hard and verbose to use. Other languages have much simpler constructs to access type meta information at runtime. Let us make Java reflection better.
http://www.jooq.org/products
Apache License 2.0
2.81k stars 376 forks source link

java.lang.NoSuchFieldException: modifiers on Reflect.set() on Android #48

Closed kigkrazy closed 6 years ago

kigkrazy commented 6 years ago

Expected behavior and actual behavior:

Reflect.on(httpUrl).set("a", "http");

Steps to reproduce the problem:

org.joor.ReflectException: java.lang.NoSuchFieldException: modifiers

Versions:

====

I found the problem in the code :

    public Reflect set(String name, Object value) throws ReflectException {
        try {
            Field field = field0(name);
            if ((field.getModifiers() & Modifier.FINAL) == Modifier.FINAL) {
                Field modifiersField = Field.class.getDeclaredField("modifiers");//android system don't have this field.
                modifiersField.setAccessible(true);
                modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
            }
            field.set(object, unwrap(value));
            return this;
        }
        catch (Exception e) {
            throw new ReflectException(e);
        }
    }
lukaseder commented 6 years ago

Thanks for your report. How can this be done on Android? Ideally, if you could provide a working PR, that would be awesome. I cannot verify this on Android right now...

kigkrazy commented 6 years ago

I'm sorry to see it now. I solve problem with that code:

    public Reflect set(String name, Object value) throws ReflectException {
        try {
            Field field = field0(name);
            //fix by KigKrazy
            // in anddroid, there is not "modifiers" field.
//            if ((field.getModifiers() & Modifier.FINAL) == Modifier.FINAL) {
//                Field modifiersField = Field.class.getDeclaredField("modifiers");
//                modifiersField.setAccessible(true);
//                modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
//            }
            field.set(object, unwrap(value));
            return this;
        }
        catch (Exception e) {
            throw new ReflectException(e);
        }
    }

my english is not good, hope U can understand.

I don't test in other platform, so there are no PR.

lukaseder commented 6 years ago

I see, so we could wrap the contents of that if statement in a try-catch-ignore block, but then does setting the field still work if it's final, in android?

lukaseder commented 6 years ago

I've committed a fix to GitHub master, due for jOOQ 0.9.8. Would you mind checking if this fixes the issue for you?