From 67c2bfe5845262d681819dd0b7bff1bd77d3f3f4 Mon Sep 17 00:00:00 2001 From: Mohammed Ehab Date: Wed, 12 Mar 2025 16:47:21 +0000 Subject: [PATCH 1/3] Refactor the Main Function Into Three Main Blocks. --- .../lambda/runtime/api/client/AWSLambda.java | 45 ++++++++++++------- 1 file changed, 28 insertions(+), 17 deletions(-) diff --git a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java index 986f8b7b..83360302 100644 --- a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java +++ b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java @@ -2,6 +2,7 @@ Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ + package com.amazonaws.services.lambda.runtime.api.client; import com.amazonaws.services.lambda.crac.Core; @@ -30,12 +31,12 @@ import java.io.IOError; import java.io.IOException; import java.io.PrintStream; +import java.io.UnsupportedEncodingException; import java.lang.reflect.Constructor; import java.net.URLClassLoader; import java.security.Security; import java.util.Properties; - /** * The entrypoint of this class is {@link AWSLambda#startRuntime}. It performs two main tasks: * @@ -176,24 +177,28 @@ private static LogSink createLogSink() { } } - public static void main(String[] args) { - startRuntime(args[0]); - } + public static void main(String[] args) throws Throwable { + try { + LambdaContextLogger logger = initLogger(); + LambdaRequestHandler lambdaRequestHandler = getLambdaRequestHandlerObject(args[0], logger); + startRuntimeLoop(lambdaRequestHandler, logger); - private static void startRuntime(String handler) { - try (LogSink logSink = createLogSink()) { - LambdaContextLogger logger = new LambdaContextLogger( - logSink, - LogLevel.fromString(LambdaEnvironment.LAMBDA_LOG_LEVEL), - LogFormat.fromString(LambdaEnvironment.LAMBDA_LOG_FORMAT) - ); - startRuntime(handler, logger); - } catch (Throwable t) { + } catch (IOException | ClassNotFoundException t) { throw new Error(t); } } - private static void startRuntime(String handler, LambdaContextLogger lambdaLogger) throws Throwable { + private static LambdaContextLogger initLogger() { + LogSink logSink = createLogSink(); + LambdaContextLogger logger = new LambdaContextLogger( + logSink, + LogLevel.fromString(LambdaEnvironment.LAMBDA_LOG_LEVEL), + LogFormat.fromString(LambdaEnvironment.LAMBDA_LOG_FORMAT)); + + return logger; + } + + private static LambdaRequestHandler getLambdaRequestHandlerObject(String handler, LambdaContextLogger lambdaLogger) throws UnsupportedEncodingException, ClassNotFoundException, IOException { UnsafeUtil.disableIllegalAccessWarning(); System.setOut(new PrintStream(new LambdaOutputStream(System.out), false, "UTF-8")); @@ -210,7 +215,7 @@ private static void startRuntime(String handler, LambdaContextLogger lambdaLogge Thread.currentThread().setContextClassLoader(customerClassLoader); // Load the user's handler - LambdaRequestHandler requestHandler; + LambdaRequestHandler requestHandler = null; try { requestHandler = findRequestHandler(handler, customerClassLoader); } catch (UserFault userFault) { @@ -220,11 +225,16 @@ private static void startRuntime(String handler, LambdaContextLogger lambdaLogge RapidErrorType.BadFunctionCode); runtimeClient.reportInitError(error); System.exit(1); - return; } + if (INIT_TYPE_SNAP_START.equals(AWS_LAMBDA_INITIALIZATION_TYPE)) { onInitComplete(lambdaLogger); } + + return requestHandler; + } + + private static void startRuntimeLoop(LambdaRequestHandler requestHandler, LambdaContextLogger lambdaLogger) throws Throwable { boolean shouldExit = false; while (!shouldExit) { UserFault userFault = null; @@ -240,7 +250,7 @@ private static void startRuntime(String handler, LambdaContextLogger lambdaLogge payload = requestHandler.call(request); runtimeClient.reportInvocationSuccess(request.getId(), payload.toByteArray()); // clear interrupted flag in case if it was set by user's code - boolean ignored = Thread.interrupted(); + Thread.interrupted(); } catch (UserFault f) { shouldExit = f.fatal; userFault = f; @@ -278,6 +288,7 @@ static void onInitComplete(final LambdaContextLogger lambdaLogger) throws IOExce RapidErrorType.BeforeCheckpointError)); System.exit(64); } + try { Core.getGlobalContext().afterRestore(null); } catch (Exception restoreExc) { From bde4d1499f4b7fdf93df26743dbc431ff67015f2 Mon Sep 17 00:00:00 2001 From: Mohammed Ehab Date: Tue, 18 Mar 2025 17:39:01 +0000 Subject: [PATCH 2/3] Use Try with Resources for logger. --- .../lambda/runtime/api/client/AWSLambda.java | 76 +++++++++---------- .../client/logging/LambdaContextLogger.java | 10 ++- 2 files changed, 46 insertions(+), 40 deletions(-) diff --git a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java index 83360302..65635ef4 100644 --- a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java +++ b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java @@ -31,7 +31,6 @@ import java.io.IOError; import java.io.IOException; import java.io.PrintStream; -import java.io.UnsupportedEncodingException; import java.lang.reflect.Constructor; import java.net.URLClassLoader; import java.security.Security; @@ -138,6 +137,42 @@ private static LambdaRequestHandler findRequestHandler(final String handlerStrin return requestHandler; } + private static LambdaRequestHandler getLambdaRequestHandlerObject(String handler, LambdaContextLogger lambdaLogger) throws ClassNotFoundException, IOException { + UnsafeUtil.disableIllegalAccessWarning(); + + System.setOut(new PrintStream(new LambdaOutputStream(System.out), false, "UTF-8")); + System.setErr(new PrintStream(new LambdaOutputStream(System.err), false, "UTF-8")); + setupRuntimeLogger(lambdaLogger); + + runtimeClient = new LambdaRuntimeApiClientImpl(LambdaEnvironment.RUNTIME_API); + + String taskRoot = System.getProperty("user.dir"); + String libRoot = "/opt/java"; + // Make system classloader the customer classloader's parent to ensure any aws-lambda-java-core classes + // are loaded from the system classloader. + customerClassLoader = new CustomerClassLoader(taskRoot, libRoot, ClassLoader.getSystemClassLoader()); + Thread.currentThread().setContextClassLoader(customerClassLoader); + + // Load the user's handler + LambdaRequestHandler requestHandler = null; + try { + requestHandler = findRequestHandler(handler, customerClassLoader); + } catch (UserFault userFault) { + lambdaLogger.log(userFault.reportableError(), lambdaLogger.getLogFormat() == LogFormat.JSON ? LogLevel.ERROR : LogLevel.UNDEFINED); + LambdaError error = new LambdaError( + LambdaErrorConverter.fromUserFault(userFault), + RapidErrorType.BadFunctionCode); + runtimeClient.reportInitError(error); + System.exit(1); + } + + if (INIT_TYPE_SNAP_START.equals(AWS_LAMBDA_INITIALIZATION_TYPE)) { + onInitComplete(lambdaLogger); + } + + return requestHandler; + } + public static void setupRuntimeLogger(LambdaLogger lambdaLogger) throws ClassNotFoundException { ReflectUtil.setStaticField( @@ -178,8 +213,7 @@ private static LogSink createLogSink() { } public static void main(String[] args) throws Throwable { - try { - LambdaContextLogger logger = initLogger(); + try (LambdaContextLogger logger = initLogger()){ LambdaRequestHandler lambdaRequestHandler = getLambdaRequestHandlerObject(args[0], logger); startRuntimeLoop(lambdaRequestHandler, logger); @@ -198,42 +232,6 @@ private static LambdaContextLogger initLogger() { return logger; } - private static LambdaRequestHandler getLambdaRequestHandlerObject(String handler, LambdaContextLogger lambdaLogger) throws UnsupportedEncodingException, ClassNotFoundException, IOException { - UnsafeUtil.disableIllegalAccessWarning(); - - System.setOut(new PrintStream(new LambdaOutputStream(System.out), false, "UTF-8")); - System.setErr(new PrintStream(new LambdaOutputStream(System.err), false, "UTF-8")); - setupRuntimeLogger(lambdaLogger); - - runtimeClient = new LambdaRuntimeApiClientImpl(LambdaEnvironment.RUNTIME_API); - - String taskRoot = System.getProperty("user.dir"); - String libRoot = "/opt/java"; - // Make system classloader the customer classloader's parent to ensure any aws-lambda-java-core classes - // are loaded from the system classloader. - customerClassLoader = new CustomerClassLoader(taskRoot, libRoot, ClassLoader.getSystemClassLoader()); - Thread.currentThread().setContextClassLoader(customerClassLoader); - - // Load the user's handler - LambdaRequestHandler requestHandler = null; - try { - requestHandler = findRequestHandler(handler, customerClassLoader); - } catch (UserFault userFault) { - lambdaLogger.log(userFault.reportableError(), lambdaLogger.getLogFormat() == LogFormat.JSON ? LogLevel.ERROR : LogLevel.UNDEFINED); - LambdaError error = new LambdaError( - LambdaErrorConverter.fromUserFault(userFault), - RapidErrorType.BadFunctionCode); - runtimeClient.reportInitError(error); - System.exit(1); - } - - if (INIT_TYPE_SNAP_START.equals(AWS_LAMBDA_INITIALIZATION_TYPE)) { - onInitComplete(lambdaLogger); - } - - return requestHandler; - } - private static void startRuntimeLoop(LambdaRequestHandler requestHandler, LambdaContextLogger lambdaLogger) throws Throwable { boolean shouldExit = false; while (!shouldExit) { diff --git a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/logging/LambdaContextLogger.java b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/logging/LambdaContextLogger.java index 693eb015..56ac6cf7 100644 --- a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/logging/LambdaContextLogger.java +++ b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/logging/LambdaContextLogger.java @@ -8,8 +8,10 @@ import com.amazonaws.services.lambda.runtime.logging.LogFormat; import com.amazonaws.services.lambda.runtime.logging.LogLevel; import static java.nio.charset.StandardCharsets.UTF_8; +import java.io.Closeable; +import java.io.IOException; -public class LambdaContextLogger extends AbstractLambdaLogger { +public class LambdaContextLogger extends AbstractLambdaLogger implements Closeable{ // If a null string is passed in, replace it with "null", // replicating the behavior of System.out.println(null); private static final byte[] NULL_BYTES_VALUE = "null".getBytes(UTF_8); @@ -29,4 +31,10 @@ protected void logMessage(byte[] message, LogLevel logLevel) { sink.log(logLevel, this.logFormat, message); } } + + @Override + public void close() throws IOException { + sink.close(); + + } } From bccc4d31941e9d04617fb10a851c2d4dafae617a Mon Sep 17 00:00:00 2001 From: Mohammed Ehab Date: Tue, 18 Mar 2025 17:41:58 +0000 Subject: [PATCH 3/3] Fix Linting Errors --- .../services/lambda/runtime/api/client/AWSLambda.java | 2 +- .../runtime/api/client/logging/LambdaContextLogger.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java index 65635ef4..2eeb14e3 100644 --- a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java +++ b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java @@ -213,7 +213,7 @@ private static LogSink createLogSink() { } public static void main(String[] args) throws Throwable { - try (LambdaContextLogger logger = initLogger()){ + try (LambdaContextLogger logger = initLogger()) { LambdaRequestHandler lambdaRequestHandler = getLambdaRequestHandlerObject(args[0], logger); startRuntimeLoop(lambdaRequestHandler, logger); diff --git a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/logging/LambdaContextLogger.java b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/logging/LambdaContextLogger.java index 56ac6cf7..dd356912 100644 --- a/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/logging/LambdaContextLogger.java +++ b/aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/logging/LambdaContextLogger.java @@ -7,11 +7,11 @@ import com.amazonaws.services.lambda.runtime.logging.LogFormat; import com.amazonaws.services.lambda.runtime.logging.LogLevel; -import static java.nio.charset.StandardCharsets.UTF_8; import java.io.Closeable; import java.io.IOException; +import static java.nio.charset.StandardCharsets.UTF_8; -public class LambdaContextLogger extends AbstractLambdaLogger implements Closeable{ +public class LambdaContextLogger extends AbstractLambdaLogger implements Closeable { // If a null string is passed in, replace it with "null", // replicating the behavior of System.out.println(null); private static final byte[] NULL_BYTES_VALUE = "null".getBytes(UTF_8);