Esta página contém recursos que ajudam você a usar o Bazel com projetos Java. Ele é vinculado a um tutorial, regras de build e outras informações específicas para criar projetos Java com o Bazel.
Como trabalhar com o Bazel
Os recursos a seguir vão ajudar você a trabalhar com o Bazel em projetos Java:
Como migrar para o Bazel
Se você cria projetos Java com o Maven, siga as etapas do guia de migração para começar a criar seus projetos Maven com o Bazel:
Versões do Java
Há duas versões relevantes do Java definidas com sinalizações de configuração:
- a versão dos arquivos de origem no repositório
- a versão do ambiente de execução Java usado para executar o código e testá-lo
Como configurar a versão do código-fonte no repositório
Sem uma configuração adicional, o Bazel pressupõe que todos os arquivos de origem Java no
repositório são gravados em uma única versão do Java. Para especificar a versão das
origens no repositório, adicione build --java_language_version={ver}
ao
arquivo .bazelrc
, em que {ver}
é, por exemplo, 11
. Os proprietários do repositório do Bazel
precisam definir essa flag para que o Bazel e os usuários possam referenciar o número da versão
do código-fonte Java. Para mais detalhes, consulte
Flag da versão da linguagem Java.
Configurar a JVM usada para executar e testar o código
O Bazel usa um JDK para compilação e outra JVM para executar e testar o código.
Por padrão, o Bazel compila o código usando um JDK que ele faz o download e executa e
testa o código com a JVM instalada na máquina local. O Bazel procura
a JVM usando JAVA_HOME
ou caminho.
Os binários resultantes são compatíveis com a JVM instalada localmente nas bibliotecas do sistema. Isso significa que os binários resultantes dependem do que está instalado na máquina.
Para configurar a JVM usada para execução e teste, use a flag
--java_runtime_version
. O valor padrão é local_jdk
.
Teste hermético e compilação
Para criar uma compilação hermética, use a sinalização de linha de comando
--java_runtime_version=remotejdk_11
. O código é compilado, executado e
testado na JVM baixada de um repositório remoto. Para mais detalhes, consulte
Flag da versão do ambiente de execução do Java.
Como configurar a compilação e a execução de ferramentas de build em Java
Há um segundo par de JDK e JVM usado para criar e executar ferramentas, que são
usados no processo de build, mas não nos resultados do build. Que o JDK e a JVM
são controlados usando --tool_java_language_version
e
--tool_java_runtime_version
. Os valores padrão são 11
e remotejdk_11
,
respectivamente.
Como compilar usando o JDK instalado localmente
O Bazel compila usando o JDK remoto por padrão, porque ele substitui os elementos internos do JDK. As cadeias de ferramentas de compilação que usam o JDK instalado localmente são configuradas, mas não usadas.
Para compilar usando o JDK instalado localmente, que usa os conjuntos de ferramentas
de compilação para o JDK local, use a flag extra --extra_toolchains=@local_jdk//:all
.
No entanto, isso pode não funcionar no JDK de fornecedores arbitrários.
Para mais detalhes, consulte Como configurar toolchains Java.
Práticas recomendadas
Além das práticas recomendadas gerais do Bazel, confira abaixo as práticas recomendadas específicas para projetos Java.
Estrutura do diretório
Prefira o layout de diretório padrão do Maven (fontes em src/main/java
, testes
em src/test/java
).
Arquivos BUILD
Siga estas diretrizes ao criar arquivos BUILD
:
Use um arquivo
BUILD
por diretório que contenha origens Java, porque isso melhora o desempenho do build.Cada arquivo
BUILD
precisa conter uma regrajava_library
semelhante a esta:java_library( name = "directory-name", srcs = glob(["*.java"]), deps = [...], )
O nome da biblioteca precisa ser o mesmo do diretório que contém o arquivo
BUILD
. Isso encurta o rótulo da biblioteca, que usa"//package"
em vez de"//package:package"
.As origens precisam ser um
glob
não recursivo de todos os arquivos Java no diretório.Os testes precisam estar em um diretório correspondente em
src/test
e depender dessa biblioteca.
Como criar novas regras para builds avançados em Java
Observação: a criação de novas regras é destinada a cenários avançados de build e teste. Você não precisa dele para começar a usar o Bazel.
Os módulos, fragmentos de configuração e provedores a seguir vão ajudar você a ampliar os recursos do Bazel ao criar seus projetos Java:
- Principal provedor Java:
java_common
- Módulo Java principal:
JavaInfo
- Fragmento de configuração:
java
Outros módulos:
Como configurar as cadeias de ferramentas Java
O Bazel usa dois tipos de toolchains Java:
- execução, usada para executar e testar binários Java, controlada com
a flag --java_runtime_version
- compilação, usada para compilar origens Java, controlada com
a flag --java_language_version
Como configurar outras cadeias de ferramentas de execução
A cadeia de ferramentas de execução é a JVM, local ou de um repositório, com algumas informações adicionais sobre a versão, o sistema operacional e a arquitetura da CPU.
As cadeias de ferramentas de execução do Java podem ser adicionadas usando regras local_java_repository
ou
remote_java_repository
no arquivo WORKSPACE
. A adição da regra disponibiliza
a JVM usando uma flag. Quando várias definições para o mesmo sistema
operacional e arquitetura de CPU são fornecidas, a primeira é usada.
Exemplo de configuração de JVM local:
load("@bazel_tools//tools/jdk:local_java_repository.bzl", "local_java_repository")
local_java_repository(
name = "additionaljdk", # Can be used with --java_runtime_version=additionaljdk, --java_runtime_version=11 or --java_runtime_version=additionaljdk_11
version = 11, # Optional, if not set it is autodetected
java_home = "/usr/lib/jdk-15/", # Path to directory containing bin/java
)
Exemplo de configuração da JVM remota:
load("@bazel_tools//tools/jdk:remote_java_repository.bzl", "remote_java_repository")
remote_java_repository(
name = "openjdk_canary_linux_arm",
prefix = "openjdk_canary", # Can be used with --java_runtime_version=openjdk_canary_11
version = "11", # or --java_runtime_version=11
target_compatible_with = [ # Specifies constraints this JVM is compatible with "@platforms//cpu:arm",
"@platforms//os:linux",
],
urls = ..., # Other parameters are from http_repository rule.
sha256 = ...,
strip_prefix = ...
)
Como configurar outros conjuntos de ferramentas de compilação
O conjunto de ferramentas de compilação é composto por JDK e várias ferramentas que o Bazel usa durante a compilação e que oferece outros recursos, como: erro propenso, dependências rígidas de Java, compilação de cabeçalho, simplificação de leitura do Android, instrumentação de cobertura e processamento de classe generativa para ambientes de desenvolvimento integrado.
O JavaBuilder é uma ferramenta agrupada do Bazel que executa a compilação e fornece os
recursos mencionados. A compilação real é executada usando o compilador
interno pelo JDK. O JDK usado para a compilação é especificado pelo atributo java_runtime
da cadeia de ferramentas.
O Bazel substitui alguns elementos internos do JDK. No caso de uma versão do JDK > 9,
os módulos java.compiler
e jdk.compiler
são corrigidos usando a flag
--patch_module
do JDK. No caso do JDK versão 8, o compilador Java é corrigido usando a flag
-Xbootclasspath
.
O VanillaJavaBuilder é uma segunda implementação do JavaBuilder, que não modifica o compilador interno do JDK e não tem nenhum dos recursos adicionais. O VanillaJavaBuilder não é usado por nenhuma das cadeias de ferramentas integradas.
Além do JavaBuilder, o Bazel usa várias outras ferramentas durante a compilação.
A ferramenta ijar
processa arquivos jar
para remover tudo, exceto assinaturas
de chamada. Os jars resultantes são chamados de jars de cabeçalho. Elas são usadas para melhorar a
compilação incremental, recompilando apenas as dependentes dependentes quando o
corpo de uma função muda.
A ferramenta singlejar
agrupa vários arquivos jar
em um único arquivo.
A ferramenta genclass
pós-processa a saída de uma compilação Java e produz
um jar
contendo apenas os arquivos de classe para origens geradas por
processadores de anotação.
A ferramenta JacocoRunner
executa o Jacoco em arquivos instrumentados e gera resultados no
formato LCOV.
A ferramenta TestRunner
executa testes JUnit 4 em um ambiente controlado.
É possível reconfigurar a compilação adicionando a macro default_java_toolchain
a
um arquivo BUILD
e registrando-a adicionando a regra register_toolchains
ao
arquivo WORKSPACE
ou usando a
flag --extra_toolchains
.
A cadeia de ferramentas só é usada quando o atributo source_version
corresponde ao
valor especificado pela flag --java_language_version
.
Exemplo de configuração de conjunto de ferramentas:
load(
"@bazel_tools//tools/jdk:default_java_toolchain.bzl",
"default_java_toolchain", "DEFAULT_TOOLCHAIN_CONFIGURATION", "BASE_JDK9_JVM_OPTS", "DEFAULT_JAVACOPTS"
)
default_java_toolchain(
name = "repository_default_toolchain",
configuration = DEFAULT_TOOLCHAIN_CONFIGURATION, # One of predefined configurations
# Other parameters are from java_toolchain rule:
java_runtime = "@bazel_tools//tools/jdk:remote_jdk11", # JDK to use for compilation and toolchain's tools execution
jvm_opts = BASE_JDK9_JVM_OPTS + ["--enable_preview"], # Additional JDK options
javacopts = DEFAULT_JAVACOPTS + ["--enable_preview"], # Additional javac options
source_version = "9",
)
que pode ser usado com --extra_toolchains=//:repository_default_toolchain_definition
ou com a adição de register_toolchains("//:repository_default_toolchain_definition")
ao espaço de trabalho.
Configurações predefinidas:
DEFAULT_TOOLCHAIN_CONFIGURATION
: todos os recursos, compatível com versões do JDK 9 ou mais recentesVANILLA_TOOLCHAIN_CONFIGURATION
: sem recursos adicionais, oferece suporte a JDKs de fornecedores arbitrários.PREBUILT_TOOLCHAIN_CONFIGURATION
: o mesmo que o padrão, mas usa apenas ferramentas pré-criadas (ijar
,singlejar
).NONPREBUILT_TOOLCHAIN_CONFIGURATION
: igual ao padrão, mas todas as ferramentas são criadas a partir de origens. Isso pode ser útil em sistemas operacionais com libc diferentes.
Como configurar sinalizações da JVM e do compilador Java
É possível configurar as flags da JVM e do javac com flags ou com
atributos default_java_toolchain
.
As flags relevantes são --jvmopt
, --host_jvmopt
, --javacopt
e
--host_javacopt
.
Os atributos default_java_toolchain
relevantes são javacopts
, jvm_opts
,
javabuilder_jvm_opts
e turbine_jvm_opts
.
Configurar flags do compilador Java específicas do pacote
É possível configurar diferentes flags do compilador Java para arquivos de origem
específicos usando o atributo package_configuration
de default_java_toolchain
.
Consulte o exemplo abaixo.
load("@bazel_tools//tools/jdk:default_java_toolchain.bzl", "default_java_toolchain")
# This is a convenience macro that inherits values from Bazel's default java_toolchain
default_java_toolchain(
name = "toolchain",
package_configuration = [
":error_prone",
],
visibility = ["//visibility:public"],
)
# This associates a set of javac flags with a set of packages
java_package_configuration(
name = "error_prone",
javacopts = [
"-Xep:MissingOverride:ERROR",
],
packages = ["error_prone_packages"],
)
# This is a regular package_group, which is used to specify a set of packages to apply flags to
package_group(
name = "error_prone_packages",
packages = [
"//foo/...",
"-//foo/bar/...", # this is an exclusion
],
)
Várias versões do código-fonte Java em um único repositório
Ele só pode compilar uma única versão de fontes Java em um build. Isso significa que, ao criar um teste ou um aplicativo Java, todas as dependências são criadas com base na mesma versão do Java.
No entanto, builds separados podem ser executados usando flags diferentes.
Para facilitar o uso de flags diferentes, os conjuntos de flags de uma versão
específica podem ser agrupados com as configurações .bazelrc
:
build:java8 --java_language_version=8
build:java8 --java_runtime_version=localjdk_8
build:java11 --java_language_version=11
build:java11 --java_runtime_version=remotejdk_11
Essas configurações podem ser usadas com a flag --config
, por exemplo,
bazel test --config=java11 //:java11_test
.