Comprehensive developer toolkit providing reusable skills for Java/Spring Boot, TypeScript/NestJS/React/Next.js, Python, PHP, AWS CloudFormation, AI/RAG, DevOps, and more.
82
82%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Risky
Do not use without reviewing
Complete guide for creating minimal AWS Lambda functions in pure Java without frameworks.
plugins {
id 'java'
id 'com.github.johnrengelman.shadow' version '8.1.1'
}
group = 'com.example'
version = '1.0.0'
java {
sourceCompatibility = JavaVersion.VERSION_21
targetCompatibility = JavaVersion.VERSION_21
}
repositories {
mavenCentral()
}
dependencies {
// AWS Lambda Core
implementation 'com.amazonaws:aws-lambda-java-core:1.2.3'
implementation 'com.amazonaws:aws-lambda-java-events:3.11.4'
implementation 'com.amazonaws:aws-lambda-java-log4j2:1.5.1'
// JSON Processing (choose one)
implementation 'com.fasterxml.jackson.core:jackson-databind:2.16.0'
// Or use org.json for minimal size
// implementation 'org.json:json:20231013'
// AWS SDK (optional - include only what you need)
implementation 'software.amazon.awssdk:dynamodb:2.21.0'
// Testing
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
testImplementation 'org.mockito:mockito-core:5.7.0'
}
test {
useJUnitPlatform()
}
shadowJar {
archiveClassifier = ''
mergeServiceFiles()
}<project xmlns="http://maven.apache.org/POM/4.0.0">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>raw-java-lambda</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-core</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-lambda-java-events</artifactId>
<version>3.11.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.16.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>raw-java-lambda/
├── build.gradle (or pom.xml)
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com/example/
│ │ │ ├── Handler.java
│ │ │ ├── service/
│ │ │ │ ├── UserService.java
│ │ │ │ └── UserServiceImpl.java
│ │ │ ├── model/
│ │ │ │ └── User.java
│ │ │ └── util/
│ │ │ └── JsonUtil.java
│ │ └── resources/
│ │ └── log4j2.xml
│ └── test/
│ └── java/
│ └── com/example/
│ └── HandlerTest.java
└── serverless.yml (or template.yaml)package com.example;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import com.example.service.UserService;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.Map;
public class Handler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
// Static initialization for reuse across invocations
private static final ObjectMapper mapper = new ObjectMapper();
private static final UserService userService = new UserServiceImpl();
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent request, Context context) {
try {
context.getLogger().log("Processing request: " + request.getHttpMethod() + " " + request.getPath());
String method = request.getHttpMethod();
String path = request.getPath();
return switch (method) {
case "GET" -> handleGet(request, context);
case "POST" -> handlePost(request, context);
case "PUT" -> handlePut(request, context);
case "DELETE" -> handleDelete(request, context);
default -> createResponse(405, "{\"error\": \"Method not allowed\"}");
};
} catch (Exception e) {
context.getLogger().log("Error: " + e.getMessage());
return createResponse(500, "{\"error\": \"Internal server error\"}");
}
}
private APIGatewayProxyResponseEvent handleGet(APIGatewayProxyRequestEvent request, Context context) {
String userId = request.getPathParameters().get("id");
User user = userService.findById(userId);
if (user == null) {
return createResponse(404, "{\"error\": \"User not found\"}");
}
try {
String body = mapper.writeValueAsString(user);
return createResponse(200, body);
} catch (Exception e) {
return createResponse(500, "{\"error\": \"Serialization error\"}");
}
}
private APIGatewayProxyResponseEvent handlePost(APIGatewayProxyRequestEvent request, Context context) {
try {
User user = mapper.readValue(request.getBody(), User.class);
User created = userService.create(user);
String body = mapper.writeValueAsString(created);
return createResponse(201, body);
} catch (Exception e) {
return createResponse(400, "{\"error\": \"Invalid request body\"}");
}
}
private APIGatewayProxyResponseEvent handlePut(APIGatewayProxyRequestEvent request, Context context) {
// Implementation
return createResponse(200, "{\"message\": \"Updated\"}");
}
private APIGatewayProxyResponseEvent handleDelete(APIGatewayProxyRequestEvent request, Context context) {
String userId = request.getPathParameters().get("id");
userService.delete(userId);
return createResponse(204, "");
}
private APIGatewayProxyResponseEvent createResponse(int statusCode, String body) {
return new APIGatewayProxyResponseEvent()
.withStatusCode(statusCode)
.withBody(body)
.withHeaders(Map.of(
"Content-Type", "application/json",
"Access-Control-Allow-Origin", "*"
));
}
}package com.example;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestStreamHandler;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.io.*;
import java.nio.charset.StandardCharsets;
public class StreamHandler implements RequestStreamHandler {
private static final ObjectMapper mapper = new ObjectMapper();
@Override
public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException {
try {
// Parse input
JsonNode root = mapper.readTree(inputStream);
String action = root.path("action").asText();
// Process based on action
String result = switch (action) {
case "process" -> processData(root);
case "transform" -> transformData(root);
default -> "{\"error\": \"Unknown action\"}";
};
// Write output
outputStream.write(result.getBytes(StandardCharsets.UTF_8));
} catch (Exception e) {
String error = "{\"error\": \"" + e.getMessage() + "\"}";
outputStream.write(error.getBytes(StandardCharsets.UTF_8));
}
}
private String processData(JsonNode input) {
// Processing logic
return "{\"status\": \"processed\"}";
}
private String transformData(JsonNode input) {
// Transformation logic
return "{\"status\": \"transformed\"}";
}
}package com.example;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.S3Event;
import com.amazonaws.services.lambda.runtime.events.models.s3.S3EventNotification;
public class S3Handler implements RequestHandler<S3Event, String> {
@Override
public String handleRequest(S3Event event, Context context) {
for (S3EventNotification.S3EventNotificationRecord record : event.getRecords()) {
String bucket = record.getS3().getBucket().getName();
String key = record.getS3().getObject().getKey();
context.getLogger().log("Processing s3://" + bucket + "/" + key);
// Process the S3 object
processS3Object(bucket, key, context);
}
return "Processed " + event.getRecords().size() + " records";
}
private void processS3Object(String bucket, String key, Context context) {
// Implementation
}
}package com.example;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.s3.S3Client;
/**
* Application context singleton for caching initialized services.
* Initialized once on first Lambda container creation, reused for warm invocations.
*/
public final class ApplicationContext {
// Singleton instance
private static volatile ApplicationContext instance;
private static final Object lock = new Object();
// Cached clients
private final DynamoDbClient dynamoDbClient;
private final S3Client s3Client;
private final String usersTableName;
private ApplicationContext() {
// Initialize AWS clients
this.dynamoDbClient = DynamoDbClient.create();
this.s3Client = S3Client.create();
// Load configuration from environment
this.usersTableName = System.getenv("USERS_TABLE");
if (usersTableName == null) {
throw new IllegalStateException("USERS_TABLE environment variable required");
}
// Pre-warm connections if needed
validateConnections();
}
public static ApplicationContext getInstance() {
if (instance == null) {
synchronized (lock) {
if (instance == null) {
instance = new ApplicationContext();
}
}
}
return instance;
}
private void validateConnections() {
// Optional: Verify connections work
dynamoDbClient.listTables();
}
public DynamoDbClient getDynamoDbClient() {
return dynamoDbClient;
}
public S3Client getS3Client() {
return s3Client;
}
public String getUsersTableName() {
return usersTableName;
}
}package com.example.service;
import com.example.ApplicationContext;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.*;
public class DynamoDbUserService implements UserService {
// Lazy-loaded via singleton
private final DynamoDbClient dynamoDb;
private final String tableName;
public DynamoDbUserService() {
ApplicationContext ctx = ApplicationContext.getInstance();
this.dynamoDb = ctx.getDynamoDbClient();
this.tableName = ctx.getUsersTableName();
}
@Override
public User findById(String id) {
GetItemRequest request = GetItemRequest.builder()
.tableName(tableName)
.key(Map.of("id", AttributeValue.builder().s(id).build()))
.build();
GetItemResponse response = dynamoDb.getItem(request);
if (!response.hasItem()) {
return null;
}
return mapToUser(response.item());
}
@Override
public User create(User user) {
PutItemRequest request = PutItemRequest.builder()
.tableName(tableName)
.item(mapFromUser(user))
.conditionExpression("attribute_not_exists(id)")
.build();
dynamoDb.putItem(request);
return user;
}
@Override
public void delete(String id) {
DeleteItemRequest request = DeleteItemRequest.builder()
.tableName(tableName)
.key(Map.of("id", AttributeValue.builder().s(id).build()))
.build();
dynamoDb.deleteItem(request);
}
private User mapToUser(Map<String, AttributeValue> item) {
User user = new User();
user.setId(item.get("id").s());
user.setName(item.get("name").s());
user.setEmail(item.get("email").s());
return user;
}
private Map<String, AttributeValue> mapFromUser(User user) {
Map<String, AttributeValue> item = new HashMap<>();
item.put("id", AttributeValue.builder().s(user.getId()).build());
item.put("name", AttributeValue.builder().s(user.getName()).build());
item.put("email", AttributeValue.builder().s(user.getEmail()).build());
return item;
}
}package com.example;
import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEvent;
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEvent;
import com.example.service.DynamoDbUserService;
import com.example.service.UserService;
import com.fasterxml.jackson.databind.ObjectMapper;
public class Handler implements RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> {
// Static initialization - runs once per container
private static final ObjectMapper mapper = new ObjectMapper();
private static final UserService userService = new DynamoDbUserService();
@Override
public APIGatewayProxyResponseEvent handleRequest(APIGatewayProxyRequestEvent request, Context context) {
// Log initialization timing
long startTime = System.currentTimeMillis();
try {
// Process request using cached services
String userId = request.getPathParameters().get("id");
User user = userService.findById(userId);
long duration = System.currentTimeMillis() - startTime;
context.getLogger().log("Request processed in " + duration + "ms");
return new APIGatewayProxyResponseEvent()
.withStatusCode(200)
.withBody(mapper.writeValueAsString(user));
} catch (Exception e) {
context.getLogger().log("Error: " + e.getMessage());
return new APIGatewayProxyResponseEvent()
.withStatusCode(500)
.withBody("{\"error\": \"Internal error\"}");
}
}
}// build.gradle
shadowJar {
archiveClassifier = ''
mergeServiceFiles()
// Exclude unnecessary files to reduce size
exclude 'META-INF/*.SF'
exclude 'META-INF/*.DSA'
exclude 'META-INF/*.RSA'
exclude 'META-INF/LICENSE*'
exclude 'META-INF/NOTICE*'
exclude 'META-INF/DEPENDENCIES'
// Minimize to remove unused dependencies
minimize {
// Keep these packages even if not directly referenced
exclude(dependency('com.amazonaws:.*'))
exclude(dependency('software.amazon.awssdk:.*'))
exclude(dependency('org.apache.logging.log4j:.*'))
}
}// build.gradle - custom tasks
tasks.register('packageForLambda', Zip) {
from(shadowJar.outputs)
archiveFileName = "function.zip"
destinationDirectory = layout.buildDirectory.dir('distributions')
}
tasks.register('deployLocal', Copy) {
dependsOn shadowJar
from shadowJar.outputs
into layout.buildDirectory.dir('sam-local')
}<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.5.1</version>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
<exclude>META-INF/LICENSE*</exclude>
<exclude>META-INF/NOTICE*</exclude>
</excludes>
</filter>
</filters>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
</transformers>
</configuration>
</execution>
</executions>
</plugin># serverless.yml
provider:
name: aws
runtime: java21
environment:
# Optimize for short-lived Lambda
JAVA_TOOL_OPTIONS: >-
-XX:+TieredCompilation
-XX:TieredStopAtLevel=1
-XX:+UseSerialGC
-Xmx256m
-XX:MaxMetaspaceSize=128mFor maximum cold start reduction, consider GraalVM native image:
# Dockerfile for custom runtime
FROM ghcr.io/graalvm/graalvm-ce:ol9-java21-21.0.2 AS builder
WORKDIR /app
COPY . .
RUN ./gradlew nativeCompile
FROM public.ecr.aws/lambda/provided:al2023
COPY --from=builder /app/build/native/nativeCompile/my-app ${LAMBDA_RUNTIME_DIR}/bootstrap
CMD ["com.example.Handler"]| JAR Size | Min Memory | Recommended | Notes |
|---|---|---|---|
| < 10MB | 256MB | 512MB | Simple handlers |
| 10-50MB | 512MB | 1024MB | With AWS SDK |
| > 50MB | 1024MB | 1769MB | Large dependencies |
Typical cold start times for Raw Java (512MB):
Warm start times: typically < 10ms
<!-- src/main/resources/log4j2.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Lambda name="Lambda">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %X{AWSRequestId} %-5p %c{1} - %m%n</pattern>
</PatternLayout>
</Lambda>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Lambda"/>
</Root>
<Logger name="software.amazon.awssdk" level="warn"/>
</Loggers>
</Configuration>plugins
developer-kit-ai
skills
chunking-strategy
prompt-engineering
developer-kit-aws
skills
aws
aws-cli-beast
aws-cost-optimization
aws-drawio-architecture-diagrams
aws-sam-bootstrap
aws-cloudformation
aws-cloudformation-auto-scaling
references
aws-cloudformation-bedrock
references
aws-cloudformation-cloudfront
references
aws-cloudformation-cloudwatch
references
aws-cloudformation-dynamodb
references
aws-cloudformation-ec2
aws-cloudformation-ecs
references
aws-cloudformation-elasticache
aws-cloudformation-iam
references
aws-cloudformation-lambda
references
aws-cloudformation-rds
aws-cloudformation-s3
references
aws-cloudformation-security
references
aws-cloudformation-task-ecs-deploy-gh
aws-cloudformation-vpc
developer-kit-core
skills
developer-kit-java
skills
aws-lambda-java-integration
aws-rds-spring-boot-integration
aws-sdk-java-v2-bedrock
aws-sdk-java-v2-core
aws-sdk-java-v2-dynamodb
aws-sdk-java-v2-kms
aws-sdk-java-v2-lambda
aws-sdk-java-v2-messaging
aws-sdk-java-v2-rds
aws-sdk-java-v2-s3
aws-sdk-java-v2-secrets-manager
graalvm-native-image
langchain4j
langchain4j-mcp-server-patterns
langchain4j-ai-services-patterns
references
langchain4j-mcp-server-patterns
references
langchain4j-rag-implementation-patterns
references
langchain4j-spring-boot-integration
langchain4j-testing-strategies
langchain4j-tool-function-calling-patterns
langchain4j-vector-stores-configuration
references
qdrant
references
spring-ai-mcp-server-patterns
references
spring-boot-actuator
spring-boot-cache
spring-boot-crud-patterns
spring-boot-dependency-injection
spring-boot-event-driven-patterns
spring-boot-openapi-documentation
spring-boot-project-creator
spring-boot-resilience4j
spring-boot-rest-api-standards
spring-boot-saga-pattern
spring-boot-security-jwt
assets
references
scripts
spring-boot-test-patterns
spring-data-jpa
references
spring-data-neo4j
references
unit-test-application-events
unit-test-bean-validation
unit-test-boundary-conditions
unit-test-caching
unit-test-config-properties
unit-test-controller-layer
unit-test-exception-handler
unit-test-json-serialization
unit-test-mapper-converter
unit-test-parameterized
unit-test-scheduled-async
unit-test-service-layer
unit-test-utility-methods
unit-test-wiremock-rest-api
developer-kit-php
skills
aws-lambda-php-integration
developer-kit-python
skills
aws-lambda-python-integration
developer-kit-tools
developer-kit-typescript
skills
aws-lambda-typescript-integration
better-auth
drizzle-orm-patterns
dynamodb-toolbox-patterns
references
nestjs
nestjs-best-practices
nestjs-code-review
nestjs-drizzle-crud-generator
scripts
nextjs-app-router
nextjs-authentication
nextjs-code-review
nextjs-data-fetching
references
nextjs-deployment
nextjs-performance
nx-monorepo
react-code-review
react-patterns
references
shadcn-ui
tailwind-css-patterns
references
tailwind-design-system
references
turborepo-monorepo
typescript-docs
typescript-security-review
zod-validation-utilities