Series MapLesson 25 / 34
Deepen PracticeOrdered learning track

Learn Java Jersey Glassfish Part 025 Deployment Topologies Traditional Containerized Embedded

18 min read3577 words
PrevNext
Lesson 2534 lesson track1928 Deepen Practice

title: Learn Java Eclipse Jersey & GlassFish - Part 025 description: Production deployment topologies for Jersey applications on GlassFish: traditional server, containerized runtime, embedded GlassFish, Kubernetes, configuration injection, lifecycle, and rollout models. series: learn-java-jersey-glassfish seriesTitle: Learn Java Eclipse Jersey & GlassFish order: 25 partTitle: Deployment Topologies: Traditional, Containerized, Embedded tags:

  • java
  • jersey
  • glassfish
  • jakarta-ee
  • deployment
  • docker
  • kubernetes
  • architecture
  • production
  • series date: 2026-06-28

Part 025 — Deployment Topologies: Traditional, Containerized, Embedded

Goal: setelah bagian ini, kita tidak hanya bisa menjalankan WAR di GlassFish. Kita bisa memilih, menjelaskan, mengoperasikan, dan mempertahankan deployment topology Jersey + GlassFish berdasarkan constraint production: release safety, runtime mutability, config drift, network boundary, operational ownership, rollback, scalability, dan diagnosability.

Pada seri sebelumnya kita sudah membahas Jersey runtime, provider/filter/interceptor, security, observability, GlassFish domain/instance/cluster, classloading, asadmin, HTTP/TLS/thread pool, JDBC/JTA, dan monitoring. Bagian ini menggabungkan semua itu menjadi deployment topology model.

Kita akan membahas tiga model utama:

  1. Traditional managed GlassFish — server dipasang sebagai platform runtime, aplikasi dideploy ke domain/instance/cluster.
  2. Containerized GlassFish — GlassFish + application artifact dibungkus menjadi immutable image.
  3. Embedded GlassFish — server dijalankan dari proses aplikasi/test harness/tooling, biasanya untuk testing, dev, atau special runtime.

Kita juga akan membahas hybrid model seperti Kubernetes, blue-green, rolling update, canary, dan promotion pipeline.


1. Kaufman Deconstruction: Skill yang Sebenarnya Dipelajari

Menguasai deployment topology bukan menghafal command asadmin deploy atau membuat Dockerfile. Itu hanya surface area.

Skill yang sebenarnya:

Sub-skillYang Harus DikuasaiFailure Jika Lemah
Runtime boundaryApa yang immutable, mutable, externalizedConfig drift, environment-specific bug
Artifact boundaryWAR/EAR/image/domain configDependency conflict, non-reproducible release
Lifecyclestartup, readiness, liveness, shutdown, drainrequest hilang saat deploy, corrupt transaction
Network boundaryproxy, listener, TLS, context root, portwrong URL, redirect bug, TLS mismatch
Resource boundaryJDBC/JMS/security/secret/configapp works locally, fails in prod
Rollout safetyrollback, blue-green, canary, rollingoutage karena deployment tidak reversible
Observabilitylogs, metrics, health, dumps, traceincident berbasis tebakan
Ownershipapp team vs platform teamunclear responsibility, slow recovery

Mental modelnya:

Deployment topology adalah keputusan tentang di mana boundary dibuat.


2. Baseline Modern untuk Seri Ini

Baseline seri ini:

  • Java: JDK 21+.
  • Jakarta EE: Jakarta EE 11.
  • GlassFish: 8.x line.
  • Jersey: 4.x line.
  • Namespace: jakarta.*, bukan javax.*.
  • Packaging default: thin WAR untuk full application server, kecuali ada alasan kuat.

Kenapa ini penting?

Karena deployment topology sangat bergantung pada siapa yang menyediakan API dan implementation:

API / Runtime CapabilityTraditional GlassFishContainerized GlassFishEmbedded GlassFish
Jakarta REST APIServer-providedImage-provided serverEmbedded runtime dependency
Jersey implementationServer-provided / app-bundled dengan hati-hatiImage-provided atau app-bundledApp dependency
CDI/JTA/JDBC resourceServer-managedImage/server-managed + env configProgrammatic/test-managed
Domain configMutable platform configIdeally baked/scriptedProgrammatic/minimal
Upgrade modelUpgrade platform/runtime separatelyRebuild imageUpgrade app dependency/runtime

