Production Java: Packaging, Deployment, and Observability
Prepare Java services for production with executable JARs, containers, configuration, logging, metrics, tracing, health checks, and operational readiness.
Packaging and Containers
Java applications can be packaged as JARs and deployed directly or inside containers.
FROM eclipse-temurin:21-jre
COPY app.jar /app/app.jar
ENTRYPOINT ["java", "-jar", "/app/app.jar"]
The runtime image should match the supported JDK/runtime and patch strategy. Avoid embedding secrets in image layers.
- Build artifacts should be immutable and reproducible.
- Runtime configuration belongs outside the image.
- Use a supported, patched Java runtime image.
Configuration and Environment Management
Separate code from environment-specific configuration. Configuration can come from environment variables, mounted files, secret stores, or deployment configuration.
String port = System.getenv().getOrDefault("PORT", "8080");
int httpPort = Integer.parseInt(port);
Validate configuration during startup so failures happen early. Never print credentials or tokens while diagnosing configuration.
- Validate configuration at startup.
- Keep secrets separate from ordinary configuration.
- Never log sensitive configuration values.
Logging, Metrics, and Distributed Tracing
Logs explain events; metrics explain trends; traces explain request flow across services.
logger.info("Order completed: orderId={}, durationMs={}",
orderId, durationMs);
Useful production metrics include request rate, error rate, latency, saturation, queue depth, database pool usage, and JVM/GC health. Observability data itself should be treated as sensitive.
- Use logs, metrics, and traces together.
- Correlation IDs make distributed debugging easier.
- Observability data must be treated as sensitive production data.
Health Checks and Graceful Shutdown
Production services need readiness and liveness concepts. Readiness answers whether the service should receive traffic; liveness answers whether the process is alive enough for the platform to keep it running.
Graceful shutdown stops accepting new work, allows in-flight work to finish within a deadline, closes resources, and exits.
SIGTERM
|
v
Stop new traffic
|
v
Finish in-flight work
|
v
Close pools / clients
|
v
Exit
- Readiness and liveness serve different purposes.
- Graceful shutdown prevents dropped work during deployments.
- Health checks should reflect meaningful service capability.