É possível especificar um Java classpath
que inclua um arquivo JAR contido em outro arquivo JAR?
É possível especificar um Java classpath
que inclua um arquivo JAR contido em outro arquivo JAR?
Respostas:
Se você está tentando criar um único jar que contém seu aplicativo e suas bibliotecas necessárias, há duas maneiras (que eu conheço) de fazer isso. O primeiro é o One-Jar , que usa um carregador de classe especial para permitir o aninhamento de frascos. O segundo é o UberJar , (ou Shade ), que explode as bibliotecas incluídas e coloca todas as classes no jarro de nível superior.
Também devo mencionar que UberJar e Shade são plugins para Maven1 e Maven2, respectivamente. Como mencionado abaixo, você também pode usar o plug-in de montagem (que na realidade é muito mais poderoso, mas muito mais difícil de configurar corretamente).
Você NÃO deseja usar as soluções "explodir conteúdo JAR". Eles definitivamente tornam mais difícil ver as coisas (já que tudo é explodido no mesmo nível). Além disso, pode haver conflitos de nomenclatura (não deve acontecer se as pessoas usarem pacotes adequados, mas você nem sempre pode controlar isso).
O recurso que você deseja é um dos 25 principais RFEs da Sun : RFE 4648386 , que a Sun, em sua infinita sabedoria, designou como de baixa prioridade. Só podemos esperar que a Sun acorde ...
Enquanto isso, a melhor solução que eu encontrei (que eu gostaria que a Sun copiasse no JDK) é usar o carregador de classes personalizado JarClassLoader .
activation.jar
)
Após algumas pesquisas, encontrei um método que não requer o maven ou qualquer extensão / programa de terceiros.
Você pode usar "Caminho da classe" no seu arquivo de manifesto.
Por exemplo:
Criar arquivo de manifesto MANIFEST.MF
Manifest-Version: 1.0
Created-By: Bundle
Class-Path: ./custom_lib.jar
Main-Class: YourMainClass
Compile todas as suas aulas e execute jar cfm Testing.jar MANIFEST.MF *.class custom_lib.jar
c
significa criar archive
f
indica que você deseja especificar o arquivo
v
é para entrada detalhada
m
significa que passaremos o arquivo de manifesto personalizado
Certifique-se de incluir a lib no pacote jar. Você deve conseguir executar o jar da maneira normal.
com base em: http://www.ibm.com/developerworks/library/j-5things6/
todas as outras informações necessárias sobre o caminho da classe que você encontra aqui
custom_lib.jar
para longe, o frasco não pode ser executado mais :(
Use a tag zipgroupfileset (usa os mesmos atributos de uma tag do conjunto de arquivos ); descompactará todos os arquivos no diretório e será adicionado ao seu novo arquivo. Mais informações: http://ant.apache.org/manual/Tasks/zip.html
Essa é uma maneira muito útil de contornar o problema do jar-in-a-jar - eu sei porque pesquisei essa questão exata do StackOverflow ao tentar descobrir o que fazer. Se você deseja empacotar um jar ou uma pasta de jars no seu jar com o Ant, esqueça todos esses caminhos de classe ou plug-ins de terceiros, tudo o que você precisa fazer é o seguinte (no Ant):
<jar destfile="your.jar" basedir="java/dir">
...
<zipgroupfileset dir="dir/of/jars" />
</jar>
Se você estiver construindo com ant (estou usando ant do eclipse), basta adicionar os arquivos jar adicionais dizendo ao ant para adicioná-los ... Não é necessariamente o melhor método para manter um projeto mantido por várias pessoas, mas ele funciona para um projeto de uma pessoa e é fácil.
por exemplo, meu destino que estava criando o arquivo .jar era:
<jar destfile="${plugin.jar}" basedir="${plugin.build.dir}">
<manifest>
<attribute name="Author" value="ntg"/>
................................
<attribute name="Plugin-Version" value="${version.entry.commit.revision}"/>
</manifest>
</jar>
Acabei de adicionar uma linha para torná-lo:
<jar ....">
<zipgroupfileset dir="${external-lib-dir}" includes="*.jar"/>
<manifest>
................................
</manifest>
</jar>
Onde
<property name="external-lib-dir"
value="C:\...\eclipseWorkspace\Filter\external\...\lib" />
foi o dir com os frascos externos. E é isso...
Você precisa criar um carregador de classes personalizado para fazer isso ou uma biblioteca de terceiros que suporte isso. Sua melhor aposta é extrair o jar do tempo de execução e adicioná-los ao caminho de classe (ou tê-los já adicionados ao caminho de classe).
Eu uso o maven para minhas compilações java, que tem um plugin chamado maven assembly plugin .
Ele faz o que você pede, mas como algumas das outras sugestões descrevem - basicamente explodindo todos os frascos dependentes e recombinando-os em um único frasco
Se você eclipsou o IDE, basta exportar seu JAR e escolher "Bibliotecas necessárias para o pacote no JAR gerado". O eclipse incluirá automaticamente os JARs dependentes necessários no JAR gerado, bem como gerou algum carregador de classes customizado do eclipse que carrega esses JARs automaticamente.
Winstone é muito bom http://blog.jayway.com/2008/11/28/executable-war-with-winstone-maven-plugin/ . Mas não para sites complexos. E isso é uma pena, porque basta incluir o plugin.
Bem, existe uma maneira muito fácil se você estiver usando o Eclipse.
Exporte seu projeto como um arquivo Jar "Executável" (clique com o botão direito do mouse na pasta do projeto no Eclipse, selecione "Exportar ..."). Ao definir as configurações de exportação, selecione "Extrair bibliotecas necessárias para o jar gerado". Lembre-se de selecionar "Extrair ..." e não "Empacotar bibliotecas necessárias ...".
Além disso : você deve selecionar uma configuração de execução nas suas configurações de exportação. Portanto, você sempre pode criar um main () vazio em alguma classe e usá-lo para sua configuração de execução.
De qualquer forma, não é garantido que funcione 100% do tempo - pois você verá uma mensagem pop-up solicitando que você verifique as licenças dos arquivos Jar incluídos e algo sobre não copiar arquivos de assinatura. No entanto, faço isso há anos e nunca encontrei um problema.
A extração para um Uber-dir funciona para mim, pois todos devemos usar root: \ java e ter código de saída em pacotes com controle de versão. Ou seja, ca.tecreations-1.0.0. A assinatura está correta porque os frascos estão intactos no local baixado. Assinaturas de terceiros intactas, extraídas para c: \ java. Aqui está o meu diretor de projeto. executar a partir do iniciador para java -cp c: \ java Launcher