Prinsip dasar:

Di full application server, jangan perlakukan GlassFish seperti servlet container kosong. Ia sudah menyediakan banyak API dan implementation. Deployment artifact harus menghormati runtime contract itu.


3. Deployment Topology Decision Matrix

Gunakan matrix ini sebagai titik awal.

ConstraintTraditional Managed ServerContainerized GlassFishEmbedded GlassFish
Existing enterprise opsSangat cocokCocok jika platform sudah container-readyJarang cocok
Immutable deploymentLemah jika manualSangat cocokCocok untuk tool/test
Multi-app shared serverCocokKurang idealTidak cocok
Kubernetes-nativeBisa, tapi awkwardSangat cocokTidak umum
Heavy Jakarta EE featuresSangat cocokCocokTerbatas/lebih kompleks
Fast local testingSedangSedangSangat cocok
Runtime drift controlPerlu disiplin asadminLebih mudahApp-controlled
Rollback artifactDeploy previous WARRollback image/tagRestart process with previous build
Platform team ownershipKuatShared app/platformApp team
Classloading simplicitySedangSedangBisa kompleks karena dependencies

Tidak ada topology yang selalu benar. Yang benar adalah topology yang membuat invariant production paling mudah dijaga.


4. Topology A: Traditional Managed GlassFish

Ini model klasik application server:

Artifact utama biasanya:

  • WAR untuk Jersey web application.
  • EAR jika ada banyak module Jakarta EE yang perlu di-bundle sebagai satu application boundary.
  • External configuration di domain/instance: JDBC pool, JMS, realm, JVM options, listener, logging.

4.1 Kapan Traditional Managed Server Masuk Akal

Model ini masuk akal jika:

  • Organisasi sudah punya platform GlassFish/Payara/Jakarta EE server yang dikelola tim infra.
  • Ada banyak aplikasi yang berbagi standard runtime.
  • Ada kebutuhan admin model, cluster, domain config, resource targeting.
  • Deployment bukan hanya app artifact, tetapi juga resource binding seperti JDBC/JTA/security realm.
  • Regulated environment butuh audit trail atas perubahan konfigurasi server.

4.2 Core Invariant

Traditional topology punya invariant:

Server adalah platform runtime yang hidup lebih lama daripada satu release aplikasi.

Konsekuensinya:

  • Aplikasi tidak boleh membawa semua dependency sembarangan.
  • Config server harus dikelola seperti source code.
  • Upgrade server bisa memengaruhi banyak aplikasi.
  • Classloader conflict harus dianggap sebagai risiko arsitektural.
  • Rollback aplikasi tidak otomatis rollback config server.

4.3 Deployment Flow yang Defensible

Flow yang sehat:

Yang harus dihindari:

# Anti-pattern: manual ad-hoc deployment tanpa traceability
asadmin deploy target/my-app.war

Yang lebih baik:

#!/usr/bin/env bash
set -euo pipefail

APP_NAME="regulatory-case-api"
ARTIFACT="/opt/releases/${APP_NAME}/${BUILD_VERSION}/${APP_NAME}.war"
TARGET="prod-cluster"
CONTEXT_ROOT="/case-api"

asadmin --terse=false list-applications --target "$TARGET"

asadmin deploy \
  --name "$APP_NAME" \
  --contextroot "$CONTEXT_ROOT" \
  --target "$TARGET" \
  --force=true \
  "$ARTIFACT"

curl --fail --silent "https://api.example.com${CONTEXT_ROOT}/health/ready"

4.4 Configuration Boundary

Pisahkan:

Jenis ConfigLokasi IdealContoh
Build configGit/build toolJava version, dependency versions
Deployment configdeployment repo/scripttarget cluster, context root
Runtime resource configGlassFish domain config as codeJDBC pool, thread pool, JVM options
Secretssecret manager / protected envDB password, token signing key
Feature behaviorapp config service/envfeature flag, threshold

Jangan memasukkan credential ke WAR.

4.5 Operational Failure Model

SymptomLikely Root CauseDiagnosis
Deploy succeeds, endpoint 404context root/path mismatchlist-applications, server log, resource model log
Works dev, fails prodmissing JNDI resourcelist-jdbc-resources, deployment log
NoSuchMethodErrorruntime/app dependency mismatchdependency tree + classloader inspection
Startup slowclasspath scan, CDI discovery, DB initstartup log, thread dump
First request slowlazy init, pool warmupwarmup endpoint, metrics
Requests fail during deployno drain or bad rolling sequenceLB logs, server lifecycle events

4.6 Traditional Deployment Pattern

Pattern yang defensible:

  1. Artifact immutable.
  2. Config scripted.
  3. Environment promotion explicit.
  4. Pre-flight validation sebelum deploy.
  5. Health check setelah deploy.
  6. Traffic switch/drain controlled.
  7. Rollback command tested.
  8. Server logs, access logs, metrics, dumps available.

5. Topology B: Containerized GlassFish

Containerized topology membungkus GlassFish runtime dan application artifact ke image.

Core invariant:

Image adalah deployment unit. Runtime, app artifact, and most baseline config harus reproducible dari image build.

5.1 Kapan Containerized GlassFish Masuk Akal

Cocok jika:

  • Platform production adalah Kubernetes/OpenShift/Nomad/ECS.
  • Tim ingin immutable infrastructure.
  • Rollback berbasis image tag lebih mudah daripada server mutation.
  • Setiap service punya runtime sendiri.
  • Scaling horizontal lebih penting daripada multi-app shared server.
  • App adalah REST service stateless.

Kurang cocok jika:

  • Anda sangat bergantung pada shared domain/cluster admin model lama.
  • Banyak aplikasi kecil berbagi satu server karena lisensi/ops constraint.
  • Runtime config sangat manual dan belum bisa di-script.
  • App bergantung pada local server state.

5.2 Image Design: Mutable vs Immutable

Bad image:

# Anti-pattern
FROM eclipse-temurin:21
COPY glassfish.zip /tmp/
RUN unzip /tmp/glassfish.zip -d /opt
COPY app.war /tmp/app.war
CMD ["/opt/glassfish/bin/asadmin", "start-domain", "--verbose"]

Masalah:

  • App belum tentu dideploy saat image dibuat.
  • Config bisa berubah saat runtime tanpa trace.
  • Startup script mungkin melakukan terlalu banyak hal non-idempotent.
  • Readiness tidak mencerminkan app ready.

Lebih defensible:

FROM eclipse-temurin:21-jre

ARG GLASSFISH_HOME=/opt/glassfish
ARG APP_NAME=regulatory-case-api

ENV GLASSFISH_HOME=${GLASSFISH_HOME}
ENV PATH="${GLASSFISH_HOME}/bin:${PATH}"

COPY glassfish8/ ${GLASSFISH_HOME}/
COPY target/${APP_NAME}.war /opt/app/${APP_NAME}.war
COPY docker/configure-glassfish.sh /opt/app/configure-glassfish.sh
COPY docker/entrypoint.sh /opt/app/entrypoint.sh

