private static void startRuntime()

in aws-lambda-java-runtime-interface-client/src/main/java/com/amazonaws/services/lambda/runtime/api/client/AWSLambda.java [199:286]


    private static void startRuntime(String handler, LambdaLogger lambdaLogger) throws Throwable {
        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);

        String runtimeApi = getEnvOrExit(ReservedRuntimeEnvironmentVariables.AWS_LAMBDA_RUNTIME_API);
        LambdaRuntimeClient runtimeClient = new LambdaRuntimeClient(runtimeApi);

        EnvReader envReader = new EnvReader();
        try (EnvWriter envWriter = new EnvWriter(envReader)) {
            envWriter.unsetLambdaInternalEnv();
            envWriter.setupEnvironmentCredentials();
            envWriter.setupAwsExecutionEnv();
        }

        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
        UserMethods methods;
        try {
            methods = findUserMethods(handler, customerClassLoader);
        } catch (UserFault userFault) {
            lambdaLogger.log(userFault.reportableError());
            ByteArrayOutputStream payload = new ByteArrayOutputStream(1024);
            Failure failure = new Failure(userFault);
            GsonFactory.getInstance().getSerializer(Failure.class).toJson(failure, payload);
            runtimeClient.postInitError(payload.toByteArray(), failure.getErrorType());
            System.exit(1);
            return;
        }

        // Call the user's init handler(a function called 'init'), if provided in the same module as the request handler.
        // This is an undocumented feature, and still exists to keep backward compatibility. Continue if this call fails.
        try {
            methods.initHandler.run();
        } catch (UserFault f) {
            lambdaLogger.log(f.reportableError());
        }

        try (EnvWriter envWriter = new EnvWriter(envReader)) {
            boolean shouldExit = false;
            while (!shouldExit) {
                UserFault userFault = null;
                InvocationRequest request = runtimeClient.waitForNextInvocation();
                if (request.getXrayTraceId() != null) {
                    envWriter.modifyEnv(m -> m.put("_X_AMZN_TRACE_ID", request.getXrayTraceId()));
                } else {
                    envWriter.modifyEnv(m -> m.remove("_X_AMZN_TRACE_ID"));
                }

                ByteArrayOutputStream payload;
                try {
                    payload = methods.requestHandler.call(request);
                    // TODO calling payload.toByteArray() creates a new copy of the underlying buffer
                    runtimeClient.postInvocationResponse(request.getId(), payload.toByteArray());
                } catch (UserFault f) {
                    userFault = f;
                    UserFault.filterStackTrace(f);
                    payload = new ByteArrayOutputStream(1024);
                    Failure failure = new Failure(f);
                    GsonFactory.getInstance().getSerializer(Failure.class).toJson(failure, payload);
                    shouldExit = f.fatal;
                    runtimeClient.postInvocationError(request.getId(), payload.toByteArray(), failure.getErrorType());
                } catch (Throwable t) {
                    UserFault.filterStackTrace(t);
                    userFault = UserFault.makeUserFault(t);
                    payload = new ByteArrayOutputStream(1024);
                    Failure failure = new Failure(t);
                    GsonFactory.getInstance().getSerializer(Failure.class).toJson(failure, payload);
                    // These two categories of errors are considered fatal.
                    shouldExit = Failure.isInvokeFailureFatal(t);
                    runtimeClient.postInvocationError(request.getId(), payload.toByteArray(), failure.getErrorType(),
                            serializeAsXRayJson(t));
                } finally {
                    if (userFault != null) {
                        lambdaLogger.log(userFault.reportableError());
                    }
                }
            }
        }
    }