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 con el proyecto Guava.
Cuando migras de cualquier herramienta de compilación a Bazel, es mejor tener ambas herramientas de compilación ejecutándose en paralelo hasta que hayas migrado por completo tu equipo de desarrollo, el sistema de CI y cualquier otro sistema pertinente. Puedes ejecutar Maven y Bazel en el mismo repositorio.
Antes de comenzar
- Instala Bazel si aún no lo hiciste.
- Si es la primera vez que usas Bazel, consulta el instructivo Introducción a Bazel: Compila Java antes de comenzar la migración. En el instructivo, se explican los conceptos, la estructura y la sintaxis de etiquetas de Bazel.
Diferencias entre Maven y Bazel
- Maven usa archivos
pom.xmlde 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, es posible que debas agregar archivos
BUILDnuevos con Bazel. La práctica recomendada es agregar un archivoBUILDa 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 Guava de Maven a Bazel.
El proyecto Guava usado es la versión v31.1. Los ejemplos que usan Guava no explican cada paso de la migración, pero muestran los archivos y el contenido que se generan o 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 espacio de trabajo puede estar vacío.
Si tu proyecto depende de archivos o paquetes que no están en uno de los directorios del proyecto, especifica estas dependencias externas en el archivo del espacio de trabajo. Para automatizar la lista de dependencias externas del archivo del espacio de trabajo, usa rules_jvm_external. Para obtener instrucciones sobre el uso de este conjunto de reglas, consulta
el archivo README.
Ejemplo de proyecto Guava: dependencias externas
Puedes enumerar las dependencias externas del
proyecto Guava con el
rules_jvm_external
conjunto de reglas.
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 definiste tu espacio de trabajo y enumeraste las dependencias externas (si corresponde), debes crear archivos BUILD para describir cómo se debe compilar tu proyecto. A diferencia de Maven con su archivo pom.xml, Bazel puede usar muchos archivos BUILD para compilar un proyecto. Estos archivos especifican varios destinos 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 úsalo para realizar una compilación inicial con Bazel.
Luego, refina tu compilación agregando más archivos BUILD con destinos más detallados.
En el mismo directorio que tu archivo
WORKSPACE, crea un archivo de texto y llámaloBUILD.En este archivo
BUILD, usa la regla adecuada para crear un destino para 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_libraryde 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_libraryde 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 archivos 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 destino se llama "everything".srcs: Usa la expansión de comodines para enumerar todos los archivos .java de tu proyecto.resources: Usa la expansión de comodines 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 dejava_libraryson las bibliotecas que se enumeran en la macrogenerated_java_libraries.
Consulta el siguiente ejemplo de este archivo BUILD de nivel superior de la migración del proyecto Guava.
Ahora que tienes un archivo
BUILDen la raíz de tu proyecto, compílalo para asegurarte de que funcione. En la línea de comandos, desde el directorio de tu espacio de trabajo, usabazel build //:everythingpara compilar tu proyecto con Bazel.El proyecto ahora se compiló correctamente con Bazel. Deberás agregar más archivos
BUILDpara permitir compilaciones incrementales del proyecto.
Ejemplo de proyecto Guava: comienza con un archivo BUILD
Cuando se migra el proyecto Guava a Bazel, inicialmente se usa un archivo BUILD para compilar todo el proyecto. Este es el contenido de este archivo BUILD inicial en el directorio del espacio de trabajo:
java_library(
name = "everything",
srcs = glob([
"guava/src/**/*.java",
"futures/failureaccess/src/**/*.java",
]),
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. Aun así, deberías considerar dividir la compilación en fragmentos más pequeños agregando más archivos BUILD con destinos detallados.
Varios archivos BUILD con varios destinos le darán a la compilación una mayor granularidad, lo que permitirá lo siguiente:
- aumento de las compilaciones incrementales del proyecto,
- aumento de la ejecución paralela de la compilación,
- mejor capacidad de mantenimiento de la compilación para usuarios futuros y
- control sobre la visibilidad de los destinos entre paquetes, lo que puede evitar problemas, como que las bibliotecas que contienen detalles de implementación se filtren en las APIs públicas.
Sugerencias para agregar más archivos BUILD:
- Puedes comenzar agregando un archivo
BUILDa 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 agregas archivos
BUILDy especificas destinos, agrega estos destinos nuevos a las seccionesdepsde 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 aumenta la cantidad de paquetes, los archivos que coinciden conglob()se reducirán. - Cada vez que agregues un archivo
BUILDa un directoriomain, asegúrate de agregar un archivoBUILDal directoriotestcorrespondiente. - Ten cuidado de limitar la visibilidad correctamente entre los paquetes.
- Para simplificar la solución de problemas de errores en la configuración de archivos
BUILD, asegúrate de que el proyecto continúe compilándose con Bazel a medida que agregas cada archivo de compilación. Ejecutabazel build //...para asegurarte de que todos tus destinos aún se compilen.
4. Compila con Bazel
Has estado compilando con Bazel a medida que agregas archivos BUILD para validar la configuración de la compilación.
Cuando tengas archivos BUILD con la granularidad deseada, puedes usar Bazel para producir todas tus compilaciones.