En esta página, se describe cómo migrar de Maven a Bazel, incluidos los requisitos previos y los pasos de instalación. Se describen las diferencias entre Maven y Bazel, y se proporciona un ejemplo de migración mediante el proyecto de Guava.
Cuando migres desde cualquier herramienta de compilación a Bazel, es mejor que ambas se ejecuten en paralelo hasta que hayas migrado por completo el equipo de desarrollo, el sistema de CI y cualquier otro sistema relevante. Puedes ejecutar Maven y Bazel en el mismo repositorio.
Antes de comenzar
- Instala Bazel si aún no lo has hecho.
- Si es la primera vez que usas Bazel, consulta el instructivo Introducción a Bazel: Compila Java antes de comenzar la migración. En este instructivo, se explican los conceptos, la estructura y la sintaxis de etiquetas de Bazel.
Diferencias entre Maven y Bazel
- Maven usa archivos
pom.xml
de nivel superior. Bazel admite varios archivos de compilación y varios destinos por archivoBUILD
, lo que permite compilaciones más incrementales que las de Maven. - Maven se encarga de los pasos del proceso de implementación. Bazel no automatiza la implementación.
- Bazel te permite expresar dependencias entre lenguajes.
- A medida que agregas secciones nuevas al proyecto, con Bazel, es posible que debas agregar nuevos archivos
BUILD
. La práctica recomendada es agregar un archivoBUILD
a cada paquete de Java nuevo.
Migra de Maven a Bazel
En los siguientes pasos, se describe cómo migrar tu proyecto a Bazel:
Los siguientes ejemplos provienen de una migración del
proyecto de Guava de Maven a Bazel.
El proyecto de Guava que se usó es el lanzamiento v31.1
. En los ejemplos que usan Guava, no se recorre cada paso de la migración, pero muestran los archivos y el contenido que se generan o se agregan de forma manual para la migración.
$ git clone https://github.com/google/guava.git && cd guava
$ git checkout v31.1
1. Crea el archivo WORKSPACE
Crea un archivo llamado WORKSPACE
en la raíz de tu proyecto. Si tu proyecto no tiene dependencias externas, el archivo del lugar de trabajo puede estar vacío.
Si tu proyecto depende de archivos o paquetes que no se encuentran en uno de los directorios del proyecto, especifica estas dependencias externas en el archivo del lugar de trabajo. Para automatizar la lista de dependencias externas del archivo del lugar de trabajo, usa rules_jvm_external
. Para obtener instrucciones sobre cómo usar este conjunto de reglas, consulta el archivo README.
Ejemplo de proyecto de Guava: dependencias externas
Puedes enumerar las dependencias externas del proyecto Guava con el conjunto de reglas rules_jvm_external
.
Agrega el siguiente fragmento al archivo WORKSPACE
:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
RULES_JVM_EXTERNAL_TAG = "4.3"
RULES_JVM_EXTERNAL_SHA = "6274687f6fc5783b589f56a2f1ed60de3ce1f99bc4e8f9edef3de43bdf7c6e74"
http_archive(
name = "rules_jvm_external",
sha256 = RULES_JVM_EXTERNAL_SHA,
strip_prefix = "rules_jvm_external-%s" % RULES_JVM_EXTERNAL_TAG,
url = "https://github.com/bazelbuild/rules_jvm_external/archive/%s.zip" % RULES_JVM_EXTERNAL_TAG,
)
load("@rules_jvm_external//:defs.bzl", "maven_install")
maven_install(
artifacts = [
"com.google.code.findbugs:jsr305:3.0.2",
"com.google.errorprone:error_prone_annotations:2.11.0",
"com.google.j2objc:j2objc-annotations:1.3",
"org.codehaus.mojo:animal-sniffer-annotations:1.20",
"org.checkerframework:checker-qual:3.12.0",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
2. Crea un archivo BUILD
Ahora que ya definiste el lugar de trabajo y las dependencias externas (si corresponde),
debes crear archivos BUILD
para describir cómo se debe compilar
tu proyecto. A diferencia de Maven con su único archivo pom.xml
, Bazel puede usar muchos archivos BUILD
para compilar un proyecto. Estos archivos especifican varios objetivos de compilación,
lo que permite que Bazel produzca compilaciones incrementales.
Agrega archivos BUILD
en etapas. Comienza por agregar un archivo BUILD
en la raíz de tu proyecto y usarlo para realizar una compilación inicial con Bazel.
Luego, para definir mejor tu compilación, agrega más archivos BUILD
con objetivos más detallados.
En el mismo directorio que tu archivo
WORKSPACE
, crea un archivo de texto y asígnale el nombreBUILD
.En este archivo
BUILD
, usa la regla correspondiente para crear un destino y compilar tu proyecto. Aquí encontrarás algunas sugerencias:Usa la regla adecuada:
Para compilar proyectos con un solo módulo de Maven, usa la regla
java_library
de la siguiente manera:java_library( name = "everything", srcs = glob(["src/main/java/**/*.java"]), resources = glob(["src/main/resources/**"]), deps = ["//:all-external-targets"], )
Para compilar proyectos con varios módulos de Maven, usa la regla
java_library
de la siguiente manera:java_library( name = "everything", srcs = glob([ "Module1/src/main/java/**/*.java", "Module2/src/main/java/**/*.java", ... ]), resources = glob([ "Module1/src/main/resources/**", "Module2/src/main/resources/**", ... ]), deps = ["//:all-external-targets"], )
Para compilar objetos binarios, usa la regla
java_binary
:java_binary( name = "everything", srcs = glob(["src/main/java/**/*.java"]), resources = glob(["src/main/resources/**"]), deps = ["//:all-external-targets"], main_class = "com.example.Main" )
Especifica los atributos:
name
: Asigna un nombre significativo al destino. En los ejemplos anteriores, el objetivo se denomina "todo".srcs
: Usa globbing para mostrar todos los archivos .java de tu proyecto.resources
: Usa el globo terráqueo para enumerar todos los recursos de tu proyecto.deps
: Debes determinar qué dependencias externas necesita tu proyecto. Por ejemplo, si generaste una lista de dependencias externas con la herramientagenerate_workspace
, las dependencias parajava_library
son las bibliotecas que se enumeran en la macrogenerated_java_libraries
.
Consulta el ejemplo a continuación de este archivo BUILD de nivel superior de la migración del proyecto de Guava.
Ahora que tienes un archivo
BUILD
en la raíz de tu proyecto, compílalo para asegurarte de que funcione. En la línea de comandos, desde el directorio de tu lugar de trabajo, usabazel build //:everything
para compilar el proyecto con Bazel.El proyecto se compiló correctamente con Bazel. Deberás agregar más archivos
BUILD
para permitir compilaciones incrementales del proyecto.
Ejemplo de proyecto de Guava: comienza con un archivo BUILD
Cuando se migra el proyecto de Guava a Bazel, inicialmente se usa un archivo BUILD
para compilar el proyecto completo. Este es el contenido de este archivo BUILD
inicial en el directorio del lugar de trabajo:
java_library(
name = "everything",
srcs = glob([
"guava/src/**/*.java",
"futures/failureaccess/src/**/*.java",
]),
javacopts = ["-XepDisableAllChecks"],
deps = [
"@maven//:com_google_code_findbugs_jsr305",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_j2objc_j2objc_annotations",
"@maven//:org_checkerframework_checker_qual",
"@maven//:org_codehaus_mojo_animal_sniffer_annotations",
],
)
3. Crea más archivos BUILD (opcional)
Bazel funciona con un solo BUILD file
, como viste después de completar tu primera
compilación. De todos modos, deberías considerar dividir la compilación en fragmentos más pequeños. Para ello, agrega más archivos BUILD
con objetivos detallados.
Varios archivos BUILD
con varios destinos brindarán un mayor nivel de detalle a la compilación, lo que permitirá lo siguiente:
- mayor cantidad de compilaciones incrementales del proyecto,
- mayor ejecución paralela de la compilación
- una mejor capacidad de mantenimiento de la compilación para los usuarios futuros
- control sobre la visibilidad de los destinos entre paquetes, lo que puede evitar problemas como las bibliotecas que contienen detalles de implementación que se filtran en APIs públicas.
Sugerencias para agregar más archivos BUILD
:
- Para comenzar, puedes agregar un archivo
BUILD
a cada paquete de Java. Comienza con los paquetes de Java que tienen la menor cantidad de dependencias y avanza hasta los paquetes con la mayor cantidad de dependencias. - A medida que agregues archivos
BUILD
y especifiques destinos, agrega estos nuevos destinos a las seccionesdeps
de los destinos que dependen de ellos. Ten en cuenta que la funciónglob()
no cruza los límites del paquete, por lo que, a medida que aumente la cantidad de paquetes, se reducirán los archivos que coincidan conglob()
. - Cada vez que agregues un archivo
BUILD
a un directoriomain
, asegúrate de agregar un archivoBUILD
al directoriotest
correspondiente. - Asegúrate de limitar correctamente la visibilidad entre los paquetes.
- Para simplificar la solución de errores en la configuración de los archivos
BUILD
, asegúrate de que el proyecto continúe compilando con Bazel a medida que agregues cada archivo de compilación. Ejecutabazel build //...
para asegurarte de que aún se compilen todos tus destinos.
4. Compila con Bazel
Compilaste con Bazel a medida que agregas archivos BUILD
para validar la configuración
de la compilación.
Cuando tienes archivos BUILD
con el nivel de detalle deseado, puedes usar Bazel
para producir todas tus compilaciones.