Arquivos .JAR

em 23/07/2003 , por Samuel Mota
Introdução
Inicialmente teremos uma visão geral sobre o que é e porque utilizar arquivos JAR, que é o mais importante. Depois temos uma referencia dos comandos usados para manipulação e criação dos arquivos .jar. JAR é a sigla para Java ARchive e é o formato criado pela SUN, baseado no mesmo formato de compactação de arquivos ZIP, para distribuir aplicações, ou bibliotecas, através de um só arquivo. Em um arquivo JAR pode-se incluir qualquer tipo de arquivo como: classes, imagens, preferences, entre outros. O formato foi criado na versão 1.1 do JDK e muito aperfeiçoado na 1.2 sinalizando sua aceitação. Hoje em dia é essencial. A própria API do java é distribuída em arquivos JAR, veja os arquivos dt.jar e tools.jar no subdiretório lib da sua JDK. Algumas características do arquivo JAR:
  • Permite comprimir seu conteúdo facilitando a transmissão da aplicação via rede;
  • Pode ser assinado digitalmente aumentando a segurança na utilização da aplicação;
  • É independente de plataforma;
  • Contém informações de versão melhorando a distribuição e atualização;
    Cenário
    Seu cliente gostaria de receber, como resultado final de um projeto, centenas de arquivos .class, imagens e outros, todos em diferentes diretórios, de maneira caótica? É muito mais interessante, por simplicidade e praticidade, que o resultado final seja apresentado em poucos arquivos, ou módulos. Um dos principais cenários de uso de arquivos JAR é a distribuição de applets principalmente pela facilidade de enviar de uma só vez todos os arquivos necessários para o cliente. Uma aplicação Web, composta por servlets e JSPs, também pode ser distribuída em Jars (na verdade um WAR). Avançando um pouco o uso da ferramenta de distribuição Java Web start baseia-se em arquivos JAR. Aplicações stand-alone podem ser mais facilmente distribuídas com arquivos JAR por eliminar a necessidade de referencias completas de caminhos dos arquivos.
    Estrutura do arquivo
    A especificação do formato JAR define como obrigatório apenas a existencia do arquivo de manifesto em um diretório chamado META-INF. Este diretório pode ainda conter outros arquivos de controle como o índice index.lst que deve agilizar a busca dos arquivos, a assinatura do arquivo e alguns outros. No mais o arquivo JAR apenas contém os arquivos que incluimos, com informações de caminho utilizadas para busca no classpath. A seguir veremos com mais detalhes o arquivo de Manifesto.
    Manifesto
    O manifesto é um arquivo texto usado para definir dados do arquivo JAR e é obrigatório. Este arquivo é o principal ponto que se deve conhecer para tirar o máximo proveito das características do JAR pois é nele que definimos todos os atributos deste arquivo. Na criação do JAR se não especificarmos um manifesto ele será criado automaticamente apenas com a informação de versão do manifesto:

    Esta é a informação básica que nosso manifesto deve conter. Existem diversas diretivas que o manifesto pode conter, uma manifesto básico terá a seguinte forma:
    Manifest-Version: 1.0
    Name: br/com/guj/artigoJAR
    Created-By: Samuel Mota
    
    JAR e o classpath
    Se tivermos uma estrutura de diretório como na imagem:
    Ao criarmos o jar a partir do diretório pai da estrutura (a raiz, antes do diretório br) teremos dentro do nosso arquivo a descrição dessa árvore. Considere que esse jar é uma biblioteca, e queremos usá-la. Para podermos utilizar as classes desse pacote JAR devemos adiciona-lo ao classpath quando chamarmos um programa:
    java -cp artigo.jar Teste
    
    Para importar os arquivos classe desse exemplo na classe Teste.java usaríamos:

    Ao encontrar essa instrução o ClassLoader (responsável por procurar as classes que serão utilizadas) irá pesquisar no bootclasspath e depois em artigo.jar, já que indicamos, através da opção -cp. que o jar faz parte do classpath. Atenção: quando utilizamos arquivos JAR no classpath não é possivel adicionar um diretório que contenha vários JAR, é necessário adicionar um a um para que o ClassLoader possa procurar em todos os arquivos.
    Classpath e o JAR
    Muitas vezes nossa aplicação utiliza vários arquivos JAR. Para evitarmos a necessidade de expecificar no classpath da inicialização de nossa aplicação todos os arquivos necessários podemos usar o atributo Class-Path. O valor desse atributo deve ser o caminho para os arquivos JAR ou diretórios a partir da localização do JAR. Este valor é adicionado ao classpath passado na linha de comando ou do sistema. Exemplo
    Class-Path gui.jar lib\commons-logging.jar lib\jasper.jar
    
    O pacote jar que contenha o manifesto com a linha acima poderá utilizar todas as classes do arquivo gui.jar e dos arquivos citados no subdiretório lib a partir da localização do JAR. Este recurso facilita pois não é necessário conhecer o caminho completo dos arquivos .jar para adiciona-los ao classpath.
    JAR executável
    Para poder tornar o arquivo JAR como um executável devemos adicionar o atributo Main-Class ao manifesto. O valor desse atributo deve ser o nome completo da classe, incluindo a package a que ele pertence, que contenha o método public static void main(String[] args) isto é, que seja o ponto de entrada da nossa aplicação. No exemplo deste artigo, supondo que classeA seja o ponto de entrada para minha aplicação o manifesto deverá conter:
    Main-Class: br.com.guj.artigoJAR.classeA
    Como os sistemas operacionais associam o .jar ao java, um duplo clique em um JAR que contém essa propriedade irá ter o mesmo efeito de chamar a tal classe tendo este jar como classpath. Isso dá a impressão de que esse jar é "executável".
    Guia rápido
    Para você criar o seu próprio JAR, a maneira mais simples é usar a ferramenta jar que acompanha o J2SDK. Utilize jar -help para outras opções. A seguir seguem os principais comandos para a criação e manipulação do arquivo JAR:
    OperaçãoComando
    Criar arquivo JARjar cf arquivo.jar "arquivos ou diretórios com Wildcards"
    Criar arquivo JAR com manifestojar cmf "arquivo manifesto" arquivo.jar "arquivos ou diretórios com Wildcards"
    Listar o conteúdo de um arquivo jar tf arquivo.jar
    Extrair todo o conteúdo do arquivo jar xf arquivo.jar
    Extrair arquivo(s) específicos o arquivo jar xf arquivo.jar "arquivos ou diretórios com Wildcards"
    Atualizar arquivos em um arquivo jar uf arquivos ou diretórios com Wildcards
    Executar uma aplicação de um arquivo(JRE versao 1.1 ou sem Main-Class)java -cp arquivo.jar classeAplicacao
    Executar uma aplicação de um arquivo(versão 1.2 com Main-Class) java -jar arquivo.jar
    Conclusão
    Adotar arquivos JAR como formato de distribuição de suas aplicações dá uma ótima impressão de profissionalismo, além é claro de facilitar algumas tarefas como atualização da aplicação, download e instalação. Uma desvantagem é que, para atualizar uma classe distribuída em um pacote JAR, você terá que atualizar todo o arquivo, mas isso pode ser amenizado com um bom planejamento na criação de pacotes dividindo-se a aplicação em grupos atualizáveis e utilizando-se o classpath para formar o ambiente completo da aplicação.
    Referências
    Alguns links de referencia: JAR Files Trail no The Java Tutorial. Artigo no Java World sobre organização e arquivos jar. JAR Files na SUN. Espero reve-los em breve!