RUN chmod +x /opt/app/*.sh \
    && /opt/app/configure-glassfish.sh

EXPOSE 8080 8181

ENTRYPOINT ["/opt/app/entrypoint.sh"]

Entry point:

#!/usr/bin/env bash
set -euo pipefail

asadmin start-domain

# Apply runtime values that legitimately vary per environment.
asadmin set configs.config.server-config.system-property.DB_HOST.value="${DB_HOST}"
asadmin set configs.config.server-config.system-property.DB_PORT.value="${DB_PORT:-5432}"

asadmin deploy \
  --name regulatory-case-api \
  --contextroot /case-api \
  --force=true \
  /opt/app/regulatory-case-api.war

asadmin stop-domain

exec asadmin start-domain --verbose

Namun perlu hati-hati: deploy saat container startup membuat startup lambat dan bisa gagal karena environment. Alternatifnya adalah pre-deploy saat image build, jika semua config tidak environment-specific.

5.3 Pre-deploy vs Startup Deploy

ModelKelebihanKekurangan
Deploy saat image buildStartup lebih predictable, artifact immutableSulit jika deployment butuh env-specific resource
Deploy saat container startupFleksibel per envStartup lebih lambat, failure lebih runtime-ish
External deploy ke running containerMirip traditionalMelawan immutable container model

Rule of thumb:

  • Untuk Kubernetes stateless service: pre-configure sebanyak mungkin, inject hanya secrets/env-specific values saat runtime.
  • Hindari manual deployment ke container yang sudah berjalan.

5.4 Runtime Filesystem Boundary

Container yang sehat:

PathSifatContoh
Image layerimmutableserver binaries, app artifact, baseline config
Ephemeral writabletemporarytemp files, exploded app, generated cache
Mounted secretruntime protectedDB password, cert key
Persistent volumeavoid unless neededuploaded files, local queue, generated reports

Untuk REST service, local persistent volume sering sinyal buruk. Biasanya lebih baik pakai object storage, database, atau external durable queue.

5.5 Kubernetes Mapping

GlassFish-specific concerns in Kubernetes:

ConcernProduction Decision
Startup timereadiness probe must wait until app deployed and warm
Shutdownuse preStop + termination grace period
Health endpointseparate liveness/readiness/startup semantics
Logswrite to stdout/stderr or ship server logs
Thread dumpexpose debug workflow, not public endpoint
Admin portdo not expose externally
Clusteringprefer platform service discovery unless GlassFish cluster features are required
Session stateavoid HTTP session for REST APIs

Example probe design:

readinessProbe:
  httpGet:
    path: /case-api/health/ready
    port: 8080
  initialDelaySeconds: 20
  periodSeconds: 10
  timeoutSeconds: 2
  failureThreshold: 6

livenessProbe:
  httpGet:
    path: /case-api/health/live
    port: 8080
  initialDelaySeconds: 60
  periodSeconds: 20
  timeoutSeconds: 2
  failureThreshold: 3

Do not use liveness for dependency readiness. If database is down and liveness kills all pods, you create a restart storm.

5.6 Graceful Shutdown

GlassFish/Jersey app harus punya shutdown behavior:

Checklist:

  • Readiness returns false before shutdown.
  • Stop accepting new traffic.
  • Let in-flight request complete within grace period.
  • Close client pools.
  • Close executor services.
  • Do not start long irreversible transactions during drain.
  • Make retry behavior idempotency-aware.

5.7 Admin Console in Containers

Production rule:

Admin console/port should not be internet exposed. In many container deployments, prefer disabling or restricting admin surface.

Use admin only via controlled internal network, short-lived debug access, or CI/CD automation with least privilege.


6. Topology C: Embedded GlassFish

Embedded GlassFish means GlassFish runtime is started inside a Java process.

Core invariant:

Application process owns the server lifecycle.

6.1 Kapan Embedded Masuk Akal

Embedded cocok untuk:

  • Integration testing.
  • Local developer harness.
  • Contract testing.
  • Demo/runtime sandbox.
  • Migration validation.
  • Build-time smoke tests.

Kurang cocok untuk:

  • Most production REST services.
  • Complex multi-instance clustered deployments.
  • Environments where platform team owns runtime.
  • Workloads needing full operational isolation.

6.2 Embedded Testing Pattern

class JerseyGlassFishIT {
    private static GlassFish glassFish;

    @BeforeAll
    static void start() throws Exception {
        GlassFishProperties properties = new GlassFishProperties();
        properties.setPort("http-listener", 18080);

        glassFish = GlassFishRuntime.bootstrap().newGlassFish(properties);
        glassFish.start();

        Deployer deployer = glassFish.getDeployer();
        deployer.deploy(new File("target/regulatory-case-api.war"));
    }

    @AfterAll
    static void stop() throws Exception {
        if (glassFish != null) {
            glassFish.stop();
            glassFish.dispose();
        }
    }
}

The point is not this exact API shape; the point is lifecycle ownership.

6.3 Embedded Failure Model

SymptomCauseFix
Test hangsserver not stoppedtry/finally, @AfterAll cleanup
Port conflictfixed port reusedrandom port allocation
Classloading differs from prodembedded classpath too richtest packaged WAR, not loose classes only
Test passes, prod failsmissing server config parityscript embedded resources similarly
Slow test suitestarts server per teststart once per test class/suite

6.4 Embedded vs Testcontainers

Often a better modern strategy:

  • Package WAR.
  • Start GlassFish container in Testcontainers.
  • Deploy artifact or use prebuilt image.
  • Test through real HTTP.

This gives stronger parity with containerized production than pure embedded runtime.


7. Deployment Rollout Models

7.1 Big Bang Deployment

All instances updated at once.

Use only if:

  • Maintenance window acceptable.
  • Fast rollback tested.
  • State/data migration safe.
  • Consumer impact understood.

Usually not preferred for critical APIs.

7.2 Rolling Deployment

Good for stateless services. Requires:

  • Backward-compatible API.
  • Backward-compatible DB schema.
  • No shared mutable in-memory state.
  • Readiness probe accurate.
  • Graceful drain.

7.3 Blue-Green Deployment

Steps:

  1. Deploy green without traffic.
  2. Run smoke checks.
  3. Shift traffic to green.
  4. Monitor error/latency/business metrics.
  5. Keep blue for rollback window.

Good for:

  • High-risk deployment.
  • Regulated release evidence.
  • Fast traffic rollback.

Risk:

  • Database migration compatibility must support both blue and green.

7.4 Canary Deployment

Small traffic percentage to new version.

Good when:

  • You have enough traffic volume for signal.
  • You can compare metrics by version.
  • App behavior is deterministic enough.
  • You can stop the canary quickly.

Requires:

  • Version-tagged logs/metrics.
  • Route traffic by weight/header/tenant.
  • Error budget thresholds.
  • Automatic or manual promotion rules.

7.5 Shadow Deployment

Duplicate traffic to new version but do not serve response.

Good for:

  • Performance comparison.
  • Serialization compatibility.
  • Read-only validation.

Danger:

  • Never shadow non-idempotent write operations unless safely neutralized.

8. Database Migration Coupling

Deployment topology fails when database migration is not compatible.

Safe deployment uses expand/contract:

For Jersey/GlassFish services:

  • Do not deploy app that requires a destructive DB migration at the same instant.
  • Do not assume rolling deployment means all nodes update atomically.
  • Keep old and new app versions compatible during rollout window.
  • Map database migration failure to deployment rollback plan.

9. Config Injection Patterns

9.1 Environment Variables

Good for:

  • Containerized deployment.
  • Simple scalar config.
  • Non-secret toggles.

Pitfalls:

  • Env var change requires restart.
  • Secrets in env can leak via diagnostics.
  • Complex config becomes unreadable.

9.2 JNDI / GlassFish Resources

Good for:

  • JDBC pools.
  • JMS resources.
  • Container-managed resources.
  • Traditional server deployments.

Pitfalls:

  • Missing resource fails at deploy/runtime.
  • Resource names drift across environment.
  • Manual admin console changes are hard to audit.

9.3 Config File

Good for:

  • Structured config.
  • Environment bundle.
  • Static runtime config.

Pitfalls:

  • File location differs across topology.
  • Secret handling hard.
  • Drift if edited on server.

9.4 Config Service / Feature Flag Service

Good for:

  • Dynamic behavior.
  • Gradual rollout.
  • Kill switches.

Pitfalls:

  • Startup dependency risk.
  • Runtime inconsistency.
  • Needs cache/fallback model.

Rules:

  • Centralize config resolution.
  • Validate config at startup.
  • Log non-secret effective config.
  • Fail fast for mandatory config.
  • Use safe defaults only for non-critical optional config.

10. Health Endpoint Design

Health endpoint is deployment control surface.

Recommended split:

EndpointMeaningIncludes Dependencies?Used By
/health/liveprocess is aliveNo heavy dependenciesliveness probe
/health/readycan receive trafficYes, but boundedreadiness probe / LB
/health/startupstartup completedApp-specificstartup probe
/health/deepdiagnosticYes, detailedinternal ops only

Example:

@Path("/health")
@Produces(MediaType.APPLICATION_JSON)
public class HealthResource {

    @GET
    @Path("live")
    public Response live() {
        return Response.ok(Map.of("status", "UP")).build();
    }

    @GET
    @Path("ready")
    public Response ready() {
        boolean dbReady = checkDatabaseWithin(Duration.ofMillis(200));
        boolean dependencyReady = checkCriticalDependencyWithin(Duration.ofMillis(200));

        if (dbReady && dependencyReady) {
            return Response.ok(Map.of("status", "UP")).build();
        }

        return Response.status(Response.Status.SERVICE_UNAVAILABLE)
                .entity(Map.of("status", "DOWN"))
                .build();
    }
}

Do not make readiness check slow. Health endpoints can become accidental DDoS against your database.


11. Startup and Warmup

Startup phases:

Warmup can include:

  • Build Jersey resource model.
  • Initialize JSON provider.
  • Open initial DB connections.
  • Validate mandatory JNDI resources.
  • Load static metadata.
  • Prime caches carefully.

Do not do:

  • Long backfills at startup.
  • Remote calls without timeout.
  • Unbounded cache load.
  • Schema migration inside app startup unless intentionally designed.

12. Shutdown and Drain Semantics

Shutdown must answer:

  1. When do we stop accepting new requests?
  2. How long do in-flight requests get?
  3. What happens to async requests?
  4. What happens to streaming/SSE clients?
  5. What happens to transactions?
  6. What happens to outbound Jersey Client calls?
  7. What cleanup is safe?

Pattern:

@ApplicationScoped
public class RuntimeLifecycle {
    private final AtomicBoolean draining = new AtomicBoolean(false);

    public boolean isReady() {
        return !draining.get() && criticalDependenciesReady();
    }

    public void beginDrain() {
        draining.set(true);
    }

    @PreDestroy
    public void shutdown() {
        beginDrain();
        closeClients();
        stopExecutors();
    }
}

Readiness should flip to false before shutdown completes.


13. Observability by Topology

CapabilityTraditionalContainerizedEmbedded
Server logfile/log collectorstdout/log collectortest log
Access logserver configsidecar/agent/server configusually test only
MetricsJMX/MP/agentPrometheus/agent/MPtest assertions
Thread dumpserver host toolingkubectl exec / JVM toolingtest JVM
Heap dumpserver pathephemeral/persistent volumetest path
Deployment auditasadmin log/CIimage digest + rollout eventstest report

A production topology that cannot answer “what version is serving this request?” is not production-ready.

Include version in:

  • log MDC;
  • response header for internal calls;
  • /info endpoint;
  • metrics labels;
  • deployment annotation;
  • image tag/digest.

14. Anti-Patterns

14.1 Snowflake Server

Server is manually edited until nobody can reproduce it.

Fix:

  • Use asadmin scripts.
  • Store config in Git.
  • Run drift detection.
  • Recreate environment from scratch regularly.

14.2 Mutable Container

Deploying new WAR manually into a running container.

Fix:

  • Rebuild image.
  • Redeploy immutable tag/digest.
  • Treat container as disposable.

14.3 Health Check That Lies

/health returns 200 while app cannot serve traffic.

Fix:

  • Split live/ready/startup.
  • Make readiness dependency-aware but bounded.

14.4 Liveness Depends on Database

Database outage causes orchestrator to restart every pod.

Fix:

  • Liveness checks process health only.
  • Readiness checks critical dependencies.

14.5 Release Requires Perfect Timing

App and DB migration must happen atomically.

Fix:

  • Expand/contract DB migration.
  • Backward-compatible API contract.
  • Rolling-safe deployment design.

14.6 App Writes Local Disk in Container

File disappears on restart/reschedule.

Fix:

  • Use object storage/database/queue.
  • Use local disk only for temp/cache.

14.7 Admin Surface Exposed

Admin console/API available from public network.

Fix:

  • Restrict network.
  • Disable if unnecessary.
  • Require strong auth.
  • Audit access.

15. Production-Grade Deployment Checklist

Artifact

  • Artifact has immutable version.
  • Build is reproducible.
  • Dependency scope checked.
  • SBOM generated if required.
  • Artifact promoted, not rebuilt per environment.

Runtime

  • GlassFish/JDK/Jakarta/Jersey version matrix documented.
  • JVM options scripted.
  • Resources scripted.
  • Listener/TLS/proxy config scripted.
  • Admin surface restricted.

Config

  • Mandatory config validated at startup.
  • Secrets not stored in artifact.
  • Non-secret effective config logged.
  • Environment differences documented.
  • Config rollback plan exists.

Deployment

  • Readiness/liveness/startup endpoints separated.
  • Graceful shutdown tested.
  • Rollback tested.
  • Deployment strategy selected: rolling/blue-green/canary.
  • Database migration is backward compatible.

Observability

  • Version visible in logs/metrics/info endpoint.
  • Access log enabled where needed.
  • Error rate and latency alerts exist.
  • Thread dump workflow documented.
  • Deployment events correlated with metrics.

16. Decision Tree

Use this decision tree as conversation starter, not as automatic rule.


17. Mini Case Study: Regulatory Case API

Assume service:

  • Jersey REST API.
  • GlassFish 8.
  • PostgreSQL via JDBC resource.
  • OAuth/JWT authentication.
  • Stateless requests.
  • Needs audit log.
  • Needs zero/minimal downtime.

Recommended topology:

  • Containerized GlassFish if platform is Kubernetes.
  • Thin WAR deployed into image/runtime.
  • DB pool configured via startup script/env/secret.
  • /health/live, /health/ready, /info.
  • Rolling deployment with max unavailable 0 or blue-green for high-risk release.
  • Expand/contract DB migration.
  • Structured logs with correlationId, caseId, subjectId, version.
  • Readiness false during drain.
  • Admin port not exposed.

Why not embedded?

  • Production ownership/lifecycle/observability are weaker.
  • Full server process should be operationally visible.

Why not old-style manual server?

  • Regulated environment needs repeatability and auditability.
  • Manual changes create defensibility risk.

18. Practice: 90-Minute Deployment Topology Exercise

Use this deliberate practice session:

  1. Pick one Jersey WAR from previous exercises.
  2. Define three deployment targets:
    • traditional GlassFish domain;
    • containerized GlassFish image;
    • embedded/test runtime.
  3. For each target, write:
    • artifact boundary;
    • config boundary;
    • secret boundary;
    • health endpoint behavior;
    • rollback method;
    • top 5 failure modes.
  4. Draw one Mermaid topology diagram.
  5. Write a one-page operational runbook.

The goal is not to deploy everything. The goal is to make topology decisions explicit.


19. Key Takeaways

  • Deployment topology is not an ops afterthought; it is part of application architecture.
  • Traditional GlassFish treats server as long-lived platform runtime.
  • Containerized GlassFish treats image as deployment unit.
  • Embedded GlassFish is excellent for testing/tooling, rarely the default production topology.
  • Readiness, liveness, graceful shutdown, config injection, and rollback are architectural invariants.
  • Rolling/blue-green/canary only work if API and database changes are backward compatible.
  • Production-grade deployment is the ability to reproduce, observe, drain, rollback, and explain the runtime.

20. References

  • Eclipse GlassFish Application Deployment Guide, Release 8: https://glassfish.org/docs/latest/application-deployment-guide.html
  • Eclipse GlassFish Application Development Guide: https://glassfish.org/docs/latest/application-development-guide.html
  • Eclipse GlassFish Release Notes, Release 8: https://glassfish.org/docs/latest/release-notes.html
  • Jakarta EE Platform 11 Specification: https://jakarta.ee/specifications/platform/11/
  • Eclipse GlassFish Downloads: https://glassfish.org/download
Lesson Recap

You just completed lesson 25 in deepen practice. Use the series map if you want to review the broader track, or continue directly into the next lesson while the context is still warm.

Continue The Track

Keep the momentum while the lesson is still fresh. Move backward for review or continue forward into the next concept.