Compilar com o Jack para o Android 6.0 a 8.1

Ele era uma cadeia de ferramentas do Android que compilava fonte Java em bytecode dex do Android. Você não precisa fazer nada diferente para usar o Jack, apenas usar seus comandos makefile padrão para compilar a árvore ou o projeto. O Android 8.1 é a última versão que usa o Jack.

Sobre o Jack

O Jack funciona como mostrado na Figura 1.

Visão geral do Jack
Figura 1. Visão geral do Jack

Formato da biblioteca do Jack

O Jack tem o próprio formato de arquivo .jack, que contém o código dex pré-compilado para a biblioteca, possibilitando uma compilação mais rápida (pré-dex).

Conteúdo do arquivo da biblioteca do Jack
Figura 2. Conteúdo do arquivo da biblioteca do Jack

Jill

A ferramenta Jill converte as bibliotecas .jar existentes no novo formato de biblioteca, como mostrado abaixo.

Como importar bibliotecas .jar com o Jill
Figura 3. Fluxo de trabalho para importar uma biblioteca .jar existente

Servidor de compilação do Jack

A primeira vez que o Jack é usado, ele abre um servidor de compilação Jack local no seu computador, que:

  • traz um aumento de velocidade intrínseco, porque evita a abertura de um novo host JRE JVM, o carregamento do código do Jack, a inicialização do Jack e o aquecimento do JIT a cada compilação. Ele também oferece tempos de compilação muito bons durante pequenas compilações (por exemplo, no modo incremental);
  • é uma solução de curto prazo para controlar o número de compilações Jack paralelas. O servidor evita sobrecarregar seu computador (problema de memória ou de disco) porque limita o número de compilações paralelas.

O servidor do Jack se desativa após um tempo ocioso sem nenhuma compilação. Ele usa duas portas TCP na interface do localhost e não está disponível externamente. Todos os parâmetros (número de compilações paralelas, tempo limite, número de portas etc.) podem ser modificados editando o arquivo $HOME/.jack.

Arquivo $HOME/.jack

O arquivo $HOME/.jack contém as seguintes configurações para as variáveis do servidor do Jack em uma sintaxe bash completa:

  • SERVER=true ativa o recurso de servidor do Jack.
  • SERVER_PORT_SERVICE=8072 define o número da porta TCP do servidor para fins de compilação.
  • SERVER_PORT_ADMIN=8073 define o número da porta TCP do servidor para fins administrativos.
  • SERVER_COUNT=1 não é usado.
  • SERVER_NB_COMPILE=4 define o número máximo de compilações paralelas permitidas.
  • SERVER_TIMEOUT=60 define o número de segundos ociosos que o servidor precisa aguardar sem qualquer compilação antes de se desligar.
  • SERVER_LOG=${SERVER_LOG:=$SERVER_DIR/jack-$SERVER_PORT_SERVICE.log} define o arquivo em que os registros do servidor são gravados. Por padrão, essa variável pode ser sobrecarregada por uma variável de ambiente.
  • JACK_VM_COMMAND=${JACK_VM_COMMAND:=java} define o comando padrão usado para iniciar um JVM no host. Por padrão, essa variável pode ser sobrecarregada pela variável de ambiente.

Solução de problemas de compilação do Jack

Problema Ação
Seu computador deixa de responder durante a compilação ou você percebe que as compilações do Jack falham com Erro de falta de memória Reduza o número de compilações simultâneas do Jack editando $HOME/.jack e alterando SERVER_NB_COMPILE para um valor mais baixo.
As compilações estão falhando com Não é possível iniciar o servidor em segundo plano A causa mais provável é que as portas TCP já estão sendo usadas no seu computador. Altere as portas editando $HOME/.jack (as variáveis SERVER_PORT_SERVICE e SERVER_PORT_ADMIN). Para resolver a situação, desative o servidor de compilação do Jack editando $HOME/.jack e alterando SERVER para false. Infelizmente, isso diminui significativamente a velocidade da sua compilação e pode obrigar você a abrir make -j com controle de carga (opção -l de make).
A compilação é interrompida sem qualquer progresso Para resolver a situação, elimine o servidor em segundo plano do Jack usando jack-admin kill-server) e remova os diretórios temporários contidos em jack-$USER do seu diretório temporário (/tmp ou $TMPDIR).

