aws-sdk-java-v2-bedrock — an installable skill for AI agents, published by giuseppe-trisciuoglio/developer-kit.
AWS SDK for Java 2.x - Amazon Bedrock
Overview
Invokes foundation models through AWS SDK for Java 2.x. Configures clients, builds model-specific JSON payloads, handles streaming responses with error recovery, creates embeddings for RAG, integrates generative AI into Spring Boot applications, and implements exponential backoff for resilience.
When to Use
Invoke Claude, Llama, Titan, or Stable Diffusion for text/image generation
Configure BedrockClient and BedrockRuntimeClient instances
Build and parse model-specific payloads (Claude, Titan, Llama formats)
Stream real-time AI responses with async handlers and error recovery
Create embeddings for retrieval-augmented generation
Integrate generative AI into Spring Boot microservices
Handle throttling with exponential backoff retry logic
Quick Start
Dependencies
<!-- Bedrock (model management) -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bedrock</artifactId>
</dependency>
<!-- Bedrock Runtime (model invocation) -->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>bedrockruntime</artifactId>
</dependency>
<!-- For JSON processing -->
<dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20231013</version>
</dependency>
Client Setup
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.bedrock.BedrockClient;
import software.amazon.awssdk.services.bedrockruntime.BedrockRuntimeClient;
// Model management client
BedrockClient bedrockClient = BedrockClient.builder()
.region(Region.US_EAST_1)
.build();
// Model invocation client
BedrockRuntimeClient bedrockRuntimeClient = BedrockRuntimeClient.builder()
.region(Region.US_EAST_1)
.build();
Instructions
Follow these steps for production-ready Bedrock integration:
Configure AWS Credentials - Set up IAM roles with Bedrock permissions (avoid access keys)
Enable Model Access - Request access to specific foundation models in AWS Console
Initialize Clients - Create reusable BedrockClient and BedrockRuntimeClient instances
Validate Model Availability - Test with a simple invocation before production use
Build Payloads - Create model-specific JSON payloads with proper format
Handle Responses - Parse response structure and extract content
Implement Streaming - Use response stream handlers for real-time generation
Add Error Handling - Implement retry logic with exponential backoff
Validation Checkpoint: Always test with a simple prompt (e.g., "Hello") before production use to verify model access and response parsing.
Examples
Text Generation with Claude
public String generateWithClaude(BedrockRuntimeClient client, String prompt) {
JSONObject payload = new JSONObject()
.put("anthropic_version", "bedrock-2023-05-31")
.put("max_tokens", 1000)
.put("messages", new JSONObject[]{
new JSONObject().put("role", "user").put("content", prompt)
});
InvokeModelResponse response = client.invokeModel(InvokeModelRequest.builder()
.modelId("anthropic.claude-sonnet-4-5-20250929-v1:0")
.body(SdkBytes.fromUtf8String(payload.toString()))
.build());
JSONObject responseBody = new JSONObject(response.body().asUtf8String());
return responseBody.getJSONArray("content")
.getJSONObject(0)
.getString("text");
}
Model Discovery
import software.amazon.awssdk.services.bedrock.model.*;
public List<FoundationModelSummary> listFoundationModels(BedrockClient bedrockClient) {
return bedrockClient.listFoundationModels().modelSummaries();
}
Multi-Model Invocation
public String invokeModel(BedrockRuntimeClient client, String modelId, String prompt) {
JSONObject payload = createPayload(modelId, prompt);
InvokeModelResponse response = client.invokeModel(request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload.toString())));
return extractTextFromResponse(modelId, response.body().asUtf8String());
}
private JSONObject createPayload(String modelId, String prompt) {
if (modelId.startsWith("anthropic.claude")) {
return new JSONObject()
.put("anthropic_version", "bedrock-2023-05-31")
.put("max_tokens", 1000)
.put("messages", new JSONObject[]{
new JSONObject().put("role", "user").put("content", prompt)
});
} else if (modelId.startsWith("amazon.titan")) {
return new JSONObject()
.put("inputText", prompt)
.put("textGenerationConfig", new JSONObject()
.put("maxTokenCount", 512)
.put("temperature", 0.7));
} else if (modelId.startsWith("meta.llama")) {
return new JSONObject()
.put("prompt", "[INST] " + prompt + " [/INST]")
.put("max_gen_len", 512)
.put("temperature", 0.7);
}
throw new IllegalArgumentException("Unsupported model: " + modelId);
}
Streaming Response with Error Handling
public String streamResponseWithRetry(BedrockRuntimeClient client, String modelId, String prompt, int maxRetries) {
int attempt = 0;
while (attempt < maxRetries) {
try {
JSONObject payload = createPayload(modelId, prompt);
StringBuilder fullResponse = new StringBuilder();
InvokeModelWithResponseStreamRequest request = InvokeModelWithResponseStreamRequest.builder()
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload.toString()))
.build();
client.invokeModelWithResponseStream(request,
InvokeModelWithResponseStreamResponseHandler.builder()
.onEventStream(stream -> stream.forEach(event -> {
if (event instanceof PayloadPart) {
String chunk = ((PayloadPart) event).bytes().asUtf8String();
fullResponse.append(chunk);
}
}))
.onError(e -> System.err.println("Stream error: " + e.getMessage()))
.build());
return fullResponse.toString();
} catch (Exception e) {
attempt++;
if (attempt >= maxRetries) {
throw new RuntimeException("Stream failed after " + maxRetries + " attempts", e);
}
try {
Thread.sleep((long) Math.pow(2, attempt) * 1000); // Exponential backoff
} catch (InterruptedException ie) {
Thread.currentThread().interrupt();
throw new RuntimeException("Interrupted during retry", ie);
}
}
}
throw new RuntimeException("Unexpected error in streaming");
}
Exponential Backoff for Throttling
import software.amazon.awssdk.awscore.exception.AwsServiceException;
public <T> T invokeWithRetry(Supplier<T> invocation, int maxRetries) {
int attempt = 0;
while (attempt < maxRetries) {
try {
return invocation.get();
} catch (AwsServiceException e) {
if (e.statusCode() == 429 || e.statusCode() >= 500) {
attempt++;
if (attempt >= maxRetries) throw e;
long delayMs = Math.min(1000 * (1L << attempt) + (long) (Math.random() * 1000), 30000);
Thread.sleep(delayMs);
} else {
throw e;
}
}
}
throw new IllegalStateException("Should not reach here");
}
Text Embeddings
public double[] createEmbeddings(BedrockRuntimeClient client, String text) {
String modelId = "amazon.titan-embed-text-v1";
JSONObject payload = new JSONObject().put("inputText", text);
InvokeModelResponse response = client.invokeModel(request -> request
.modelId(modelId)
.body(SdkBytes.fromUtf8String(payload.toString())));
JSONObject responseBody = new JSONObject(response.body().asUtf8String());
JSONArray embeddingArray = responseBody.getJSONArray("embedding");
double[] embeddings = new double[embeddingArray.length()];
for (int i = 0; i < embeddingArray.length(); i++) {
embeddings[i] = embeddingArray.getDouble(i);
}
return embeddings;
}
Spring Boot Integration
@Configuration
public class BedrockConfiguration {
@Bean
public BedrockClient bedrockClient() {
return BedrockClient.builder()
.region(Region.US_EAST_1)
.build();
}
@Bean
public BedrockRuntimeClient bedrockRuntimeClient() {
return BedrockRuntimeClient.builder()
.region(Region.US_EAST_1)
.build();
}
}
@Service
public class BedrockAIService {
private final BedrockRuntimeClient bedrockRuntimeClient;
private final ObjectMapper mapper;
@Value("${bedrock.default-model-id:anthropic.claude-sonnet-4-5-20250929-v1:0}")
private String defaultModelId;
public BedrockAIService(BedrockRuntimeClient bedrockRuntimeClient, ObjectMapper mapper) {
this.bedrockRuntimeClient = bedrockRuntimeClient;
this.mapper = mapper;
}
public String generateText(String prompt) {
Map<String, Object> payload = Map.of(
"anthropic_version", "bedrock-2023-05-31",
"max_tokens", 1000,
"messages", List.of(Map.of("role", "user", "content", prompt))
);
InvokeModelResponse response = bedrockRuntimeClient.invokeModel(
InvokeModelRequest.builder()
.modelId(defaultModelId)
.body(SdkBytes.fromUtf8String(mapper.writeValueAsString(payload)))
.build());
return extractText(response.body().asUtf8String());
}
}
See examples directory for comprehensive usage patterns.
Best Practices
Model Selection
Claude 4.5 Sonnet: Complex reasoning, analysis, and creative tasks
Claude 4.5 Haiku: Fast and affordable for real-time applications
Llama 3.1: Open-source alternative for general tasks
Titan: AWS native, cost-effective for simple text generation
Performance
Reuse client instances (avoid creating new clients per request)
Use async clients for I/O operations
Implement streaming for long responses
Cache foundation model lists
Security
Never log sensitive prompt data
Use IAM roles for authentication
Sanitize user inputs to prevent prompt injection
Implement rate limiting for public applications
Constraints and Warnings
Cost Management: Bedrock API calls incur charges per token; implement usage monitoring and budget alerts.
Model Access: Foundation models must be enabled in AWS Console; verify region availability.
Rate Limits: Implement exponential backoff for throttling; check per-model limits.
Payload Size: Maximum payload size varies by model; use chunking for large documents.
Streaming Complexity: Handle partial content and error recovery carefully.
Data Privacy: Prompts and responses may be logged by AWS; review data policies.
Credentials: Never embed credentials in code; use IAM roles for EC2/Lambda.
Common Model IDs
Claude Sonnet 4.5: anthropic.claude-sonnet-4-5-20250929-v1:0
Claude Haiku 4.5: anthropic.claude-haiku-4-5-20251001-v1:0
Llama 3.1 70B: meta.llama3-1-70b-instruct-v1:0
Titan Embeddings: amazon.titan-embed-text-v1
See Model Reference for complete list.
References
Advanced Topics - Multi-model patterns, advanced error handling
Model Reference - Detailed specifications, payload formats
Testing Strategies - Unit testing, LocalStack integration
AWS Bedrock User Guide
AWS SDK Examples
Supported Models
Related Skills
aws-sdk-java-v2-core - Core AWS SDK patterns
langchain4j-ai-services-patterns - LangChain4j integration
spring-boot-dependency-injection - Spring DI patternsdon't have the plugin yet? install it then click "run inline in claude" again.