# Installation (/docs/java/installation)

Tracepanel for Java is three libraries on Maven Central, under
`dev.tracepanel`: `tracepanel-spring-boot` and `tracepanel-ktor`, and
`tracepanel-core` that both depend on. Your app adds one of the first two.
See the [changelog](https://github.com/tracepanel/tracepanel-java/blob/main/CHANGELOG.md).

## Add it to your app [#add-it-to-your-app]

<Tabs items={["Spring Boot (Gradle)", "Spring Boot (Maven)", "Ktor"]}>
  <Tab value="Spring Boot (Gradle)">

Add the dependency for development only, so the production build leaves it
out:

```kotlin
// build.gradle.kts
dependencies {
    developmentOnly("dev.tracepanel:tracepanel-spring-boot:0.3.1")
}
```

Run the app with the `dev` profile, or with Spring Boot DevTools among its
dependencies:

```bash
./gradlew bootRun --args='--spring.profiles.active=dev'
```

Spring Boot picks up Tracepanel by its auto-configuration: there is no code to
add.

  </Tab>
  <Tab value="Spring Boot (Maven)">

Add the dependency in a profile that only development runs use:

```xml
<profiles>
  <profile>
    <id>dev</id>
    <dependencies>
      <dependency>
        <groupId>dev.tracepanel</groupId>
        <artifactId>tracepanel-spring-boot</artifactId>
        <version>0.3.1</version>
      </dependency>
    </dependencies>
  </profile>
</profiles>
```

Start the app with the Maven profile, and Spring's `dev` profile (or
DevTools) to turn Tracepanel on:

```bash
./mvnw spring-boot:run -Pdev -Dspring-boot.run.profiles=dev
```

  </Tab>
  <Tab value="Ktor">

Add the dependency and install the plugin. Ktor has no dependency injection
to find your DataSource or your HTTP client by, so you hand them over:

```kotlin
// build.gradle.kts
dependencies {
    implementation("dev.tracepanel:tracepanel-ktor:0.3.1")
}
```

```kotlin
import dev.tracepanel.core.Jdbc
import dev.tracepanel.ktor.Tracepanel
import dev.tracepanel.ktor.TracepanelClient

fun Application.module() {
    install(Tracepanel)
    val db = Database.connect(Jdbc.dataSource(hikari, "default"))
    val http = HttpClient(CIO) { install(TracepanelClient) }
}
```

Tracepanel is on in Ktor's development mode: `-Dio.ktor.development=true`, or
`ktor.development` in the config. The dependency goes into the production
build, where Tracepanel stays off.

  </Tab>
</Tabs>

## When it turns on [#when-it-turns-on]

Tracepanel turns on in development only. In Spring Boot, that is a `dev`,
`development` or `local` profile, or Spring Boot DevTools on the classpath.
Elsewhere it stays off, even if the dependency reached a production build by
mistake, and says so once in the log. In Ktor, it is Ktor's development mode.
In both, `TRACEPANEL_ENABLED=1` turns it on anyway and `TRACEPANEL_ENABLED=0`
turns it off. When it is off, it installs nothing.

## The agent [#the-agent]

The agent is a separate program that keeps the traces, finds the issues and
serves the console. You don't install it. The first time the app starts, the
SDK downloads the agent of its version from the agent's npm package for your
platform, checks it against the checksum the SDK was built with, and keeps it
in `~/.cache/tracepanel/` for every project. Without a network, it runs
`tracepanel-agent` from the `PATH`. `TRACEPANEL_AGENT_BIN` names another one.
See [How it works](/docs/how-it-works).

## Open the panel [#open-the-panel]

Open a page of your app, or its Swagger UI. A badge in the corner opens the
[panel](/docs/panel). The [console](/docs/console) is at `/__tracepanel__/`
on your app. Every response carries `Tracepanel-Id` and `Server-Timing`, and
the SDK exposes them on CORS responses, so a single-page app on another
origin reads them too.

The console answers this machine only: the traces hold SQL parameters, logs and
errors, and EXPLAIN runs queries. When the app runs in a container, or on a
shared dev server, `TRACEPANEL_CONSOLE_REMOTE=1` lets other machines open it.

Values under a secret's name (`password`, `token`, `api_key`, `session`, …) are
masked before they are recorded: in the query of an outgoing call's URL, which
also loses its `user:password@`, and in a SQL parameter bound to such a column
(`password = ?`, `INSERT INTO users (email, password)`).

Add `.tracepanel/` to your `.gitignore`: it holds the project's traces.
