I am following a tutorial from aws blogs: https://aws.amazon.com/blogs/compute/clojure/ to run a aws lambda function written in clojure.
I compile the code using lein uberjar
which generates the jar files.
Code:
project.clj
(defproject lambda-clj-examples "0.1.0"
:dependencies [[org.clojure/clojure "1.7.0"]
[org.clojure/data.json "0.2.6"]
[com.amazonaws/aws-lambda-java-core "1.0.0"]]
:aot :all)
src/hello.clj
(ns hello
(:gen-class
:methods [^:static [handler [String] String]]))
(defn -handler [s]
(str "Hello " s "!"))
The command to create the function
aws lambda create-function \
--function-name clj-hello \
--handler hello::handler \
--runtime java8 \
--memory 512 \
--timeout 10 \
--role arn:aws:iam::myawsaccountid:role/basic_lambda_role \
--zip-file fileb://./target/lambda-clj-examples-0.1.0-standalone.jar \
--region us-east-1
When I go to my function in the aws console, and invoke it, the following message is returned:
{
"errorMessage": "Error loading class PojoHandler: clojure/lang/IFn",
"errorType": "java.lang.NoClassDefFoundError"
}
The log output is:
Error loading class hello: clojure/lang/IFn: java.lang.NoClassDefFoundError
java.lang.NoClassDefFoundError: clojure/lang/IFn
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:348)
Caused by: java.lang.ClassNotFoundException: clojure.lang.IFn
at java.net.URLClassLoader.findClass(URLClassLoader.java:382)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
... 2 more
To make sure that my standalone jar file has the IFn dependecy, I run
jar tf target/lambda-clj-examples-0.1.0-standalone.jar | grep "IFn.class"
and the output is
clojure/lang/IFn.class
which seems like a good sign.
Should I do something else to make this function work?
Thanks in advance for the help
EDIT: updated lambda creation command with the right handler.
EDIT 2: I realized that my local Java version 11, not Java 8, as @Simon, pointed out in a comment of his answer, this turned out to be the issue.
What's the real command you're using to call create-function
? Your pasted example is from the blog which does not substitute awsaccountid
. It's possible the JAR is not being uploading to Lambda correctly as a binary object (i.e. wrong path).
I also don't see where you add POJO handling in hello.clj, since you pass --handler PojoHandler::handlepojo