Compilación con Jack (AOSP 6.0 - 8.1)

Jack es la cadena de herramientas de compilación predeterminada de Android para Android 6.0 a 8.1.

Jack es una cadena de herramientas de Android que se usa para compilar códigos fuente de Java en códigos de bytes dex de Android. No tienes que realizar ninguna acción diferente para usar Jack; simplemente usa los comandos estándar de tu archivo Make para compilar el árbol o tu proyecto. Android 8.1 es la última versión que usa Jack.

Información sobre Jack

Jack funciona como se muestra en la Figura 1.

Descripción general de Jack.

Figura 1: Descripción general de Jack.

Formato de la biblioteca de Jack

Jack tiene su propio formato de archivo .jack que contiene el código dex compilado previamente para la biblioteca, lo que permite una compilación más rápida (proceso de pre-dexing).

Contenido del archivo de biblioteca de Jack.

Figura 2: Contenido del archivo de biblioteca de Jack.

Jill

Como se muestra en la siguiente figura, la herramienta Jill traduce las bibliotecas .jar existentes al nuevo formato de biblioteca.

Flujo de trabajo para importar una biblioteca "jar." existente.

Figura 3: Flujo de trabajo para importar una biblioteca .jar existente.

Servidor de compilación de Jack

La primera vez que usas Jack, se ejecuta un servidor local de compilación de Jack en tu computadora. Este servidor hace lo siguiente:

  • Genera una aceleración intrínseca, porque evita ejecutar un nuevo host JRE JVM, cargar el código de Jack, inicializar Jack y preparar el JIT en cada compilación. Además, proporciona muy buenos tiempos de compilación durante compilaciones pequeñas (por ejemplo, en modo incremental).
  • Brinda una solución a corto plazo para controlar la cantidad de compilaciones de Jack paralelas. El servidor evita que se sobrecargue tu computadora (problema de memoria o de disco), ya que limita la cantidad de compilaciones paralelas.

El servidor de Jack se apaga después de un tiempo de inactividad sin compilaciones. Utiliza dos puertos TCP en la interfaz localhost y no está disponible externamente. Se pueden modificar todos los parámetros (cantidad de compilaciones paralelas, tiempo de espera, número de puertos, etc.). Para hacerlo, edita el archivo $HOME/.jack.

Archivo $HOME/.jack

El archivo $HOME/.jack contiene la siguiente configuración para las variables del servidor de Jack en una sintaxis de Bash completa:

  • SERVER=true habilita la función del servidor de Jack.
  • SERVER_PORT_SERVICE=8072 establece el número de puerto TCP del servidor para fines de compilación.
  • SERVER_PORT_ADMIN=8073 establece el número de puerto TCP del servidor para fines administrativos.
  • SERVER_COUNT=1 no está en uso.
  • SERVER_NB_COMPILE=4 establece la cantidad máxima de compilaciones paralelas permitidas. SERVER_TIMEOUT=60 establece la cantidad de segundos de inactividad que el servidor debe esperar sin ninguna compilación antes de apagarse automáticamente. SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} establece el archivo en el que se escriben los registros del servidor. De forma predeterminada, una variable de entorno puede sobrecargar esta variable.
  • JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} establece el comando predeterminado que se usa para ejecutar una JVM en el host. De forma predeterminada, una variable de entorno puede sobrecargar esta variable.

Solución de problemas de compilaciones de Jack

Problema Acción
Tu computadora deja de responder durante la compilación o no se realizan correctamente las compilaciones de Jack por Error de memoria insuficiente. Para reducir la cantidad de compilaciones simultáneas de Jack, edita $HOME/.jack y cambia SERVER_NB_COMPILE a un valor inferior.
No se realizan correctamente las compilaciones por Error al ejecutar el servidor en segundo plano. La causa más probable es que los puertos TCP ya estén en uso en tu computadora. Para cambiar los puertos, edita $HOME/.jack (variables de SERVER_PORT_SERVICE y SERVER_PORT_ADMIN). Para desbloquear el problema, inhabilita el servidor de compilación de Jack: edita $HOME/.jack y cambia SERVER a false. Lamentablemente, esto ralentiza bastante tu compilación y es posible que debas ejecutar make -j con control de carga (opción -l de make).
La compilación queda bloqueada, sin avanzar Para desbloquear el problema, finaliza el proceso del servidor de Jack que se ejecuta en segundo plano con jack-admin kill-server y quita los directorios temporales que hay en jack-$USER de tu directorio temporal (/tmp o $TMPDIR).

