aws / aws-lambda-base-images

Apache License 2.0
670 stars 110 forks source link

Java 17 (Corretto) Runtime #29

Closed driverpt closed 1 year ago

driverpt commented 2 years ago

As title says

nicofabre commented 2 years ago

Do we have an estimated date for Java 17 implementation in AWS Lambda ? Our team would really like to enjoy Java features brought between Java 11 and Java 17 in AWS Lambda. We know that we can create Lambda container image for that (https://docs.aws.amazon.com/lambda/latest/dg/images-create.html). But it would be better and more convenient to have Java 17 as a Lambda base image / native runtime. Why does it take so long to have Java 17 implemented in AWS Lambda ? I had expected to get that in September 2021 when Java 17 was released. AWS is ensuring the development of Java with its Corretto project. Why AWS does not implement it in AWS Lambda ?

dsvensson commented 2 years ago

I tried adapting the current Java 11 base image to Corretto 17 by just replacing the corresponding <hash>.tar.xz file. First hurdle was the missing runtime.jsa file in the Corretto 17 directory. I assume this is generated via:

/var/lang/bin/java -Xshare:dump -XX:SharedArchiveFile=/var/lang/lib/server/runtime.jsa 
    --class-path /var/runtime/amzn-log4j-security-jdk11-0.1alpha.jar:/var/runtime/lib/aws-lambda-java-core-1.2.0.jar:/var/runtime/lib/aws-lambda-java-runtime-0.2.0.jar:/var/runtime/lib/aws-lambda-java-serialization-0.2.0.jar

....this file should probably be generatede via the build system to include your own jars as well.

It then starts, but then subsequently fails when some agentlib tries to access a module that hasn't been opened.

Exception in thread "main" java.lang.reflect.InvocationTargetException
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndStartAgent(InstrumentationImpl.java:491)
    at java.instrument/sun.instrument.InstrumentationImpl.loadClassAndCallPremain(InstrumentationImpl.java:503)
Caused by: java.lang.IllegalAccessError: class Log4jPatch (in unnamed module @0x3e3abc88) cannot access class jdk.internal.org.objectweb.asm.Opcodes (in module java.base) because module java.base does not export jdk.internal.org.objectweb.asm to unnamed module @0x3e3abc88
    at Log4jPatch.asmVersion(Log4jPatch.java:35)
    at Log4jPatch.agentmain(Log4jPatch.java:56)
    at Log4jPatch.premain(Log4jPatch.java:108)
    ... 6 more
*** java.lang.instrument ASSERTION FAILED ***: "result" with message agent load/premain call failed at src/java.instrument/share/native/libinstrument/JPLISAgent.c line: 422
FATAL ERROR in native method: processing of -javaagent failed, processJavaStart failed

I'm not sure where to pass module opening to allow this as the JVM is launched via the rie binary.

This can for example be fixed via:

JAVA_TOOL_OPTIONS="--add-opens=java.base/java.util=ALL-UNNAMED --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED"

After these two changes the Java 11 base image has been adapted to Corretto 17, or so it seems at least. Next step is deleting some useless crap from the Corretto 17 distribution similar to that old Java 11 directory to get the size down a bit.

This is what I ended up with. Opted for using the Java 11 base image for a smaller Dockerfile, with the idea that the other layers are cached near site of use, not sure if that makes sense or not, but hopefully a proper 17 version will come shortly.

FROM public.ecr.aws/lambda/java:11

ADD amazon-corretto-17-x64-linux-jdk.tar.gz /var/lang-tmp/

RUN rm -rf /var/lang && \
    mv /var/lang-tmp/amazon-corretto-17.0.1.12.1-linux-x64 /var/lang && \
    rm -rf \
      /var/lang/man \
      /var/lang/legal \
      /var/lang/lib/src.zip \
      /var/lang/lib/server/classes_nocoops.jsa

RUN /var/lang/bin/java -Xshare:dump -XX:SharedArchiveFile=/var/lang/lib/server/runtime.jsa \
    --class-path /var/runtime/amzn-log4j-security-jdk11-0.1alpha.jar:/var/runtime/lib/aws-lambda-java-core-1.2.0.jar:/var/runtime/lib/aws-lambda-java-runtime-0.2.0.jar:/var/runtime/lib/aws-lambda-java-serialization-0.2.0.jar

# Open up JVM internals used by the AWS Lambda -javaagent
ENV JAVA_TOOL_OPTIONS="--add-opens=java.base/java.util=ALL-UNNAMED --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED"
wietlol commented 2 years ago

On top of Corretto 17 support, would the java-17 runtime also use the Graviton processors?

driverpt commented 2 years ago

@dsvensson , putting "--add-opens=java.base/java.util=ALL-UNNAMED --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED defeats the purpose.

JDK 17 makes Jigsaw (Java 9 Modules) Mandatory. I noticed that inside the Docker Image there are some AWS Jars which are not yet have module-info.java. Since it's maintained by AWS, it's best we let AWS properly configure a Base Corretto 17 Image

driverpt commented 2 years ago

@wietlol , Java is "Compile once, run anywhere", so i would guess that Gravitron support is implicit. Java11 Runtime already supports Gravitron

dsvensson commented 2 years ago

@dsvensson , putting "--add-opens=java.base/java.util=ALL-UNNAMED --add-exports=java.base/jdk.internal.org.objectweb.asm=ALL-UNNAMED defeats the purpose.

As long as you are aware of the meaning and the goal is just to run 17, it fits the purpose. 11 didn't have modules. For me I just want to use the same JVM in both lambda and ECS deploys for convenience. The instant a new base is ready it's time to ditch the workaround.

driverpt commented 2 years ago

@dsvensson , Jigsaw Modules exist since Java 9. In JDK 17 they became mandatory. Just wanting to use JDK 17 without understanding how it should work is not the way to go. Jigsaw was created for Security purposes, so when you develop a Library Jar, your Internal Classes aren't accessible. I advise you to create a proper module-info.java and understand how Jigsaw works

dsvensson commented 2 years ago

@dsvensson , Jigsaw Modules exist since Java 9. In JDK 17 they became mandatory. Just wanting to use JDK 17 without understanding how it should work is not the way to go. Jigsaw was created for Security purposes, so when you develop a Library Jar, your Internal Classes aren't accessible. I advise you to create a proper module-info.java and understand how Jigsaw works

You are absolutely correct. There was no module requirement. My comment was sloppy, it should have said that modules was not an issue. For my usecase modules add very little value. It will be a nice bonus when everything is aligned, but nothing I personally care about. In my case I was not running on a LTS version before for the rest of the application, and 17 presented that opportunity. When moving to the most recent LTS it just made sense to use the same version everywhere to simplify CI and development experience (arm64 laptops), with the goal of migrating to a supported 17 upstream image at some point in the future. My initial comment achieves just that. Your comments only add off topic useless discussions that I will try to stay out of going forward. Criticism is better received with patches.

jam01 commented 2 years ago

Hey aws team, we're wondering if there's any news on this effort. JDK 18 is coming out in a month and we're hoping to stay on the latest releases as much as possible, as encouraged by the OpenJDK team.

sigpwned commented 2 years ago

Google Cloud just announced that Cloud Functions now support Java 17 at preview release level today. It would be great to have even a high-level idea of delivery date for AWS for the same feature!

SentryMan commented 2 years ago

Any news on this? It's been quite some time since 17 came out.

jtuliani commented 2 years ago

Java 17 support for Lambda is included in our roadmap planning, however due to some uncertain dependencies we don't yet have a timeline that's ready to share.

sigpwned commented 2 years ago

@jtuliani I appreciate the transparency very much, but it's still disappointing not to have even a rough ETA. Thank you for the response, regardless.

sigpwned commented 2 years ago

FWIW, I have run across this java17 layer project from an apparent serverless solutions architect at AWS. I haven't used it yet, but thought it was relevant, so thought I'd drop it here for discussion. I will circle back with feedback if and when I do end up using it, and it would be great to hear others' experiences too! Regardless, many thanks to @msailes / @marksailes for moving the ball forward!

msailes commented 2 years ago

This method is also documented on the AWS Blog https://aws.amazon.com/blogs/compute/build-a-custom-java-runtime-for-aws-lambda/

sigpwned commented 2 years ago

Having been inspired by @msailes' excellent java17 layer project, I decided to tackle putting together a Java 17 Lambda custom base image. You can find the source code at aleph0io/aws-lambda-java-base-images, and the public docker images in the ECR public gallery and DockerHub.

I have also created a (simple) example lambda function using the base image at aleph0io/example-java-lambda-function to show how to use it. In short, use it just like an official base image.

I'm using the custom base image in production, and it works a treat. If anyone else uses it, I would be very keen to hear any feedback at all. In the meantime, it's probably best to consider them experimental.

Naturally, once AWS releases the official runtime, everyone should use that, but hopefully this will help in the meantime.

I only have an image for Java 17 x86_64 for now, but I hope to also add support for non-LTS versions and at least arm64 architecture soon, too.

EDIT: There are now custom lambda base images available for Java 17, 18, and 19 in the ECR public gallery and DockerHub.

Berehulia commented 2 years ago

Hi, @jtuliani. We are working on some comparisons of different Lambda runtimes and want to pick Java 17 for research. Will it be released at the end of Q3? Could you share your plans with us if possible, please?

celtric commented 2 years ago

Missed Java 17 1st birthday by a few days. Happy birthday! šŸŽ‚ And Java 19 was released yesterday. But here we are, still stuck with Java 11 official images in Lambda...

oletjens commented 1 year ago

@jtuliani Any news on this?

softprops commented 1 year ago

I'm using @msailes https://github.com/msailes/lambda-java17-layer project it it seems to work just fine for now

for those using sam you need only to copy that projects zip to a bucket

curl --proto '=https' --tlsv1.2 -sSfL https://github.com/msailes/lambda-java17-layer/releases/download/v0.0.1-alpha/java17layer.zip -O > java17layer.zip    
echo "1db3dfa9cf07f22447641be476fedbaa125778b8150cbe8573b4b51ea9fe27b4 java17layer.zip" | sha256sum -c
aws s3 cp java17layer.zip s3://{YOUR_BUCKET_NAME}/layers/

then refer to the layer from your sam template in a layer version, add that layer your lambda and use the provided runtime

AWSTemplateFormatVersion: "2010-09-09"
Transform: AWS::Serverless-2016-10-31

Resources:
  Layer:
    Type: AWS::Serverless::LayerVersion
    Properties:
      LayerName: java-17-runtime
      ContentUri: s3://{YOUR_BUCKET_NAME}/layers/java17layer.zip
      CompatibleRuntimes:
        - provided
   Function:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: path/to/your/app.zip
      Handler: com.you.your.Handler
      Runtime: provided.al2
      Layers:
        - !Ref Layer
      Architectures:
        - arm64
alsikorski commented 1 year ago

@jtuliani Any news on this?

jtuliani commented 1 year ago

We are continuing to work on Java 17 support, but don't currently have a timeline we can share.

SentryMan commented 1 year ago

Does this new snap start feature explain the delay?

jtuliani commented 1 year ago

It wouldn't be appropriate for me to comment on internal scheduling details. However, we do hope you are excited to try SnapStart!

softprops commented 1 year ago

Iā€™m now more eager for an official java17 runtime since snapstart was announced.

Iā€™ve since moved onto java17 with a custom runtime mentioned above. Now it feels like those that are using current java lts version are missing out if only java11 is getting snapstart support.

I raised a separate question in the aws java runtime client project if thereā€™s a way to work it in there, in which case I wouldnā€™t be missing out on whatā€™s going on in java11 runtime https://github.com/aws/aws-lambda-java-libs/issues/380

cforce commented 1 year ago

:( Java 17 LTS is out since (14.09.2021) 1 year and 4 months ago and still not supported in lambda. I really wonder what is so difficult to make it happen that there is even not a timeline https://github.com/aws/aws-lambda-java-libs/issues/380#issuecomment-1378977890.

Microsoft Azure functions is supporting Java 17 https://learn.microsoft.com/de-de/azure/azure-functions/functions-reference-java?tabs=bash%2Cconsumption#create-java-functions

Please catch up with state of the art Java support

jtuliani commented 1 year ago

We recognize the extended delay in providing Java 17 support in AWS Lambda, and apologize for the inconvenience this has caused. Our plan is to publish a base container images for Java 17 this month, with the managed runtime and tooling support (SAM CLI, CFN, CDK, AWS CLI, console, etc) support to follow. We will provide an ETA for the managed runtime when we publish the container image.

nicofabre commented 1 year ago

I think lots of people are happy about the news above. But, if I may, without willing to be a killjoy, the next Java LTS version (Java 21) will be released in few months (September 2023) with several interesting features. May I ask if the solution you are going to implement for Java 17 will also allow a fast implementation of Java 21 in AWS Lambda when it will be released ? According to my understanding "base container image" should be easy to change to put a new JDK version within ?

Another question : Will Lambda SnapStart work with this solution ?

Anyway, thank you for your efforts to consider Java community.

argenstijn commented 1 year ago

Happy to hear it. But also a feeling kinda disappointed as Lambda Java 17 support to my opinion should have already been there.

softprops commented 1 year ago

My company is starting its migration from 17 to 19 to in prep for the ā€œloomā€ing 21 release this year.

Iā€™ve got nothing but love for the hard work aws does on these runtimes but I agree with the sentiment above. an official 17 runtime is going is going to feel like todays 11 when java 21 comes along.

sigpwned commented 1 year ago

@softprops in case it's useful, I maintain a set of community Lambda base images, including for Java 19, in the ECR public gallery. They're open source, so you can always read or fork, too. I'll add images for Java 20 and 21 as they come out.

Good luck with the migration! I can't wait for Project Loom either.

jtuliani commented 1 year ago

@nicofabre Yes, the managed runtime for Java 17 will support SnapStart. SnapStart is not currently supported for functions deployed using container images.

nathanagood commented 1 year ago

It is exceedingly frustrating that this isn't done yet, and I would think embarrassing for you as 20 is in RC and 21 is in EAB. Is there an update?

You seriously need the Raise the Bar on the Java support for Lambda runtimes.

coderfromhere commented 1 year ago

@jtuliani how is it going so far? Are we still to expect it in a few days time?

pushkarchawda commented 1 year ago

Java17 Preview Base Image is out.

Image URI

public.ecr.aws/lambda/java:17-preview

Check out at https://gallery.ecr.aws/lambda/java

jtuliani commented 1 year ago

We have today published a Lambda container base image for Java 17, for both x86_64 and arm64 architectures.

Our performance testing has shown a degradation in cold start latency for a subset of functions when using the Java 17 image; while we investigate further we have tagged the Java 17 image as ā€˜previewā€™ and it should not be used for production workloads.

Instructions for how to use Lambda container base images for Java are given in the ā€˜Usageā€™ tab at https://gallery.ecr.aws/lambda/java.

This release includes a change to the default tiered compilation setting previously used by the Java 11 base image. With Java 11, Lambda uses the C2 compiler; with the Java 17 Lambda configures tiered compilation to stop at C1 level 1 by default. For more information and why for most functions this will provide an overall performance benefit, see https://aws.amazon.com/blogs/compute/optimizing-aws-lambda-function-performance-for-java/. Customers can enable the previous tiered compilation behavior by setting the JAVA_TOOL_OPTIONS environment variable to -XX:-TieredCompilation

We expect to publish updated images suitable for production workloads and managed runtime support for Java 17 within 90 days.

checketts commented 1 year ago

Is there a way to use the preview Java 17 with snapstart? Or does that require the managed runtime?

jtuliani commented 1 year ago

@checketts As yet, SnapStart is only supported for Java managed runtimes, not container images. So you can't use the Java 17 preview image with SnapStart, nor can you use the Java 11 container image. We're aware of customer demand for SnapStart support with container images, but don't have an ETA to share at this time.

jtuliani commented 1 year ago

We have today published an updated Java 17 container image which addresses the performance issue in the previously published preview image. This new image is no longer tagged as preview and is suitable for production workloads. We are continuing to work on the Java 17 managed runtime release, which remains on track for delivery by our target date of 2023-05-29 as previously communicated.

rhermes62 commented 1 year ago

Just saw CDK support for Java 17 launch yesterday with version 2.77.0šŸ‘€

Looks like we are getting close! Thank you!!

jtuliani commented 1 year ago

Support for Java 17 as a managed runtime in AWS Lambda is now GA:

https://aws.amazon.com/about-aws/whats-new/2023/04/aws-lambda-java-17 https://aws.amazon.com/blogs/compute/java-17-runtime-now-available-on-aws-lambda

sigpwned commented 1 year ago

Congrats to the AWS team! Huge release.