Como encontrar o log do Jack

Se você executar um comando make com um destino dist, o log do Jack estará em $ANDROID_BUILD_TOP/out/dist/logs/jack-server.log. Caso contrário, você pode encontrar o log executando jack-admin server-log. Em caso de falhas do Jack reproduzíveis, veja um log mais detalhado definindo a seguinte variável:

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

Use comandos makefile padrão para compilar a árvore (ou seu projeto) e anexar a saída padrão e o erro. Para remover os logs de criação detalhados, execute:

unset ANDROID_JACK_EXTRA_ARGS

Limitações do Jack

  • Por padrão, o servidor do Jack pode ser usado por apenas um usuário em um computador. Para aceitar mais usuários, selecione diferentes números de porta para cada um deles e ajuste o SERVER_NB_COMPILE corretamente. Também é possível desativar o servidor do Jack configurando SERVER=false em $HOME/.jack.
  • A compilação do CTS é lenta devido à integração atual do vm-tests-tf.
  • As ferramentas de manipulação de bytecode (como o JaCoCo) não são compatíveis.

Como usar o Jack

O Jack é compatível com a linguagem de programação Java 1.7 e integra os outros recursos descritos abaixo.

Pré-dexação

Ao gerar um arquivo de biblioteca do Jack, o .dex da biblioteca é gerado e armazenado dentro do arquivo de biblioteca .jack como um pré-dex. Durante a compilação, o Jack reutiliza o pré-dex de cada biblioteca. Todas as bibliotecas são pré-dexadas:

Bibliotecas do Jack com pré-dex
Figura 4. Bibliotecas do Jack com pré-dex

O Jack não reutiliza o pré-dex da biblioteca se for usada a redução, ofuscação ou o reempacotamento na compilação.

Compilação incremental

Compilação incremental significa que somente os componentes modificados desde a última compilação (e as dependências deles) são recompilados. A compilação incremental pode ser significativamente mais rápida do que uma compilação completa quando as alterações se limitam a um conjunto de componentes.

A compilação incremental é desativada por padrão e é desativada automaticamente quando a redução, o ofuscamento, o reempacotamento ou o legado de multidex está habilitado. Para ativar compilações incrementais, inclua a linha a seguir no arquivo Android.mk do projeto que você quer criar de forma incremental:

LOCAL_JACK_ENABLED := incremental

Redução e ofuscação

O Jack usa arquivos de configuração do ProGuard para permitir a redução e a ofuscação.

Entre as opções comuns estão as seguintes:

  • @
  • -include
  • -basedirectory
  • -injars
  • -outjars (apenas 1 jar de saída permitido)
  • -libraryjars
  • -keep
  • -keepclassmembers
  • -keepclasseswithmembers
  • -keepnames
  • -keepclassmembernames
  • -keepclasseswithmembernames
  • -printseeds

Entre as opções de redução está a seguinte:

  • -dontshrink

Entre as opções de ofuscação estão as seguintes:

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

Entre as opções ignoradas estão as seguintes:

  • -dontoptimize (Jack não otimiza)
  • -dontpreverify (Jack não faz a pré-verificação)
  • -skipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclasses
  • -dontskipnonpubliclibraryclassmembers
  • -keepdirectories
  • -target
  • -forceprocessing
  • -printusage
  • -whyareyoukeeping
  • -optimizations
  • -optimizationpasses
  • -assumenosideeffects
  • -allowaccessmodification
  • -mergeinterfacesaggressively
  • -overloadaggressively
  • -microedition
  • -verbose
  • -dontnote
  • -dontwarn
  • -ignorewarnings
  • -printconfiguration
  • -dump

Reempacotamento

O Jack usa arquivos de configuração jarjar para realizar o reempacotamento. Embora o Jack seja compatível com os tipos de regra "rule", ele não é compatível com os tipos de regra "zap" ou "keep".

Compatibilidade com multidex

O Jack oferece compatibilidade nativa e legada com multidex. Como os arquivos dex estão limitados a 65 mil métodos, os apps com mais do que isso precisam ser divididos em vários arquivos dex. Para ver mais detalhes, consulte Ativar multidex para apps com mais de 64 mil métodos.