Skip to content

Support creation of AWS Lambda .zip archives #237

@xjusko

Description

@xjusko

AWS Lambda supports deployments of Java functions in [a simple ZIP format|https://docs.aws.amazon.com/lambda/latest/dg/create-deployment-pkg-zip-java.html].

As with standard JARs, the class files, resources, manifest resources, and service provider configurations are all included from the root of the archive. Unlike standard JARs, dependent JARs are included under a 'lib/' folder.

Currently, to create ad-hoc Lambda deployments for testing I'm starting with a {{JavaArchive}}. I add the standard JAR assets, and then use the [{{Archive.add(Archive, ArchivePath, StreamExporter)}}|https://repository.jboss.org/nexus/content/repositories/unzip/org/jboss/shrinkwrap/shrinkwrap-api/1.2.6/shrinkwrap-api-1.2.6-javadoc.jar-unzip/index.html] API (as used by [{{ContainerBase.addAsLibraries(Archive...)}}|https://repository.jboss.org/nexus/content/repositories/unzip/org/jboss/shrinkwrap/shrinkwrap-impl-base/1.2.6/shrinkwrap-impl-base-1.2.6-javadoc.jar-unzip/index.html] to add the dependencies. Finally, I export it to a temp file with a '.zip' extension for upload:


final JavaArchive lambdaZip = ShrinkWrap.create(JavaArchive.class);
lambdaZip.addClasses(handlerClass);
final ArchivePath archiveLibraryPath = ArchivePaths.create("/lib");
Maven.resolver()
    .loadPomFromFile("pom.xml")
    .importCompileAndRuntimeDependencies()
    .resolve()
    .withTransitivity()
    .asList(JavaArchive.class)
    .forEach(javaArchive -> lambdaZip.add(javaArchive, archiveLibraryPath, ZipExporter.class));
lambdaZip.as(ZipExporter.class).exportTo(tempZipFile, overwrite);

It would be nice to be able to use the [{{LibraryContainer}}|https://repository.jboss.org/nexus/content/repositories/unzip/org/jboss/shrinkwrap/shrinkwrap-api/1.2.6/shrinkwrap-api-1.2.6-javadoc.jar-unzip/index.html] API directly instead.

I can think of a few ways to accomplish this (and there are likely others):

Make {{JavaArchive}} a {{LibraryContainer}}. The library path would be defaulted to 'lib/'.

#* Easy to do since {{JavaArchiveImpl}} extends {{ContainerBase}}, which already has the all the necessary implementation.
#* The API would now extend the [JAR File Specification|https://docs.oracle.com/javase/8/docs/technotes/guides/jar/jar.html], so there's the question of utility vs. conformance.
#* There's also the issue of the default archive name having a '.jar' extension instead of '.zip' (per the service descriptor properties file for {{JavaArchive}}).

Add {{LibraryContainer}} and {{ServiceProviderContainer}} to the list of interfaces extended by {{GenericArchive}}.

#* Easy again with the underlying implementation being {{ContainerBase}}.
#* There's no presumption of a spec with {{GenericArchive}}, so presumably there's no harm in the additional API. Perhaps that makes defaulting the library path to 'lib/' more assuming, though.
#* I was surprised to find the default extension for {{GenericArchive}} is '.jar', which implies the JAR spec. I would have guessed '.zip'. I'd propose changing it as part of this approach, but that would be a breaking change for anyone who's come to depend on it being '.jar'.
#* Another issue here is if you further say the {{WebContainer}}, {{EnterpriseContainer}}, and {{ResourceAdapterContainer}} API might as well be added too. Their respective implementation classes extend {{ContainerBase}}, creating a multiple inheritance situation on the implementation side. There's also conflict between the standard paths, e.g. 'lib/' vs. 'WEB-INF/lib/'.

Add a new {{LambdaArchive}} interface and implementation to ShrinkWrap proper.

#* It would be the equivalent of approach #1, but with a default extension of '.zip'.
#* AWS Lambda seems here to stay.
#* I would think it better to take this as an opportunity to make the base API more generic, rather than to specialize with a new subtype.

Create the same {{LambdaArchive}}, but in a ShrinkWrap extension project.

I'm happy to create a pull request given guidance on the preferred approach. For myself, I'd lean towards #2 if changing the default extension is deemed acceptable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions