I have a suite of Quarkus-based REST services that make use of DynamoDB for data persistence. I've implemented this using DynamoDBMapper
and have no problems with my code when running in JVM mode. However, when I attempt to build and run a native image I am getting DynamoDB mapping errors.
My entity code looks like this:
@DynamoDBTable(tableName = "MyTable")
public class MyEntity {
/**
*
*/
private static final long serialVersionUID = -4532872175331494789L;
@DynamoDBHashKey(attributeName = "pk")
private String partitionKey = null;
@DynamoDBRangeKey(attributeName = "sk")
private String rangeKey = null;
...
}
I'm creating my table upon startup like this...
AmazonDynamoDB client = ...
DynamoDB dynamoDB = new DynamoDB(client);
String accessKey = "xxx";
String secretKey = "yyy";
AWSCredentials creds = new BasicAWSCredentials(accessKey, secretKey);
AWSCredentialsProvider credProvider = new AWSStaticCredentialsProvider(creds);
DynamoDBMapper mapper = new DynamoDBMapper(client, credProvider);
CreateTableRequest req = mapper.generateCreateTableRequest(MyEntity.class);
client.createTable(req);
Again, in JVM mode this code works with no issues. However, if I build a native image and run it, I see the following Exception:
11:20:48 ERROR [io.quarkus.application] Failed to start application: com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMappingException: MyEntity; no mapping for HASH key
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperTableModel.hashKey(DynamoDBMapperTableModel.java:119)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperTableModel$Builder.build(DynamoDBMapperTableModel.java:449)
at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$StandardTableFactory.getTable(StandardModelFactories.java:107)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.getTableModel(DynamoDBMapper.java:408)
at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.generateCreateTableRequest(DynamoDBMapper.java:2268)
at com.amazonaws.services.dynamodbv2.datamodeling.AbstractDynamoDBMapper.generateCreateTableRequest(AbstractDynamoDBMapper.java:339)
at com.myapp.persistence.DynamoDBTableInitializer.observeStartup(DynamoDBTableInitializer.java:93)
at com.myapp.persistence.DynamoDBTableInitializer_Observer_observeStartup_988ebae54ee676255a64ec2d4203a1bb713ccc8e.notify(DynamoDBTableInitializer_Observer_observeStartup_988ebae54ee676255a64ec2d4203a1bb713ccc8e.zig:111)
at io.quarkus.arc.impl.EventImpl$Notifier.notifyObservers(EventImpl.java:282)
at io.quarkus.arc.impl.EventImpl$Notifier.notify(EventImpl.java:267)
at io.quarkus.arc.impl.EventImpl.fire(EventImpl.java:69)
at io.quarkus.arc.runtime.LifecycleEventRunner.fireStartupEvent(LifecycleEventRunner.java:23)
at io.quarkus.arc.runtime.ArcRecorder.handleLifecycleEvents(ArcRecorder.java:108)
at io.quarkus.deployment.steps.LifecycleEventsBuildStep$startupEvent78.deploy_0(LifecycleEventsBuildStep$startupEvent78.zig:77)
at io.quarkus.deployment.steps.LifecycleEventsBuildStep$startupEvent78.deploy(LifecycleEventsBuildStep$startupEvent78.zig:36)
at io.quarkus.runner.ApplicationImpl.doStart(ApplicationImpl.zig:285)
at io.quarkus.runtime.Application.start(Application.java:87)
at io.quarkus.runtime.Application.run(Application.java:210)
at io.quarkus.runner.GeneratedMain.main(GeneratedMain.zig:41)
My HASH key is clearly mapped in my entity class, so I don't know why I'm getting this error. Can anyone recommend any troubleshooting tips or provide any insight into what's going on?
You need to register the class for reflection to be working in native mode:
@RegisterForReflection
@DynamoDBTable(tableName = "MyTable")
public class MyEntity {
See:
When building a native executable, GraalVM operates with a closed world assumption. It analyzes the call tree and removes all the classes/methods/fields that are not used directly.
The elements used via reflection are not part of the call tree so they are dead code eliminated (if not called directly in other cases). To include these elements in your native executable, you need to register them for reflection explicitly.