Java and Scala support is beta stage
We are done implementing most functionality for Pants's Java and Scala support ([tracked here](🔗)). However, there may be use cases that we aren't yet handling.
Please share feedback for what you need to use Pants with your JVM project by either [opening a GitHub issue](🔗) or [joining our Slack](🔗)!
Example Java and Scala repository
Check out [github.com/pantsbuild/example-jvm](🔗) to try out Pants's Java and Scala support.
## Initial setup
First, activate the relevant backends in `
Then run [`
./pants tailor ::`](🔗) to generate BUILD files. This will create `
java_sources` and `
scala_sources` targets in every directory containing library code, as well as test targets like `
scalatest_tests` and `
junit_tests` for filenames that look like tests.
You can run `
./pants list ::` to see all targets in your project:
### Choosing JDK and Scala versions
2.11.x` adds support for choosing JDK and Scala versions per target in your repository, but to reduce the amount of boilerplate required, most users set repository-wide defaults in `
pants.toml`, and then only override them when necessary for particular targets.
JDKs used by Pants are automatically fetched using [Coursier](🔗), and are chosen using the [`
[jvm].jdk` setting](🔗) to set a repository-wide default.
To override the default on a particular target, you can use the [`
jdk=` field](🔗). It can be useful to use the [`
parametrize` builtin](🔗) with the `
jdk=` field, particularly to run test targets under multiple JDKs.
#### Scala version
The Scala version to use is configured on a resolve-by-resolve basis (see the "Third-party dependencies" section below) using the [`
[scala].version_for_resolve` option](🔗). The default Scala version for your repository will thus be whichever Scala version is configured for the "default" resolve, which is configured by the [`
To use multiple Scala versions in a repository, you would define multiple resolves, and then adjust the [`
resolve` field](🔗) of any targets which should be used with the non-`
To cross-build a set of Scala targets for multiple Scala versions, you can use the [`
parametrize` builtin](🔗) with the `
resolve=` field of the target and its dependencies.
A jvm_artifact for scala-library artifact is explicitly required.
The Scala backend currently requires that a `
jvm_artifact` target for the `
org.scala-lang:scala-library` Scala runtime be present in any resolve used for Scala. If such a jvm_artifact is missing, Pants will error. Pants will automatically inject a dependency on the runtime. (This target may be automatically supplied by Pants in a future version, but that is not currently implemented.)
### First-party dependencies
In many cases, the dependencies of your first-party code are automatically inferred via [dependency inference](🔗) based on your `
import` statements. If you do need to declare additional dependencies for any reason, you can do so using Pants' [syntax for declaring dependencies for targets](🔗).
### Third-party dependencies and lockfiles
Third-party dependencies (i.e. those from repositories like [Maven central](🔗)) are also automatically inferred via dependency inference, but must first be declared once per repository as [`
Pants requires use of a lockfile for thirdparty dependencies. After adding or editing `
jvm_artifact` targets, you will need to update affected lockfiles by running `
./pants generate-lockfiles`. The default lockfile is located at `
3rdparty/jvm/default.lock`, but it can be relocated (as well as additional resolves declared) via the [`
Thirdparty symbols and the `
To efficiently determine which symbols are provided by thirdparty code (i.e., without hitting the network in order to compute dependencies in the common case), Pants relies on a static mapping of which artifacts provide which symbols, and defaults to treating each `
jvm_artifact` as providing symbols within its `
packages` argument allows you to override which symbols a `
jvm_artifact` provides. See the [`
jvm_artifact` docs](🔗) for more information.
To have your code [load files as "resources"](🔗):
Add a `
resource` or `
resources` target with the relevant files in the `
source` / `
sources` field, respectively.
Ensure that [an appropriate `
source_root`](🔗) is detected for the `
resources` target, in order to trim the relevant prefix from the filename to align with the layout of your JVM packages.
Add that target to the `
dependencies` field of the relevant JVM target (usually the one that uses the JVM APIs to load the resource).
## Compile code
To manually check that sources compile, use `
## Run tests
To run tests, use `
You can also pass through arguments to the test runner with `
Pants can cancel tests which take too long. This is useful to prevent tests from hanging indefinitely.
To add a timeout, set the `
timeout` field to an integer value of seconds in any of the supported targets, like this:
When you set timeout on any of the target generators (i.e. `
scalatest_tests`, etc.), the same timeout will apply to every generated corresponding target.
You can also set a default value and a maximum value in `
If a target sets its `
timeout` higher than `
[test].timeout_maximum`, Pants will use the value in `
Use the option `
./pants test --no-timeouts` to temporarily disable timeouts, e.g. when debugging.
### Setting environment variables
Test runs are _hermetic_, meaning that they are stripped of the parent `
./pants` process's environment variables. This is important for reproducibility, and it also increases cache hits.
To add any arbitrary environment variable back to the process, you can either add the environment variable to the specific tests with the `
extra_env_vars` field on `
junit_test` / `
junit_tests` / `
scala_junit_test` / `
scala_junit_tests` / `
scalatest_test` / `
scalatest_tests` targets or to all your tests with the `
[test].extra_env_vars` option. Generally, prefer the field `
extra_env_vars` field so that more of your tests are hermetic.
With both `
[test].extra_env_vars` and the `
extra_env_vars` field, you can either hardcode a value or leave off a value to "allowlist" it and read from the parent `
./pants` process's environment.
## Lint and Format
scalafmt` and `
Google Java Format` can be enabled by adding the `
pants.backend.experimental.scala.lint.scalafmt` and `
pants.backend.experimental.java.lint.google_java_format` backends (respectively) to `
backend_packages` in the `
[GLOBAL]` section of `
Once enabled, `
lint` and `
fmt` will check and automatically reformat your code:
## Working in an IDE
Pants supports loading Java and Scala projects in IntelliJ via the [BSP protocol](🔗) (which should ease VSCode support [via Metals](🔗), although it is not yet supported).
After Setup (see below), and after IntelliJ has finished indexing your code, you should be able to:
Use goto definition and other symbol-index-using operations.
Run test classes, which will first compile them will Pants (and render compile failures if not), and then run them in the foreground with IntelliJ's test runner.
#### First time setup (per-repository)
Use a version of Pants containing BSP support:
Versions after `
2.12.0a0` support code indexing.
Versions after `
2.13.0.dev2` support test running.
Add a `
.gitignore` entry for the `
Add a "group" config file like the one below, adjusting the address specs and resolve name as appropriate.
Add to `
pants.toml` an option to point at the BSP configuration file:
#### Per-user setup
Run ./pants experimental-bsp to write the BSP connection file and script.
Ensure that you have the IntelliJ Scala plugin installed (it provides BSP support).
In IntelliJ, choose `
File > New > Project from Existing Sources…`
Choose the root of the repository for the project from the file dialog.
In the "Import Project" dialog, choose "Import project from external model" and select "BSP."
IntelliJ will invoke Pants to run the BSP server and synchronize state to produce IntelliJ modules.
If you see errors related to missing tools, you can set additional environment variables for BSP invocations in `
pants.toml` under the `
[experimental-bsp].runner_env_vars` option, and then re-run `
This is necessary because IntelliJ is invoked on macOS generally by launchd and not from the shell. Any `
PATH` set in the shell will not be passed to the Pants BSP server in that case.
If this is developer-specific, consider setting `
--experimental-bsp-runner-env-args` as a command-line option, or using a `
After configuration changes, or after adding new thirdparty dependencies, you will generally need to reload the BSP configuration ([for now](🔗)), which you can do with this button in the side panel:
When filing bug reports, include the log output of the Pants instance hosting the BSP server, which goes to `