I am developing c# lambda functions using Visual Studio 2017, the AWS Toolkit for VS2017 and the AWS Lambda Project .Net Core 2.0 template. I have successfully developed and deployed a few functions. I developed a function that uses Aspose.Net version 18.5. The function executes as expected when tested on my Windows machine. However, when deployed on AWS Lambda, I receive this stack trace:
One or more errors occurred. (The type initializer for 'Gdip' threw an exception.): AggregateException
at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
at lambda_method(Closure , Stream , Stream , LambdaContextInternal )
at System.Drawing.SafeNativeMethods.Gdip.GdipCreateMatrix2(Single m11, Single m12, Single m21, Single m22, Single dx, Single dy, IntPtr& matrix)
at \u0006 .\u0002(Single \u0002, Single \u0003, Single \u0005, Single , Single \u0006, Single \u000e, \u000e \u000f)
at .\u0002(\u0005 \u0002, \u000f \u0003, \u000e \u0005, Single , Single \u0006, Boolean \u000e, Int32 \u000f, Boolean \u0002 , Double& \u0003 , Double& \u0005 , \u0002 & )
at ..ctor(\u000f \u0002, \u0005 \u0003, \u000f \u0005)
at \u0002 .\u000f \u0002(\u000f \u0002, \u0005 \u0003, \u000f \u0005, & )
at \u0006 .\u0002( & \u0002)
at Aspose.Pdf.Devices.ImageDevice.\u0002(Page \u0002)
at Aspose.Pdf.Devices.PngDevice.Process(Page page, Stream output)
at CreateImagesFromPDF.Function.<FunctionHandler>d__10.MoveNext() in C:\Users\Thomas\source\repos\CreateImagesFromPDF\CreateImagesFromPDF\Function.cs:line 156
Unable to load DLL 'libdl': The specified module or one of its dependencies could not be found.
(Exception from HRESULT: 0x8007007E): DllNotFoundException
at Interop.Libdl.dlopen(String fileName, Int32 flag)
at System.Drawing.SafeNativeMethods.Gdip.LoadNativeLibrary()
at System.Drawing.SafeNativeMethods.Gdip..cctor()
The key message here appears to be "Unable to load DLL 'libdl'. Researching the problem I found that Aspose is dependant on System.Drawing.Common which is dependant on libdl.dll on Windows and libdl.so on Linux (where Lambda executes). Apparently, in some distros of Linux, this library is libdl.so.2. If this were a regular app, not a Lambda function, the answer appears to be to create a symbolic link from libdl.so.2 to libdl.so. Unfortunately, I don't believe that is available to me with Lambda. If I were creating my Lambda package on Linux, I would include libdl.so.2 renamed to libdl.so in the package. But, I am creating the package using the AWS Toolkit and don't know how I can add that library to it. Any help I can get with this problem would be appreciated.
Here is my source code:
using (GetObjectResponse response = await S3Client.GetObjectAsync(request))
{
using (Stream responseStream = response.ResponseStream)
{
using (MemoryStream ms = new MemoryStream())
{
responseStream.CopyTo(ms);
using (Document doc = new Document(ms))
{
for (int i = 0; i < doc.Pages.Count; i++)
{
string outFile = fileName + "_" + (i + 1).ToString() + ".png";
string tmpFile = "/tmp/" + outFile;
Page page = doc.Pages[i + 1];
using (FileStream imageStream = new FileStream(tmpFile, FileMode.Create))
{
PngDevice pngDevice;
pngDevice = new PngDevice(Convert.ToInt32((double)page.Rect.Width * 4.17), Convert.ToInt32((double)page.Rect.Height * 4.17));
pngDevice.Process(page, imageStream);
imageStream.Close();
var putRequest = new PutObjectRequest
{
BucketName = s3Event.Bucket.Name,
Key = newFolder + outFile,
ContentType = "image/png",
FilePath = tmpFile
};
PutObjectResponse resp = await S3Client.PutObjectAsync(putRequest);
File.Delete(tmpFile);
}
}
}
}
}
}
The code is failing on the line "pngDevice.Process(page, imageStream);".