Skip to content
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

Incompatible with AWS SDK 1.11.36 (Null Pointer Exception) #57

Closed
fpoolev opened this issue Sep 21, 2016 · 10 comments
Closed

Incompatible with AWS SDK 1.11.36 (Null Pointer Exception) #57

fpoolev opened this issue Sep 21, 2016 · 10 comments
Labels
Milestone

Comments

@fpoolev
Copy link

fpoolev commented Sep 21, 2016

A null pointer exception is being thrown by some dynamically generated queries. I believe the root cause of the problem is that the return types for some queries have changed. See the release notes below for details.

Compatibility with the latest version is required for the DynamoDBTypedConverted annotation fixes and updates.

Release Notes:
https://aws.amazon.com/releasenotes/4268484867346012

java.lang.NullPointerException
    at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories.rulesOf(StandardModelFactories.java:146)
    at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories.access$100(StandardModelFactories.java:53)
    at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$ConversionSchemaFactory.getModelFactory(StandardModelFactories.java:80)
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.getTableModel(DynamoDBMapper.java:392)
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.toParameters(DynamoDBMapper.java:1946)
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.toParameters(DynamoDBMapper.java:1935)
    at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.toParameters(DynamoDBMapper.java:1965)
    at com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList.<init>(PaginatedQueryList.java:66)
    at org.socialsignin.spring.data.dynamodb.core.DynamoDBTemplate.query(DynamoDBTemplate.java:191)
    at org.socialsignin.spring.data.dynamodb.query.MultipleEntityQueryRequestQuery.getResultList(MultipleEntityQueryRequestQuery.java:38)
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery$CollectionExecution.execute(AbstractDynamoDBQuery.java:103)
    at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.execute(AbstractDynamoDBQuery.java:288)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:462)
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:440)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:208)
    at com.sun.proxy.$Proxy153.findBy<redacted>(Unknown Source)
    at com.<redacted>.api.repository.dynamo.<redacted>DynamoRepositoryTest.testFindBy<redacted>(<redacted>DynamoRepositoryTest.java:92)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
    at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
    at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:254)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193)
    at org.junit.runners.Suite.runChild(Suite.java:128)
    at org.junit.runners.Suite.runChild(Suite.java:27)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:117)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:42)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:262)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:84)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
@derjust
Copy link
Owner

derjust commented Sep 21, 2016

Thanks for the feedback. I will try to look into it on a short notice

@derjust
Copy link
Owner

derjust commented Feb 20, 2017

I just pushed out version 4.5.0 which is compatible with Spring-Boot 1.5 / Spring-Data Ingalls and uses AWS SDK 1.11.93

Does the NPE still appears for you then?

@fpoolev
Copy link
Author

fpoolev commented Mar 24, 2017

Hi derjust,

Thanks for all your efforts. I had a chance to test this again but unfortunately the NPE still appears. This test was run with 4.5.0, Spring Boot 1.5.2.RELEASE, and AWS SDK 1.11.109 (1.11.93 has the same result too).

Maybe the updating stack trace will provide some insight:

java.lang.NullPointerException
	at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories.rulesOf(StandardModelFactories.java:160)
	at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories.access$100(StandardModelFactories.java:56)
	at com.amazonaws.services.dynamodbv2.datamodeling.StandardModelFactories$StandardModelFactory.getTableFactory(StandardModelFactories.java:83)
	at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.getTableModel(DynamoDBMapper.java:393)
	at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.toParameters(DynamoDBMapper.java:1961)
	at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.toParameters(DynamoDBMapper.java:1950)
	at com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper.toParameters(DynamoDBMapper.java:1982)
	at com.amazonaws.services.dynamodbv2.datamodeling.PaginatedQueryList.<init>(PaginatedQueryList.java:66)
	at org.socialsignin.spring.data.dynamodb.core.DynamoDBTemplate.query(DynamoDBTemplate.java:194)
	at org.socialsignin.spring.data.dynamodb.query.MultipleEntityQueryRequestQuery.getResultList(MultipleEntityQueryRequestQuery.java:38)
	at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery$CollectionExecution.execute(AbstractDynamoDBQuery.java:103)
	at org.socialsignin.spring.data.dynamodb.repository.query.AbstractDynamoDBQuery.execute(AbstractDynamoDBQuery.java:288)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:483)
	at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:461)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:57)
	at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
	at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213)
	at com.sun.proxy.$Proxy127.findBy<redacted>LessThanEqual(Unknown Source)
	at <redacted>.api.repository.dynamo.<redacted>DynamoRepositoryTest.testFindBy<redacted>LessThanEqual(<redacted>DynamoRepositoryTest.java:189)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
	at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
	at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
	at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
	at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
	at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
	at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
	at org.junit.runners.Suite.runChild(Suite.java:128)
	at org.junit.runners.Suite.runChild(Suite.java:27)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
	at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
	at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
	at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:51)
	at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:237)
	at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

