BEF ultimately computes classpath information and maps it into the existing Java Developer Tools (JDT) plugins of Eclipse. This works well, but there are some caveats to this mapping. The caveats come from the fact that JDT grew up around the Maven build system, and Bazel is a more flexible build.
The top-level README links into a major set of limitations we have with mapping Bazel packages into JDT. The limitations allow us to use JDT without modifications.
Each Eclipse project maps to a single Bazel package. For example, Bazel package //projects/libs/apple-api maps to an Eclipse project named apple-api. There is a Bazel Classpath Container node inside of the apple-api project, that is the computed classpath from the Bazel BUILD file for the package.
The Bazel Classpath Container actually configures two classpaths with JDT:
- the main classpath
- the test classpath
The way this is computed is as follows:
- any dependency within the package that only appears in java_test target(s) is added to the test classpath
- all other dependencies for any java rule in the package get added to the main classpath
Within Bazel, every Java rule could target a different JDK version. However, BEF currently only supports a single global JDK setting for configuration during import. It is configured by the source level set on the command line (or .bazelrc file) javacopt option:
--javacopt "-source 8 -target 8"
While this is a limitation, this is only the default set during import. You may then manually configure the JDK by configuring the Build Path of any Eclipse Project.
- Right click on the project in the Package Explorer
- Click Build Path -> Configure Build Path...
- Click the Libraries tab
- Click on the existing JRE or JDK entry, and then click Remove
- Click Add Library... -> JRE System Library and then make your choice
This feature provides a benefit when working with large Bazel workspaces. With a large workspace, during import you will likely only choose to import a handful of packages. BEF will configure an Eclipse project for each of those packages, with the proper classpath.
However, the Eclipse Open Type dialog will then only have visibility into the types found in the classpaths of the imported projects. Types that are available in the Bazel workspace, but not in those projects, will not be visible to Open Type. This makes it hard to discover useful types when doing development.
The Global Search Classpath is a feature to resolve this issue. It scans the external jar directory of the Bazel build, and adds all found jars to a synthetic classpath node nested under the Bazel Workspace project in the Package Explorer. By having them appear in a classpath object, JDT can now find all enclosed types.
This feature does add your entire set of workspace jars to the search path for Eclipse. If you have thousands of jars in your workspace, this may cause performance issues. To disable this feature do the following before importing packages into your workspace:
- Eclipse -> Preferences -> Bazel (exact menu varies by platform)
- Uncheck the Enable global classpath search option.
Also, you may at times see multiple versions of the same external jar in your workspace.
This happens if you upgrade versions of that external jar.
BEF crawls internal Bazel directories to build the index, and Bazel does not typically clean
up old versions of jars when you upgrade.
This simply results in an extra entry in the Open Type dialog, and is easily ignored by the user.
The real solution to this is to run bazel clean
from the command line in your workspace
before opening the workspace in Eclipse if you have done any external jar upgrades.
Note that the feature may not work for all use cases. See the Global Search Classpath issue for status and open issues.
Bazel has an unfortunate default classpath setting for Java packages: explicit_java_test_deps=false This setting runs contrary to the design of Bazel in that all dependencies should be explicit. Most Bazel users are unaware of this setting, and come to rely on it.
What this setting does (when false) is implicitly add bundled versions of junit and hamcrest-core to your test classpaths. It is better to configure this settings as true and explicitly add the version of junit and hamcrest-core that you want. But, BEF has a feature to intelligently handle this case so that your BEF classpath is correct regardless of this setting.
BEF Behavior:
- If explicit_java_test_deps=true, BEF will NOT add the implicit test runner jar (with bundled junit and hamcrest-core classes) to the Eclipse JDT classpath
- If explicit_java_test_deps=false (or unspecified, false is the default), BEF will add the implicit test runner jar (Runner_deploy-ijar.jar) to the Eclipse JDT classpath. This will prevent JDT from adding red squigglies to your test classes where junit/hamcrest classes are referenced.
To see what entries BEF has supplied to the JDT classpath for a project, do the following:
- Open your imported project's node in the Package Explorer
- Open the Bazel Classpath Container node
- You will see the list of jars added to the JDT classpath below that node
The next page in our guide discusses the Launchers with the Bazel Eclipse Feature.