5

After I upload and run my java .jar file, I get a warning and an error. The warning is:

This function contains external libraries. Uploading a new file will override these libraries.

And The error is:

java.lang.NoClassDefFoundError: org/apache/http/client/methods/HttpUriRequest
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
Caused by: java.lang.ClassNotFoundException: org.apache.http.client.methods.HttpUriRequest
at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)   

I can build the jar no problem, all dependencies are in my pom. I have a handful of libraries that I'm using, like org.json that also throw the same java.lang.NoClassDefFoundError error. I do import these classes. My jar however doesn't include these files, only my class. I'm suspecting that's related. Is that true? Do I need to find amazon class substitution for these "external" classes that I'm using? I'm confused.

smac2020
  • 9,637
  • 4
  • 24
  • 38
user2917629
  • 883
  • 2
  • 15
  • 30

4 Answers4

14

Amazon Lambda will not download your dependencies for you. It expects your deployment file to contain all dependencies necessary to run your Lambda function. You will need to switch to using the zip deployment method that allows you to include multiple jar files (your Lambda function jar and all dependency jars). Follow the instructions here.

Mark B
  • 183,023
  • 24
  • 297
  • 295
  • Above instruction link is dead. May follow this [new link](https://docs.aws.amazon.com/lambda/latest/dg/java-package.html) – Lee Chee Kiam Jul 30 '21 at 03:43
6

Another option is to create a fat jar file. That is a jar which already contains all your dependency. Such file will be larger to deploy but easier to manage. I would recommend you to use some build tool like Maven to build a fat jar.

Community
  • 1
  • 1
Mangat Rai Modi
  • 5,397
  • 8
  • 45
  • 75
2

Maybe this is a bit late to answer, but if you are using Gradle you need to run shadowJar task that will generate a fat jar contains all required dependencies.

ex. ./gradlew shadowJar

or if you use serverless you can use ./gradlew deploy where deploy task depending on shadowJar and it will deploy the whole stack.

I made a simple task to help me with this in my project build.gradle script:

task deployF() {
    group = 'serveless'
    dependsOn = ['shadowJar']
    def functionName = project.findProperty("fun")
    doLast {
        exec {
            commandLine 'serverless', 'deploy', '-f', functionName
        }
    }
}

to use it you need to call ./gradle deployF -Pfun=YOUR_FUNCTION_NAME this will build the jar file and deploy the selected function to lambda

Mohammad Ersan
  • 12,304
  • 8
  • 54
  • 77
0

Simply include your dependency jar in dependencyManagement>dependencies>dependency tag in pom.xml in addition to normal dependencies tree. That will also create fat jar.