Cómo buscar el registro de Jack

Si ejecutaste un comando make con destino dist, el registro de Jack se encuentra en $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log. De lo contrario, puedes ejecutar jack-admin server-log para buscarlo. En caso de fallas reproducibles de Jack, para obtener un registro más detallado, puedes configurar la siguiente variable:

export ANDROID_JACK_EXTRA_ARGS="--verbose debug --sanity-checks on -D sched.runner=single-threaded"

Utiliza los comandos estándar del archivo Make para compilar el árbol (o tu proyecto), y adjunta el resultado y el error estándares. Para quitar registros de compilación detallados, ejecuta lo siguiente:

unset ANDROID_JACK_EXTRA_ARGS

Limitaciones de Jack

  • De forma predeterminada, solo un usuario puede usar el servidor de Jack en una computadora. Si quieres admitir usuarios adicionales, selecciona números de puerto diferentes para cada usuario y ajusta SERVER_NB_COMPILE según corresponda. También puedes inhabilitar el servidor de Jack. Para hacerlo, configura SERVER=false en $HOME/.jack. La compilación de CTS es lenta debido a la integración actual de vm-tests-tf. Las herramientas de manipulación de códigos de bytes (como JaCoCo) no son compatibles.

Cómo usar Jack

Jack admite el lenguaje de programación Java 1.7 y, luego, integra las funciones adicionales que se describen a continuación.

Proceso de pre-dexing

Cuando generas un archivo de la biblioteca de Jack, se genera el archivo .dex de la biblioteca y se guarda dentro del archivo de biblioteca .jack como pre-dex. Cuando realizas la compilación, Jack vuelve a usar el pre-dex de cada biblioteca. Todas las bibliotecas pasan por un proceso de pre-dexing.

Bibliotecas de Jack con proceso de pre-dexing.

Figura 4: Bibliotecas de Jack con proceso de pre-dexing.

Jack no vuelve a usar la biblioteca con proceso de pre-dexing si en la compilación se utiliza reducción, ofuscación o modificación.

Compilación incremental

La compilación incremental significa que solo se vuelven a compilar los componentes modificados desde la última compilación (y sus dependencias). La compilación incremental puede ser bastante más rápida que una compilación completa cuando los cambios se limitan a un conjunto de componentes.

La compilación incremental está inhabilitada de manera predeterminada (y se desactiva automáticamente cuando se habilita la opción de reducción, ofuscación, modificación o legado multidex). Para habilitar compilaciones incrementales, agrega la siguiente línea al archivo Android.mk del proyecto que deseas compilar de forma incremental:

LOCAL_JACK_ENABLED := incremental

Reducción y ofuscación

Jack usa los archivos de configuración de ProGuard para habilitar las opciones de reducción y ofuscación.

Esta son algunas de las opciones comunes:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (solo se admite un archivo .jar de resultados)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

Estas son algunas opciones de reducción:

  • -dontshrink

Estas son algunas opciones de ofuscación:

  • -dontobfuscate
  • -printmapping
  • -applymapping
  • -obfuscationdictionary
  • -classobfuscationdictionary
  • -packageobfuscationdictionary
  • -useuniqueclassmembernames
  • -dontusemixedcaseclassnames
  • -keeppackagenames
  • -flattenpackagehierarchy
  • -repackageclasses
  • -keepattributes
  • -adaptclassstrings

Las opciones omitidas incluyen lo siguiente:

  • -dontoptimize (Jack no optimiza)
  • -dontpreverify (Jack no realiza verificación previa)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

Modificación y reempaquetado

Jack usa archivos de configuración jarjar para realizar ediciones. Si bien Jack es compatible con tipos de reglas "rule", no lo es con tipos de reglas "zap" ni "keep".

Asistencia con multidex

Jack ofrece soporte integrado para multidex heredado. Como los archivos dex tienen un límite de 65,000 métodos, las aplicaciones con más de 65,000 métodos deben dividirse en varios archivos dex. Para obtener más información, consulta Cómo habilitar multidex para aplicaciones con más de 64,000 métodos.