Quero empacotar meu projeto em um único JAR executável para distribuição.
Como posso fazer um projeto do Maven empacotar todos os JARs de dependência no meu JAR de saída?
Quero empacotar meu projeto em um único JAR executável para distribuição.
Como posso fazer um projeto do Maven empacotar todos os JARs de dependência no meu JAR de saída?
Respostas:
e você executa com
O objetivo de compilação deve ser adicionado antes da montagem: único ou não, o código em seu próprio projeto não está incluído.
Veja mais detalhes nos comentários.
Geralmente, esse objetivo está vinculado a uma fase de construção para ser executada automaticamente. Isso garante que o JAR seja construído ao executar
mvn install
ou executar uma implementação / liberação.fonte
mvn clean compile assembly:single
.<appendAssemblyId>false</appendAssemblyId>
noconfiguration
para evitar o irritante sufixo "-jar-with-dependencies" no nomecompile
e você está ferrado.Você pode usar o plug-in de dependência para gerar todas as dependências em um diretório separado antes da fase do pacote e incluir isso no caminho de classe do manifesto:
Como alternativa, use
${project.build.directory}/classes/lib
como OutputDirectory para integrar todos os arquivos jar no jar principal, mas você precisará adicionar um código de carregamento de classe personalizado para carregar os jars.fonte
${project.build.directory}/classes/lib
comooutputDirectory
ter um .jar principal com todas as dependências dentro, mas - Como adicionar código de carregamento de classe personalizado para carregar esses jars? Eu preciso fazer execução de obras como:java -jar main-jar-with-deps.jar
. Isso é possível ?Eu escrevi sobre algumas maneiras diferentes de fazer isso.
Consulte Jar executável com Apache Maven (WordPress)
ou executável-jar-com-maven-exemplo (GitHub)
Notas
Esses prós e contras são fornecidos por Stephan .
Para implantação manual
Copiar dependências para um diretório específico
Tornar o jar executável e o caminho de classe consciente
Nesse ponto, ele
jar
é realmente executável com elementos externos do caminho de classe.Criar arquivos implantáveis
O
jar
arquivo é apenas executável com o...lib/
diretório irmão . Precisamos criar arquivos para implantar com o diretório e seu conteúdo.Agora você tem
target/${project.build.finalName}.(zip|tar|tar.bz2|tar.gz)
qual contém ojar
elib/*
.Plugin de Montagem do Apache Maven
Você tem
target/${project.bulid.finalName}-jar-with-dependencies.jar
.Apache Maven Shade Plugin
Você tem
target/${project.build.finalName}-shaded.jar
.onejar-maven-plugin
Spring Boot Maven Plugin
Você tem
target/${project.bulid.finalName}-spring-boot.jar
.fonte
Tomando a resposta não respondida e reformatá-la, temos:
Em seguida, eu recomendaria tornar isso uma parte natural da sua compilação, em vez de algo para chamar explicitamente. Para tornar isso parte integrante de sua construção, inclua esse plug-in no seu
pom.xml
e vincule-o aopackage
evento do ciclo de vida. No entanto, um problema é que você precisa chamar oassembly:single
objetivo se colocar isso em seu pom.xml, enquanto chamaria 'assembly: assembly' se o executasse manualmente a partir da linha de comando.fonte
Use o maven-shade-plugin para empacotar todas as dependências em um uber-jar. Também pode ser usado para criar um jar executável, especificando a classe principal. Depois de tentar usar o maven-assembly e o maven-jar, descobri que esse plugin era mais adequado às minhas necessidades.
Achei esse plugin particularmente útil, pois mescla o conteúdo de arquivos específicos em vez de substituí-los. Isso é necessário quando existem arquivos de recursos com o mesmo nome nos jars e o plug-in tenta empacotar todos os arquivos de recursos
Veja o exemplo abaixo
fonte
Long usou o plug-in maven assembly , mas não consegui encontrar uma solução para o problema
"already added, skipping"
. Agora, estou usando outro plugin - onejar-maven-plugin . Exemplo abaixo (mvn package
jar de compilação):Você precisa adicionar repositório para esse plug-in:
fonte
Você pode usar o maven-dependency-plugin, mas a questão era como criar um JAR executável. Para fazer isso, é necessária a seguinte alteração na resposta de Matthew Franglen (btw, o uso do plug-in de dependência leva mais tempo para compilar ao iniciar a partir de um destino limpo):
fonte
Você pode usar o plugin maven-shade para criar um uber jar como abaixo
fonte
Outra opção se você realmente deseja reembalar o conteúdo de outros JARs em seu JAR resultante único é o plug-in Maven Assembly . Descompacta e depois empacota tudo em um diretório via
<unpack>true</unpack>
. Então você teria um segundo passe que o incorporou em um JAR maciço.Outra opção é o plugin OneJar . Isso executa as ações de reembalagem acima, tudo em uma única etapa.
fonte
Você pode adicionar o seguinte ao seu pom.xml :
Depois, você deve alternar através do console para o diretório em que o pom.xml está localizado. Então você deve executar o assembly mvn: single e, em seguida, seu arquivo JAR executável com dependências será compilado. Você pode verificá-lo ao alternar para o diretório de saída (destino) com cd ./target e iniciar seu jar com um comando semelhante ao java -jar mavenproject1-1.0-SNAPSHOT-jar-with-dependencies.jar .
Eu testei isso com o Apache Maven 3.0.3 .
fonte
Eu passei por todas essas respostas procurando criar um frasco executável gordo contendo todas as dependências e nenhuma delas funcionou corretamente. A resposta é o plugin de sombra, é muito fácil e direto.
Esteja ciente de que suas dependências precisam ter um escopo de compilação ou tempo de execução para que isso funcione corretamente.
Este exemplo veio de mkyong.com
fonte
plugin
elemento entrapom.xml
embaixobuild/plugins
.Você pode combinar o
maven-shade-plugin
emaven-jar-plugin
.maven-shade-plugin
agrupa suas classes e todas as dependências em um único arquivo jar.maven-jar-plugin
para especificar a classe principal do seu jar executável (consulte Configurar o caminho de classe , capítulo "Tornar o jar executável").Exemplo de configuração do POM para
maven-jar-plugin
:Por fim, crie o jar executável chamando:
fonte
Ken Liu está certo na minha opinião. O plug-in de dependência maven permite expandir todas as dependências, que podem ser tratadas como recursos. Isso permite que você os inclua no artefato principal . O uso do plug-in assembly cria um artefato secundário que pode ser difícil de modificar - no meu caso, eu queria adicionar entradas de manifesto personalizadas. Meu pom acabou como:
fonte
Deveria ser assim:
A descompactação deve estar na fase de gerar recursos, pois, se estiver na fase de pacote, não será incluída como recurso. Tente pacote limpo e você verá.
fonte
Problema ao localizar o arquivo de montagem compartilhado com o maven-assembly-plugin-2.2.1?
Tente usar o parâmetro de configuração descriptorId em vez dos parâmetros descriptors / descriptor ou descriptorRefs / descriptorRef.
Nenhum deles faz o que você precisa: procure o arquivo no caminho de classe. É claro que você precisa adicionar o pacote no qual o assembly compartilhado reside no caminho de classe do maven-assembly-plugin (veja abaixo). Se você estiver usando o Maven 2.x (não o Maven 3.x), pode ser necessário adicionar essa dependência no pom.xml principal do pai na seção pluginManagement.
Veja isso para mais detalhes.
Classe: org.apache.maven.plugin.assembly.io.DefaultAssemblyReader
Exemplo:
fonte
Para resolver esse problema, usaremos o Maven Assembly Plugin que criará o JAR junto com seus JARs de dependência em um único arquivo JAR executável. Basta adicionar a configuração do plugin abaixo no seu arquivo pom.xml.
Depois de fazer isso, não esqueça de executar a ferramenta MAVEN com este comando mvn clean compile assembly: single
http://jkoder.com/maven-creating-a-jar-together-with-its-dependency-jars-into-a-single-executable-jar-file/
fonte
Não responderei diretamente à pergunta, já que outras pessoas já fizeram isso antes, mas realmente me pergunto se é uma boa idéia incorporar todas as dependências no próprio jarro do projeto.
Entendo o ponto (facilidade de implantação / uso), mas isso depende do caso de uso do seu projeto (e pode haver alternativas (veja abaixo)).
Se você o usar totalmente independente, por que não.
Mas se você usar seu projeto em outros contextos (como em um aplicativo da Web ou soltar em uma pasta onde estão os outros jarros), poderá haver duplicatas jar em seu caminho de classe (os que estão na pasta e os que estão nos jarros). Talvez não seja um negócio de lances, mas geralmente evito isso.
Uma boa alternativa:
Assim, no final, apenas um manifesto e um "carregador de classe dinâmico especial principal", você pode iniciar seu projeto com:
fonte
Para criar um JAR executável a partir da própria linha de comando, execute o comando abaixo no caminho do projeto:
fonte
pom.xml
contrárioError reading assemblies: No assembly descriptors found.
. É o que acontece comigo de qualquer maneira.Esta é a melhor maneira que encontrei:
Com essa configuração, todas as dependências serão localizadas
/dependency-jars
. Meu aplicativo não possuiMain
classe, apenas contexto, mas uma de minhas dependências possui umaMain
classe (com.myDomain.etc.MainClassName
) que inicia o servidor JMX e recebe umstart
ou umstop
parâmetro. Então, com isso, eu era capaz de iniciar meu aplicativo assim:Espero que seja útil para todos vocês.
fonte
Comparei os plugins de árvore mencionados neste post. Eu gerei 2 frascos e um diretório com todos os frascos. Comparei os resultados e, definitivamente, o maven-shade-plugin é o melhor. Meu desafio era ter vários recursos de primavera que precisavam ser mesclados, além de serviços jax-rs e JDBC. Todos foram mesclados corretamente pelo plugin de sombra em comparação com o maven-assembly-plugin. Nesse caso, a primavera falhará, a menos que você as copie para sua própria pasta de recursos e as mescle manualmente uma vez. Ambos os plugins produzem a árvore de dependência correta. Eu tinha vários escopos como teste, fornecimento, compilação, etc. o teste e o fornecimento foram ignorados pelos dois plugins. Ambos produziram o mesmo manifesto, mas consegui consolidar licenças com o plug-in de sombra usando o transformador. Com o maven-dependency-plugin, é claro que você não Não tenho esses problemas porque os frascos não são extraídos. Mas, como alguns outros apontaram, é necessário carregar um arquivo extra para funcionar corretamente. Aqui está um trecho do pom.xml
fonte
Algo que funcionou para mim foi:
Eu tive um caso extraordinário porque minha dependência era do sistema um:
Alterei o código fornecido pelo @ user189057 com as alterações: 1) o maven-dependency-plugin é executado na fase "prepare-package" 2) Estou extraindo a classe descompactada diretamente para "target / classes"
fonte
Tentei a resposta mais votada aqui e consegui que o jar fosse executável. Mas o programa não foi executado corretamente. Não sei qual foi o motivo. Quando tento executar
Eclipse
, obtenho um resultado diferente, mas quando executo o jar na linha de comando, obtenho um resultado diferente (ele trava com um erro de tempo de execução específico do programa).Eu tinha um requisito semelhante ao OP, pois tinha muitas dependências (Maven) para o meu projeto. Felizmente, a única solução que funcionou para mim foi o uso
Eclipse
. Muito simples e muito direto. Esta não é uma solução para o OP, mas é uma solução para alguém que tem um requisito semelhante, mas com muitas dependências do Maven,1) Clique com o botão direito do mouse na pasta do projeto (no Eclipse) e selecione
Export
2) Depois selecione
Java
->Runnable Jar
3) Você será solicitado a escolher o local do arquivo jar
4) Por fim, selecione a classe que possui o método Main que você deseja executar, escolha
Package dependencies with the Jar file
e clique emFinish
fonte
Isso também pode ser uma opção. Você poderá criar seu arquivo jar
fonte
Para quem procura opções para excluir dependências específicas do uber-jar, esta é uma solução que funcionou para mim:
Portanto, não é uma configuração do mvn-assembly-plugin, mas uma propriedade da dependência.
fonte
Já existem milhões de respostas, gostaria de acrescentar que você não precisa
<mainClass>
se não precisa adicionar o entryPoint ao seu aplicativo. Por exemplo, as APIs podem não ter necessariamente ummain
método.configuração do plugin maven
Construir
verificar
fonte
Adicione ao pom.xml:
e
É isso aí. O próximo pacote mvn também criará um frasco de gordura adicionalmente, incluindo todos os jars de dependência.
fonte
O maven-assembly-plugin funcionou muito bem para mim. Passei horas com o maven-dependency-plugin e não consegui fazê-lo funcionar. O principal motivo foi o fato de eu ter que definir explicitamente na seção de configuração os itens de artefato que devem ser incluídos conforme descrito na documentação . Há um exemplo para os casos em que você deseja usá-lo como:, em
mvn dependency:copy
que não há itens de artefato incluídos, mas ele não funciona.fonte
Esta postagem do blog mostra outra abordagem com a combinação dos plug-ins do maven-jar e do maven-assembly. Com o xml de configuração de montagem da postagem do blog, também pode ser controlado se as dependências serão expandidas ou apenas coletadas em uma pasta e referenciadas por uma entrada de caminho de classe no manifesto:
E exatamente esse é descrito aqui: https://caffebig.wordpress.com/2013/04/05/executable-jar-file-with-dependent-jars-using-maven/
fonte
fonte
Ok, então esta é a minha solução. Eu sei que não está usando o arquivo pom.xml. Mas eu tive o problema de meu programa compilar e executar no Netbeans, mas falhou quando tentei o Java -jar MyJarFile.jar. Agora, eu não entendo completamente o Maven e acho que foi por isso que estava tendo problemas para que o Netbeans 8.0.2 incluísse meu arquivo jar em uma biblioteca para colocá-los em um arquivo jar. Eu estava pensando em como eu costumava usar arquivos jar sem Maven no Eclipse.
É o Maven que pode compilar todos os dependanices e plugins. Não Netbeans. (Se você pode obter o Netbeans e poder usar java .jar para fazer isso, diga-me como (^. ^) V)
[Resolvido - para Linux] abrindo um terminal.
Então
Próximo
Próximo
Isso criará um arquivo jar no diretório de destino.
Agora
(Pode ser necessário executar
chmod +x MyJarFile-1.0-jar-with-dependencies.jar
:)E finalmente
Por favor, veja
https://cwiki.apache.org/confluence/display/MAVEN/LifecyclePhaseNotFoundException
Vou postar esta solução em algumas outras páginas com um problema semelhante. Espero que eu possa salvar alguém de uma semana de frustração.
fonte