desseim
desseim

Reputation: 8248

Why does Android classloader allow reflective access to the public field of a package-private class from another package?

It seems that the Android application class loader allows to reflectively acquire a reference to the public static field of a package-private class even from a different package (than the one the aforementioned class is defined in), while Sun JDK classloader for example doesn't.

More concretely, given the following class definition:

package org.example.a

class PackagePrivateClass {
    public static final Parcelable.Creator<PackagePrivateClass> CREATOR = generateCreator();
}

And the following code in a separate package:

package org.example.b

public class TestClass {
    public void testMethod() {
        final Class classRef = Class.forName("org.example.a.PackagePrivateClass");
        final Field creatorFieldRef = classRef.getField("CREATOR");
        creatorFieldRef.get(null);  // throws here (unless on Android)
    }
}

When executed on Sun JVM it throws an IllegalAccessException on the last line:

java.lang.IllegalAccessException: Class org.example.b.TestClass can not access a member of class org.example.a.PackagePrivateClass with modifiers "public static final"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)
...

However, when run on an Android device (5.1 Lollipop FWIW) it executes without throwing and creatorFieldRef.get(null) actually returns a valid reference to the CREATOR field.

My question is : why is it the case ? Is it a bug or a feature of the Android classloader ?? (or, if applicable, what did I get wrong in my example ?)

Upvotes: 10

Views: 434

Answers (1)

wero
wero

Reputation: 33000

Seems that it is a bug in the android runtime which was fixed in this commit:

Add access checks to Method and Field reflection.

Prior to this commit it was possible to access fields via reflection in an unrestricted way or even set the value of final fields.

The access check is now implemented in the runtime functions ValidateFieldAccess and ValidateAccess.

Upvotes: 2

Related Questions