Description
Describe the bug
If a SecurityManager is installed, Greengrass Core Device discovery performed using DiscoveryClient will fail even with a permissive policy.
Expected Behavior
Greengrass Discovery completes successfully even if a security manager is installed.
Current Behavior
Greengrass Core Device discovery performed using DiscoveryClient fails with exception [1]
[1]
Exception thrown: java.util.concurrent.ExecutionException: com.google.gson.JsonIOException: Failed making field 'software.amazon.awssdk.iot.discovery.model.DiscoverResponse#GGGroups' accessible; either change its visibility or write a custom TypeAdapter for its declaring type
java.util.concurrent.ExecutionException: com.google.gson.JsonIOException: Failed making field 'software.amazon.awssdk.iot.discovery.model.DiscoverResponse#GGGroups' accessible; either change its visibility or write a custom TypeAdapter for its declaring type
at java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:357)
at java.util.concurrent.CompletableFuture.get(CompletableFuture.java:1908)
at greengrass.BasicDiscovery.getClientFromDiscovery(BasicDiscovery.java:157)
at greengrass.BasicDiscovery.main(BasicDiscovery.java:114)
Caused by: com.google.gson.JsonIOException: Failed making field 'software.amazon.awssdk.iot.discovery.model.DiscoverResponse#GGGroups' accessible; either change its visibility or write a custom TypeAdapter for its declaring type
at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:22)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:158)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
at com.google.gson.Gson.getAdapter(Gson.java:501)
at com.google.gson.Gson.fromJson(Gson.java:990)
at com.google.gson.Gson.fromJson(Gson.java:929)
at software.amazon.awssdk.iot.discovery.DiscoveryClient.lambda$discover$0(DiscoveryClient.java:97)
at java.util.concurrent.CompletableFuture$AsyncSupply.run(CompletableFuture.java:1604)
at java.util.concurrent.CompletableFuture$AsyncSupply.exec(CompletableFuture.java:1596)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:175)
Caused by: java.security.AccessControlException: access denied ("java.lang.reflect.ReflectPermission" "suppressAccessChecks")
at java.security.AccessControlContext.checkPermission(AccessControlContext.java:472)
at java.security.AccessController.checkPermission(AccessController.java:886)
at java.lang.SecurityManager.checkPermission(SecurityManager.java:549)
at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:128)
at com.google.gson.internal.reflect.ReflectionHelper.makeAccessible(ReflectionHelper.java:19)
... 12 more
Reproduction Steps
Build a standalone JAR file that executes https://github.com/aws/aws-iot-device-sdk-java-v2/blob/main/samples/Greengrass/src/main/java/greengrass/BasicDiscovery.java as main class. This can obtained for example by adding the snippet [1] to the build -> plugins section of https://github.com/aws/aws-iot-device-sdk-java-v2/blob/main/samples/Greengrass/pom.xml.
Run the produced jar file with the following command:
java -Djava.security.manager -Djava.security.policy=security.policy -jar ./Greengrass-1.0-SNAPSHOT-jar-with-dependencies.jar ${DISCOVERY_SAMPLE_ARGS}
where DISCOVERY_SAMPLE_ARGS
is as described in https://docs.aws.amazon.com/greengrass/v2/developerguide/test-client-device-communications.html#test-client-device-communications-java and security.policy
contains the following maximally permissive policy:
grant {
permission java.security.AllPermission;
};
The command should fail logging the reported exception if the-Djava.security.manager -Djava.security.policy=security.policy
arguments are provided and succeed if they are removed.
[1]
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifest>
<mainClass>greengrass.BasicDiscovery</mainClass>
</manifest>
</archive>
<descriptorRefs>
<descriptorRef>jar-with-dependencies</descriptorRef>
</descriptorRefs>
</configuration>
</plugin>
Possible Solution
The issue is likely caused by the fact that
is executed through CompletableFuture.supplyAsync() using the Fork Join Pool common pool.
Quoting from ForkJoinPool Javadoc, If a SecurityManager is present and no factory is specified, then the default pool uses a factory supplying threads that have no Permissions enabled..
Additional Information/Context
No response
SDK version used
main branch cloned from 1a2e1b5
Environment details (OS name and version, etc.)
Raspberry PI OS, openjdk version "1.8.0_312" OpenJDK Runtime Environment (build 1.8.0_312-8u312-b07-1+rpi1-b07) OpenJDK Client VM (build 25.312-b07, mixed mode)