Skip to content

DynamoDb: call to batchWriteItem kills the client #1000

@mikx

Description

@mikx

Calling client.batchWriteItem(request) with duplicate keys results in uncaught exception that completely kills the client. No further requests are possible. The client is in invalid state, connection is closed.

Expected Behavior

Exception should be caught or not happen in the first place.

Current Behavior

[ERROR] [test] software.amazon.awssdk.services.dynamodb.model.DynamoDbException: Provided list of item keys contains duplicates (Service: DynamoDb, Status Code: 400, Request ID: 0209UO3TTEJO3C3PK8QRNV1MKJVV4KQNSO5AEMVJF66Q9ASUAAJG)
*** FAILED ***Exception in thread "Thread-37" java.io.InvalidClassException: software.amazon.awssdk.core.SdkBytes; unable to create instance
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2074)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2249)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2249)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
at java.base/java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:566)
at java.base/java.lang.Throwable.readObject(Throwable.java:896)
at java.base/jdk.internal.reflect.GeneratedMethodAccessor32.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1160)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2216)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
at java.base/java.io.ObjectInputStream.defaultReadObject(ObjectInputStream.java:566)
at java.base/java.lang.Throwable.readObject(Throwable.java:896)
at java.base/jdk.internal.reflect.GeneratedMethodAccessor32.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at java.base/java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:1160)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2216)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2249)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:2355)
at java.base/java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:2249)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2087)
at java.base/java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1594)
at java.base/java.io.ObjectInputStream.readObject(ObjectInputStream.java:430)
at org.scalatest.tools.Framework$ScalaTestRunner$Skeleton$1$React.react(Framework.scala:822)
at org.scalatest.tools.Framework$ScalaTestRunner$Skeleton$1.run(Framework.scala:811)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.reflect.InvocationTargetException
at jdk.internal.reflect.GeneratedSerializationConstructorAccessor189.newInstance(Unknown Source)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at java.base/java.io.ObjectStreamClass.lambda$newInstance$0(ObjectStreamClass.java:1086)
at java.base/java.security.AccessController.doPrivileged(Native Method)
at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:85)
at java.base/java.io.ObjectStreamClass.newInstance(ObjectStreamClass.java:1094)
at java.base/java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:2071)
... 41 more
Caused by: java.lang.NullPointerException: bytes must not be null.
at software.amazon.awssdk.utils.Validate.paramNotNull(Validate.java:117)
at software.amazon.awssdk.core.BytesWrapper.(BytesWrapper.java:41)
at software.amazon.awssdk.core.BytesWrapper.(BytesWrapper.java:37)
... 48 more

Possible Solution

Prevent or catch the exception

Steps to Reproduce (for bugs)

call batchWriteItem(...) with two items with identical keys

Context

Obviously, inserting duplicate keys could be avoided on the client side.
My concern is that a simple input mistake renders the client completely inoperable.

Your Environment

  • AWS Java SDK version used: SDK 2.2.0
  • JDK version used: JDK 11.0.1
  • Operating System and version: Windows 10

Metadata

Metadata

Assignees

No one assigned

    Labels

    guidanceQuestion that needs advice or information.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions