-
Notifications
You must be signed in to change notification settings - Fork 877
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Custom lookup for reflective schemas #5885
Conversation
4beef67
to
bcccbc6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This JAR just contains the test POJOs.
I opted to just have a one-off JAR since it's simpler than setting up a new module and using that as a test dependency for the enhanced client, since it involves updating the import config and release yml files.
This commit updates `BeanTableSchema` and `ImmutableTableSchema` to allow customers to provide their own instance of `MethodHandle.Lookup`. This is a necessary feature for situations where either of these schemas are used in an application where the item classes and the SDK classes are loaded by different classloaders. Since these schemas work by reflectively scanning the item class to find the attributes' getters and setters (or builder for immutable classes), the enhanced client makes use of a LambdaMetaFactory to construct lambdas that directly call these methods to avoid reflection when mapping to and from a `AttributeValue`s. At least as of Java 21, the way that lambdas are constructed (all lambdas, not just the ones created by the enhanced client), is they are made internal classes of the "caller" class, i.e. the class that defined it. The calling class is identified by the class that created the `Lookup` object. This means that when using the default `Lookup` created `LambdaToMethodBridgeBuilder`, all of these lambdas are inner classes of of `LambdaToMethodBridgeBuilder`. This is an issue when the item class is from a different classloader (or module) because when the lambda attempts to reference the item class (e.g. to call a getter), it's `ClassLoader` will throw a `ClassNotFoundException` because because it's not a class that it knows about. By allowing the customer to provide a `Lookup` object, they can guarantee that the the `Lookup` has visibility and access to the item classes.
bcccbc6
to
da65644
Compare
* @return An initialized {@link BeanTableSchema} | ||
*/ | ||
@SuppressWarnings("unchecked") | ||
public static <T> BeanTableSchema<T> create(BeanTableSchemaParams<T> params) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we have a naming convention for this? "Params" feels placeholder/gross to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no precedent in the Enhanced Client for naming of parameters objects, but in core, we do have several public API's that follow the 'Params' naming, e.g. in auth
: https://sdk.amazonaws.com/java/api/2.27.12/software/amazon/awssdk/auth/signer/params/package-summary.html
The endpoint providers also follow this pattern https://sdk.amazonaws.com/java/api/latest/software/amazon/awssdk/services/s3/endpoints/S3EndpointParams.html
...ced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/mapper/BeanTableSchemaParams.java
Outdated
Show resolved
Hide resolved
...ced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/mapper/BeanTableSchemaParams.java
Show resolved
Hide resolved
...-enhanced/src/main/java/software/amazon/awssdk/enhanced/dynamodb/mapper/BeanTableSchema.java
Show resolved
Hide resolved
Integ failure not related, it's Kinesis |
|
Motivation and Context
This commit updates
BeanTableSchema
andImmutableTableSchema
to allowcustomers to provide their own instance of
MethodHandle.Lookup
.This is a necessary feature for situations where either of these schemas
are used in an application where the item classes and the SDK classes
are loaded by different classloaders. Since these schemas work by
reflectively scanning the item class to find the attributes' getters and
setters (or builder for immutable classes), the enhanced client makes
use of a LambdaMetaFactory to construct lambdas that directly call these
methods to avoid reflection when mapping to and from a
AttributeValue
s. At least as of Java 21, the way that lambdas areconstructed (all lambdas, not just the ones created by the enhanced
client), is they are made internal classes of the "caller" class, i.e.
the class that defined it. The calling class is identified by the class
that created the
Lookup
object. This means that when using the defaultLookup
createdLambdaToMethodBridgeBuilder
, all of these lambdas areinner classes of of
LambdaToMethodBridgeBuilder
. This is an issue whenthe item class is from a different classloader (or module) because when
the lambda attempts to reference the item class (e.g. to call a getter),
it's
ClassLoader
will throw aClassNotFoundException
because becauseit's not a class that it knows about.
By allowing the customer to provide a
Lookup
object, they canguarantee that the the
Lookup
has visibility and access to the itemclasses.
Modifications
Testing
Screenshots (if appropriate)
Types of changes
Checklist
mvn install
succeedsscripts/new-change
script and following the instructions. Commit the new file created by the script in.changes/next-release
with your changes.License