NoSuchMethodError - Troubleshooting Practice


The Problem
I am using DynamoDB in our project, and we add prefix before table names in different Environment such as: dev_, or product.

So I modified the code to add prefix which reads from property file based on environment.
@Configuration
@PropertySource("classpath:default/application.properties", "classpath:${env}/application.properties")
public class AppConfig {
    @Value("aws.product.line:")
    private String tableNamePrefix;

    @Bean
    public DynamoDBMapper dynamoDBMapper() {
        final TableNameOverride tableNameOverride = TableNameOverride.withTableNamePrefix(tableNamePrefix);
        final DynamoDBMapperConfig mapperConfig = new DynamoDBMapperConfig(tableNameOverride);
        final DynamoDBMapper mapper = new DynamoDBMapper(amazonDynamoDB(), mapperConfig);
        return mapper;
    }
    @Bean
    public AmazonDynamoDB amazonDynamoDB()...
}

It compiles but it failed with the following exception when I ran it:
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapper]: Factory method 'dynamoDBMapper' threw exception; nested exception is java.lang.NoSuchMethodError: com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig$TableNameOverride.withTableNamePrefix(Ljava/lang/String;)Lcom/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig$TableNameOverride;
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:189)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:588)
    ... 60 more
Caused by: java.lang.NoSuchMethodError: com.amazonaws.services.dynamodbv2.datamodeling.DynamoDBMapperConfig$TableNameOverride.withTableNamePrefix(Ljava/lang/String;)Lcom/amazonaws/services/dynamodbv2/datamodeling/DynamoDBMapperConfig$TableNameOverride; 

Troubleshooting
Next, I checked the built war, found there are 2 aws-java-sdk:
aws-java-sdk-1.4.2.1.jar
aws-java-sdk-core-1.10.10.jar

In 1.4.2, there is no TableNameOverride.withTableNamePrefix method.

Next, I ran mvn dependency:tree to figure out which library imports and depends on aws-java-sdk, then exclude from it.
<dependency>
    <groupId>xx</groupId>
    <artifactId>xxx</artifactId>
    <exclusions>
        <exclusion>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk-dynamodb</artifactId>
        </exclusion>
        <exclusion>
            <groupId>com.amazonaws</groupId>
            <artifactId>aws-java-sdk</artifactId>
        </exclusion>                    
    </exclusions>
</dependency>
ran mvn dependency:tree again to make sure aws-java-sdk-1.4.2 is gone, ran test, all works now.

Misc:
Check http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/types.html#type_signatures:
to know about the type signature meaning:
L fully-qualified-class ;   fully-qualified-class
long f (int n, String s, int[] arr);
has the following type signature:
(ILjava/lang/String;[I)J

Labels

adsense (5) Algorithm (69) Algorithm Series (35) Android (7) ANT (6) bat (8) Big Data (7) Blogger (14) Bugs (6) Cache (5) Chrome (19) Code Example (29) Code Quality (7) Coding Skills (5) Database (7) Debug (16) Design (5) Dev Tips (63) Eclipse (32) Git (5) Google (33) Guava (7) How to (9) Http Client (8) IDE (7) Interview (88) J2EE (13) J2SE (49) Java (186) JavaScript (27) JSON (7) Learning code (9) Lesson Learned (6) Linux (26) Lucene-Solr (112) Mac (10) Maven (8) Network (9) Nutch2 (18) Performance (9) PowerShell (11) Problem Solving (11) Programmer Skills (6) regex (5) Scala (6) Security (9) Soft Skills (38) Spring (22) System Design (11) Testing (7) Text Mining (14) Tips (17) Tools (24) Troubleshooting (29) UIMA (9) Web Development (19) Windows (21) xml (5)