2

I have an app that runs on the JVM, provided as a fat jar. It needs to invoke a native Linux binary, for example ffmpeg. What directory structure would a Zip file need to contain in order to package both the jar and the executable together? I cannot find documentation, just code examples using build tools that I have not worked with.

Let's pretend the name of my lambda is blah. I am hoping to get an answer like:

Deployable jar contains:
  + blah/  # contains fat jar
  + lib/  # contains ffmpeg

Here is a bash script I wrote that does not work. It just puts the fat jar and the native executable in the dist/ directory before zipping them together.

FATJAR=blah-assembly-0.0.4.jar
mkdir -p dist/
rm -f dist/*
rm -f $DEPLOYED_ZIP
cp $FATJAR dist/
cp /usr/local/bin/ffmpeg dist/
(cd dist && zip -r $FATJAR ffmpeg && mv $FATJAR ../$DEPLOYED_ZIP)
Mike Slinn
  • 7,705
  • 5
  • 51
  • 85
  • http://stackoverflow.com/questions/2937406/how-to-bundle-a-native-library-and-a-jni-library-inside-a-jar - you can't execute them while they are in the jar, so you either have to copy them to local filesystem manually and place them anywhere you like in your jar, or use some of those mentioned utilities that does this for you. I don't if you can are allowed to use the local filesystem in aws lamda though, that could prevent you from using native libraries completely. – zapl May 25 '16 at 00:30
  • $DEPLOYED_ZIP is just a zip to deliver the files to Lambda. I expect it would automatically be unzipped by Lambda just like all other uploads. Anyway, you did not answer my question: what is the necessary directory contents of a zip file for deploying a JVM app to AWS Lambda, when another executable must also be delivered? – Mike Slinn May 25 '16 at 03:28
  • @MikeSlinn did you ever get this to work, if so please could you answer your own question, I am struggling to do exactly this. If I zip up the jar and binary and send to Lambda the lambda does not find my entry point in the jar? – Clinton Bosch Mar 01 '18 at 04:28
  • No, never got the info I needed – Mike Slinn Mar 01 '18 at 15:43

1 Answers1

0

Any structure of the zip file will do as long as the native binary included in the package appears in the PATH or is invoked through its full path. In both cases this means that you must update the Java code in one of the following ways:

  1. modify the PATH environment variable or
  2. call the binary by its full path.

As of this writing the path of the directory where the package contents is extracted on an AWS Lambda system can be read from the LAMBDA_TASK_ROOT environment variable.

Leon
  • 31,443
  • 4
  • 72
  • 97
  • 1) Does this mean the executable jar should be packaged within the zip alongside the native executable, or should the jar be enhanced with the native executable because it will be unpacked? 2) For Scala, then the path could be expressed as: `Option(sys.env("LAMBDA_TASK_ROOT").getOrElse("./")` – Mike Slinn May 28 '16 at 15:16
  • 1) Packing the native executable alongside the jar in the zip will work for sure. Cannot comment on the other option. 2) I am not familiar with Scala, but the code doesn't look right to me (assuming that it is the complete code for setting the PATH environment variable). – Leon May 28 '16 at 18:01
  • 2) The other code just means "use the env var if defined, otherwise look in the current directory". – Mike Slinn May 28 '16 at 21:21
  • That's clear. The code only reads the value of the LAMBDA_TASK_ROOT env var, but doesn't use the result to update the PATH env var. – Leon May 29 '16 at 05:50
  • No need to update `PATH` if the native executable is invoked with an explicit path – Mike Slinn May 29 '16 at 09:50