# Running xlyEntry locally

This page is the developer onboarding path: clone the repo, get
`xlyEntry` started on your machine, and hit a framework endpoint. The
companion [Multi-service deployment](deployment.md) page covers the
operator view (multiple services, profile permutations, nginx).

## Prerequisites

| Tool | Version notes |
|---|---|
| JDK 8 | `xly-src/build.gradle` pins `sourceCompatibility = 1.8`. JDK 11+ has not been validated. |
| Gradle wrapper | Bundled (`./gradlew`). Don't install Gradle separately. |
| MySQL 8 | Driver `com.mysql.cj.jdbc.Driver`. The schema in your DB must match what the active profile yaml points at — see "DB override" below. |
| Redis | The `local` profile expects `127.0.0.1:16379` with password `xlyXLY2015` (see `xlyEntry/src/main/resources/application-local.yml`). |
| ActiveMQ + MongoDB | The `local` profile points at `t0.xlyprint.com` for both. If you have network access to that host, you don't need to run them locally. |

For the full library inventory the runtime brings up — Spring Boot
2.2.5, MyBatis 2.1.2, Druid, Activiti, Shiro, iText, Aspose, and the
rest — see [Tech stack](tech-stack.md).

The auto-catalog generator (`scripts/gen_catalog.py`) is unrelated to
running xly — it only reads schema metadata via `~/.my.cnf`. See
[Contributing](../../contributing/index.md) for that path.

## DB override

The committed `xlyEntry/src/main/resources/application-local.yml` has
`spring.datasource.url` pointing at a remote dev DB. Most developers
override that to a local-or-personal target. Two options:

1. **Edit the yaml** in your working tree. Don't commit the change.
2. **Override at the JVM level** with `-Dspring.datasource.url=...`
   when invoking `bootRun`.

The wiki's recon scripts use `~/.my.cnf` for `xlyweberp_saas_ai` —
that's a *different* schema than what `application-local.yml` ships
with (`xlyweberp_saas`). Pick one schema and stay consistent.

## Run

From `xly-src/`:

```bash
./gradlew :xlyEntry:bootRun -Dspring.profiles.active=local
```

`xlyEntry` is packaged as a WAR (see its `build.gradle`) but Spring
Boot's embedded Tomcat is what `bootRun` uses, so no external Tomcat
deploy is needed for development.

## Smoke check

Once startup completes (look for `Tomcat started on port(s): 8080`):

| URL | What you should see |
|---|---|
| `http://localhost:8080/xlyEntry/` | The framework landing page. Unauthenticated pages render; authenticated ones bounce to `/login`. |
| `http://localhost:8080/xlyEntry/druid/` | The Druid datasource monitor. Default credentials `xly` / `666666` are in the yaml — change them before exposing the port. |

If the smoke check fails, look in the log directory configured at
`logging.dirpath` in the active profile yaml.

## What `local` does and doesn't include

The `local` profile boots **only** the framework runtime. It does not
boot:

- `xlyApi` — start it as a second JVM if you need the external API surface.
- `xlyInterface` — same.
- `xlyPlc`, `xlyFlow`, `xlyFace` — same; each has its own application class and profile.
- The `xlyErpJms*` consumers — they are standalone Spring Boot apps. Without them, ActiveMQ base-data merge and document fan-out jobs will not run. Redis cache invalidation for BACK saves still works through synchronous `@CacheEvict`.

For multi-service local development, see
[Multi-service deployment](deployment.md).

## When startup fails

The two most common failure modes:

1. **`Communications link failure`** — the `spring.datasource.url`
   target is unreachable from your machine. Override it (see "DB
   override").
2. **`Connection refused: t0.xlyprint.com:61616` or `:27017`** — your
   network can't reach the shared dev infra. You can either get on
   the right network, point the yaml at local instances, or comment
   out the relevant beans for the duration of your debugging session.
