Aws-sdk-java: aws-core-sdk will not run without ReflectPermission "suppressAccessChecks"

Created on 7 Oct 2015  路  11Comments  路  Source: aws/aws-sdk-java

Currently the static initializer of InternalConfig$Factory uses jackson-databind to do "fancy" deserialization of a ton of configuration classes from a json file. These classes are not public / do not have proper publicly accessible ctors/etc, hence jackson cannot perform the logic without calling AccessibleObject.setAccessible(true). Since it happens in clinit(), the whole library is unusable without granting this permission.

IMO, this is a very serious bug. This situation makes it nearly impossible to properly protect confidential data (such as AWS credentials) in any app using the library, because it means private fields are no longer private, and so on.

To hack around this bug in elasticsearch, we have to grant this horrible permission to our AWS plugins, and then use the following hack in all AWS plugins to try to contain the damage:

static {
        // This internal config is deserialized but with wrong access modifiers,
        // cannot work without suppressAccessChecks permission right now. We force
        // a one time load with elevated privileges as a workaround.
        SecurityManager sm = System.getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new SpecialPermission());
        }
        AccessController.doPrivileged(new PrivilegedAction<Void>() {
            @Override
            public Void run() {
                try {
                    Class.forName("com.amazonaws.internal.config.InternalConfig$Factory");
                } catch (ClassNotFoundException e) {
                    throw new RuntimeException("Unable to initialize internal aws config", e);
                }
                return null;
            }
        });
    }

Personally, I don't see the need for fancy serialization here at all: a simple .properties file or similar could remove a ton of classes here, and possibly a 3rd-party library dependency on a popular library (jackson-databind) which would reduce jar hell for users of this library. That is how I would solve it.

Otherwise, at least set the access modifiers on all these classes/ctors/etc to be correct (public). By requiring suppressAccessChecks it means everything is effectively public.

Most helpful comment

@prangdal That would be a version discrepancy; jackson-databind version in your classpath is older than what library/framework (s3 SDK presumably) has been compiled against.

All 11 comments

Want to go for the simple approach where we just fix the access modifier as this style of configuration is on it's way out and I don't want to spend too much time refactoring the deserialization logic. In going down this route I believe I found an issue with Jackson databind that's still throwing exceptions even when the field/method/constructor is public. Opened an issue/PR with them, will update this issue when I hear back.

As per https://github.com/FasterXML/jackson-databind/issues/997:

  1. May want to disable MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS to avoid the problem (any 2.x version)
  2. For finer-grained control, Jackson 2.7 will add MapperFeature.OVERRIDE_PUBLIC_ACCESS_MODIFIERS, disabling of which prevents calls in case of accessors accessible using Reflection

Thanks for the suggestion! MapperFeature.CAN_OVERRIDE_ACCESS_MODIFIERS works for us.

This has been fixed and is staged for our next release tentatively scheduled for next Tuesday.

I just tested this release and it works, thanks again!

I am trying to work with AWS SDK for S3 to download and upload documents from my bucket.. I have just added S3 dependency with "aws-java-sdk-bom" version 1.11.24.

I am getting following error when i am running the class "S3Sample" and I see this is relates to the topic of discuss here.. can someone suggest me a fix with this please. I am trying to refer to the region "AP_SOUTH_1"

Exception in thread "main" java.lang.NoSuchFieldError: ALLOW_FINAL_FIELDS_AS_MUTATORS
at com.amazonaws.partitions.PartitionsLoader.(PartitionsLoader.java:52)
at com.amazonaws.regions.RegionMetadataFactory.create(RegionMetadataFactory.java:30)
at com.amazonaws.regions.RegionUtils.initialize(RegionUtils.java:66)
at com.amazonaws.regions.RegionUtils.getRegionMetadata(RegionUtils.java:54)
at com.amazonaws.regions.RegionUtils.getRegion(RegionUtils.java:107)
at com.amazonaws.regions.Region.getRegion(Region.java:43)
at com.soc.services.s3.connect.S3Sample.main(S3Sample.java:84)

appreciate your help here..
Thanks
Pradeep Rangdal

@prangdal That would be a version discrepancy; jackson-databind version in your classpath is older than what library/framework (s3 SDK presumably) has been compiled against.

@prangdal I had the same problem with you, and it works with me when i changed the version of jackson-databind to 2.6.6. Thank you @cowtowncoder.

@roamingdragon This issue is not fixed in my case. I checked both version of jackson-databind but the issue persists.

@abirkhan04 did you get a solution...i Am stuck with this too!!!!!

Was this page helpful?
0 / 5 - 0 ratings