rules_scala icon indicating copy to clipboard operation
rules_scala copied to clipboard

Add support for add_exports/add_opens

Open timothyg-stripe opened this issue 1 year ago • 3 comments
trafficstars

I'm happy to write some tests for this, but existing tests appear to be broken in CI, and much of the functionality requires Bazel 7.0.0 to work anyway (while CI is still on Bazel 6.3).


Description

  • In scala_binary, scala_test, and friends, read java_info.module_flags_info and include those --add-exports and --add-opens JVM flags in the launcher script.
  • On Bazel 7.0.0+, add add_exports and add_opens attributes to all rules (including scala_import) and propagate the flags through JavaInfo.
    • Bazel's JavaInfo constructor only added this functionality in 7.0.0; see https://github.com/bazelbuild/bazel/issues/20033.

Motivation

JDK 17 strongly encapsulates JDK internals, so many libraries need --add-exports= and --add-opens= JVM flags to run. Bazel's Java rules already support adding those flags through java_library(add_opens = [...], add_exports = [...]), and these fields are read in Bazel's java_binary rule. This PR adds the same functionality to Scala rules.

Fixes #1523

timothyg-stripe avatar Mar 07 '24 00:03 timothyg-stripe

I managed to get a passing build with this PR, but it's a bit unfortunate since it would force users to add some additional lines to their WORKSPACE file.

  1. I'm currently using bazel_features to detect Bazel version for support for add_opens/add_exports.
  2. The project currently recommends that folks run load("@io_bazel_rules_scala//scala:scala.bzl", "rules_scala_setup", "rules_scala_toolchain_deps_repositories") in WORKSPACE. But loading @io_bazel_rules_scala//scala:scala.bzl also loads Bazel rules like scala_library, which requires @bazel_features.
  3. For load("@bazel_features//...") to work, the WORKSPACE file needs to run bazel_features_deps() before the attempted load.

The sum effect of this is that users must have

http_archive(
    name = "bazel_features",
    sha256 = "d7787da289a7fb497352211ad200ec9f698822a9e0757a4976fd9f713ff372b3",
    strip_prefix = "bazel_features-1.9.1",
    url = "https://github.com/bazel-contrib/bazel_features/releases/download/v1.9.1/bazel_features-v1.9.1.tar.gz",
)

load("@bazel_features//:deps.bzl", "bazel_features_deps")
bazel_features_deps()

in the WORKSPACE file before loading anything from rules_scala – and specifically, we cannot call bazel_features_deps() for them in rules_scala_toolchain_deps_repositories().


I think there are three options:

  1. Bite the bullet and force every user to install bazel_features. (That's what this PR would do, in its current shape.)

  2. Abandon support for Bazel 6.x. (Bazel 7.0.0+ has proper support for this feature.)

  3. Change the .bzl file structure so that files that should be loaded from BUILD files are separate from those that should be loaded from WORKSPACE files. In other words, lift rules_scala_setup and rules_scala_toolchain_deps_repositories out of @io_bazel_rules_scala//scala:scala.bzl, and into something like @io_bazel_rules_scala//scala:workspace.bzl.

    This way, users still have to load bazel_features – but at least we can call bazel_features_deps() for them.

I think option 2 seems most straightforward, though I'll leave it up to the maintainers to decide.

@liucijus @simuons

timothyg-stripe avatar Mar 30 '24 21:03 timothyg-stripe

Hi, @timothyg-stripe, so this feature can be enabled only for bazel 7 and up. Could this be done with skylib versions?

simuons avatar Apr 22 '24 13:04 simuons

@simuons unfortunately, skylib versions isn't sufficient since versions.get does not work in a BUILD file. See https://github.com/bazelbuild/bazel/issues/4566.

timothyg-stripe avatar Apr 28 '24 01:04 timothyg-stripe