Empacotando Nemo
dezembro 15th, 2006 | by Aldrin Leal |(Post técnico – Vida pessoal ainda vegetativa)
No meu entretenimento atual (breve a ser apresentado ao grande público – stay tuned!), um detalhe me chamou a atenção: O quanto realmente perdemos de espaço, em aplicações java. E o quanto ainda temos que aprender (a despeito de inúmeras soluções de gerência integrada de artefatos e dependências encontradas por aí).
Ok, antes disso, um prólogo: Parte da idéia do meu projeto é demonstrar a viabilidade técnica do que eu chamo de aplicações pervasivas. Sabe aquele programinha útil que você sempre mantém no seu pendrive ou CD? Então, isto é um nicho interessantíssimo.
Na maioria absoluta dos casos, as aplicações que empacotam tem uma característica de executáveis desktop. E porque não aplicações web? Bem, isto envolve a necessidade de pensar sobre as seguintes coisas:
- Aonde persistir os dados? No disco rígido, na mídia móvel, em rede, ou em lugar algum?
- Como integrar os zilhões de dependências de uma pilha Web necessita, de forma portável? Isto é, como consigo empacotar o servidor, seus logs, sua área de comunicação inter-processo, e seus módulos nativos para outras linguagens?
- Além disso, será que cabe neste espaço disponível?
Com relação aos isso, decidi basear a solução nas seguintes premissas
- Uso de um bom container genérico de componentes, permitindo a inclusão e a exclusão de features através de componentes;
Assim, com este container, todos os aspectos ficam gerenciáveis a partir de descritores. Uma nova necessidade, um novo componente. E assim a solução se ajusta.
Que tipos de abstrações são necessárias? As principais são: Serviços de Persistência (RDBMS, FileSystem, Configuração, Propriedades), Serviços de Conectividade (SSH, HTTP, SMTP), e Serviços de Localização e Publicação de Recursos (LiveTribe, Bonjour, Container), Logging, Cache, entre outros. Em suma: Tudo aquilo que, em um ambiente de servidor, é tido como de facto, fica sujeito a questionamentos. Como gosto e questionar, acho que a abordagem é válida.
A partir deste container, permitir que os diversos aspectos (storage, logging, IPC, JNI) sejam abstraídos conforme a disponibilização destes componentes;
- Fatorar a questão do storage
Minhas propriedades podem ficar num lugar (persistido na memória, carregado via HTTP, serializado via SFTP), a base em outro (Embedded, ou via um Tunnel SSH), e a aplicação pode continuar no pendrive. Porque não, portanto, permitir que sejam criadas “Zonas” de Storage, como componentes, e disponíveis para os outros serviços? No caso particular, isto é feito através do commons-vfs.
- Gerência de Dependência (ainda indefinido – mantenha-se alerta!)
Este conceito é relativamente novo, mas popularizado por idéias como o Maven (particularmente, o Maven 2), Transit, e agora, o Ivy. Consiste em gerenciar quais classes devem ser carregadas para atender as necessidades de outra e, além disso, permitir a sua resolução dinâmica através de repositórios). Ainda não cheguei a um consenso sobre a isto.
- Empacotamento de Aplicações Java usando técnicas agressivas de otimização de espaço, ou, empacotamento de forma clássica (arquivo zip);
Já ouviu falar no Pack200? Bem, vamos a alguns números, relativos a um stub de carga/resolução de artefatos mínimo para o pocketserver:
Arquivo .jar, sem a inclusão das dependências:
-rw-r–r– 1 aldrin aldrin 8150 2006-12-15 12:05 pocketserver-bootstrap-0.0.1-SNAPSHOT.jar
Nada mal, ok? Aplicando o Jar Jar Links (não esse, mas esse), eu consigo fazer com que as dependências sejam embutidas como um subpacote do pacote principal. Resultado? Isto:
-rw-r–r– 1 aldrin aldrin 3290958 2006-12-15 12:05 pocketserver-bootstrap-0.0.1-SNAPSHOT-full.jar
3.3 Mib? Não era 8K? Era… Ok, vamos refazer o jar, porém aplicando alguma filtragem, e excluindo pacotes que serão desnecessários:
-rw-r–r– 1 aldrin aldrin 1182446 2006-12-15 12:26 pocketserver-bootstrap-standalone-0.0.1-SNAPSHOT.jar
Melhorou. Agora, pack200 para o tiro de misericórdia. Vou pular os detalhes (exige uma explicação sobre compressão lossy, teoria da informação, e compressão/arquivamento). Mas, se queres uma boa noção, ele é uma compressão lossy (estilo .jpg e .mp3, aonde a descompactação não é necessariamente fiel ao arquivo de origem), alinhado com a lógica de compressão após arquivo (i.e., “-Porque meu .tar.gz é menor que o meu .zip”):
-rw-r–r– 1 aldrin aldrin 184475 2006-12-15 12:26 pocketserver-bootstrap-0.0.1-SNAPSHOT-optimized-full.pack.gz
Mas pera, não é um jar. Sim, com razão. O pack200 foi feito para ser usado basicamente pelo JNLP (i.e., Java WebStart). Porém, com alguns ajustes (em breve – caaaalma!), meu módulo de Pack200 pra Jar para o commons-vfs deve reproduzir o efeito desejado). Sem perda de performance, um ganho de mais de 20x em relação ao primeiro jar completo.
E aí fica a dúvida? Será que estamos preparados para isso?
You must be logged in to post a comment.