# Deploy a Java Servlet and JSP application on Yeeted

Legacy Java on purpose: a Jakarta **Servlet + JSP packaged as a WAR**, served
by Tomcat 10 via the project's **own Dockerfile**, the bring-your-own path
where the platform synthesizes nothing and deploys the Dockerfile verbatim.

The store is in-memory and dependency-free by design; this sample's job is
the deployment shape, and the Go/Node/Python samples already carry the
database and cache wiring.

Tests: `mvn test` (JUnit 5 on the store + validation) · `./smoke.sh
https://...` against a deployment. The WAR builds with `mvn package`
(finalName ROOT so the app owns `/`).

## Run locally

Use JDK 21 and Maven to run the store tests and build the WAR:

```sh
mvn test
mvn package
```

To run the full application with Docker, from `java/shorten-servlet`:

```sh
docker build -t yeeted-shorten-servlet .
docker run --rm -p 8080:8080 yeeted-shorten-servlet
```

Open `http://localhost:8080`. The multi-stage Dockerfile builds `ROOT.war`
and serves it with Tomcat. The app's in-memory store is reset on restart.

## Deploy and verify

Follow the [deployment walkthrough](getting-started.md). Deploy this
folder with its existing Dockerfile, `pom.xml`, source, and manifest. Request
no database. The manifest selects port 8080 and `/healthz`.

```sh
sh smoke.sh "$PREVIEW_URL"
curl -i "$PREVIEW_URL/api/links" --data-urlencode 'url=https://yeeted.ai/'
```

Unlike the Go shortener, this endpoint expects form data, not JSON. A valid
write returns 201 and a JSON response with a `short` path under `/p/`.
Request that path without following redirects to see 302 and the original
URL in `Location`. Invalid URLs return 400; a full store returns 503.

## What to change before real use

This demonstrates packaging and deployment of a WAR, not durable storage.
There is no authentication, and every replica would have its own separate
link store. Add a shared persistent store and application access controls
before adapting it into a public shortening service.

[All examples](index.md) · [Deploy an example](getting-started.md)