@fpoolev
Copy link
Author

fpoolev commented Mar 25, 2017

An example interface which causes the NPE:

public interface ZDynamoRepository extends PagingAndSortingRepository<Z, Long> {
    List<Z> findByXAndYLessThanEqual(@Param("x") Long x, @Param("y") Instant y);
}

@PabloThiele
Copy link

Got the same issue in a specific query format. The weird thing is that besides adding my configuration on DynamoDBMapperConfig bean it is ignored (getting null).

@frommeyerc
Copy link

I've run into the same/similar NPE issue. For me this seems to be caused by a custom DynamoDBMapperConfig to customize the table names. I didn't specify a TypeConverterFactory which is what causes the NPE. Unfortunately when using the Builder supplied by DynamoDBMapperConfig.builder() there is no default for this factory. Even when using the Builder with defaults it doesn't have a default for this factory. I'll try now to work around this by merging in the DEFAULT configuration. Maybe DynamoDBTemplate needs to define it's own fallback strategy here (e.g. if null use DynamoDBTypeConverterFactory.standard().

@derjust
Copy link
Owner

derjust commented Jan 26, 2018

I worked in that area and there was the chance to cause it to be null - This is fixed in 5.0.1.
But trying to reproduce with the items above

@derjust derjust added this to the v5.0.2 milestone Jan 26, 2018
@derjust derjust modified the milestones: v5.0.2, v5.0.3 Mar 22, 2018
@derjust derjust added the bug label Mar 22, 2018
derjust added a commit that referenced this issue Mar 25, 2018
Issue #57: Fix compatibility with AWS SDK 1.11.36 (NullPointerException)
@derjust
Copy link
Owner

derjust commented Mar 25, 2018

Will be part of 5.0.3
Available as 5.0.3-SNAPSHOT already

@derjust derjust closed this as completed Mar 25, 2018
@data1435
Copy link

data1435 commented Jun 15, 2018

When are you planning to release version 5.0.3?

@hb5fa
Copy link

hb5fa commented Oct 1, 2018

I am using 5.0.2 with Spring-data-dynamodb and the following configuration seems to work around the NPE problem and provided good results:

First I annotated my bean accessor

@EnableDynamoDBRepositories(dynamoDBMapperConfigRef = "getDynamoDBMapperConfig", basePackages = "my.company.base.package")

I also setup an environment variable called ENV_PREFIX which is Spring wired via SpEL.

@Value("#{systemProperties['ENV_PREFIX']}")
private String envPrefix;

Then I setup a TableNameOverride bean:

@Bean
public DynamoDBMapperConfig.TableNameOverride getTableNameOverride() {
    return DynamoDBMapperConfig.TableNameOverride.withTableNamePrefix(envPrefix);
}

Finally, I setup the DynamoDBMapperConfig bean using TableNameOverride injection.

@Bean
public DynamoDBMapperConfig getDynamoDBMapperConfig(DynamoDBMapperConfig.TableNameOverride tableNameOverride) {
    DynamoDBMapperConfig.Builder builder = new DynamoDBMapperConfig.Builder();
    builder.setTableNameOverride(tableNameOverride);
    builder.setTypeConverterFactory(DynamoDBTypeConverterFactory.standard());
    return builder.build();
}

In hind sight, I could have setup a DynamoDBTypeConverterFactory bean that returns a standard DynamoDBTypeConverterFactory and inject that into the getDynamoDBMapperConfig() method using the DynamoDBMapperConfig builder. But this will also do the job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants