Diferença entre a compilação do escopo maven e fornecida para o empacotamento JAR

260

Qual é a diferença entre o escopo do maven compilee providedquando o artefato é construído como um JAR? Se fosse WAR, eu entenderia - o artefato seria incluído ou não no WEB-INF / lib. Mas no caso de um JAR, não importa - as dependências não estão incluídas. Eles precisam estar no caminho de classe quando seu escopo é compileou provided. Eu sei que as provideddependências não são transitivas - mas é apenas uma diferença?

emstol
fonte

Respostas:

289

Do Maven Doc :

  • compilar

    Este é o escopo padrão, usado se nenhum for especificado. Dependências de compilação estão disponíveis em todos os caminhos de classe de um projeto. Além disso, essas dependências são propagadas para projetos dependentes.

  • forneceu

    Isso é muito parecido com a compilação, mas indica que você espera que o JDK ou um contêiner forneça a dependência no tempo de execução. Por exemplo, ao criar um aplicativo da web para o Java Enterprise Edition, você definiria a dependência da API do Servlet e das APIs Java EE relacionadas ao escopo fornecido porque o contêiner da web fornece essas classes. Esse escopo está disponível apenas no caminho de classe de compilação e teste e não é transitivo.

Recapitular:

  • dependências não são transitivas (como você mencionou)
  • o escopo fornecido está disponível apenas no caminho de classe de compilação e teste, enquanto o escopo de compilação está disponível em todos os caminhos de classe.
  • dependências fornecidas não são empacotadas
Jacob
fonte
5
Sim eu conheço. Mas eu pondero sobre a diferença nos escopos no JAR packagingcontexto. Maven doc não menciona sobre isso. Eu uso o Maven por um tempo, mas eu já me perguntei sobre isso :) Portanto, parece que, no JAR packagingcontexto, não há diferença entre compilee provided(exceto a transição de dependência). Estou certo?
emstol
3
@ Jacob, o que se entende por "enquanto o escopo de compilação está disponível em todos os caminhos de classe ".
511 Geek
1
Eu acho que "NÃO transitivo" é o grande problema aqui. Como o inferno da dependência é algo que os desenvolvedores enfrentam com muita frequência, e o escopo fornecido evita que ele vá e mexer com outras versões é crucial.
Seetharamani Tmr
2
Eu acho que a diferença está na fase de embalagem. Com a compilação, ele incluirá o jar na guerra final ou no jar (como o jar executável de inicialização por mola), e desde que isso não ocorra. Como o jar fornecido pode ser fornecido pelo contêiner da web (como colocar na pasta ext lib), ele não está no pacote war se não for dependente de outros escopos, compilação e tempo de execução.
Addo Zhang
1
Voltando à sua pergunta original, você está certo de que, no caso do JAR, as dependências não são empacotadas dentro do próprio JAR. Porém, no maven, uma embalagem JAR significa que você deseja que ela seja usada como uma biblioteca. Assim que você o importar em algum outro projeto maven, as dependências transitivas serão trazidas se o escopo for compilee não serão se o escopo for provided.
LeoLuz
291

Compilar significa que você precisa do JAR para compilar e executar o aplicativo. Para um aplicativo da web, como exemplo, o JAR será colocado no diretório WEB-INF / lib.

Fornecido significa que você precisa do JAR para compilar, mas em tempo de execução já existe um JAR fornecido pelo ambiente, para que você não precise dele empacotado com seu aplicativo. Para um aplicativo da web, isso significa que o arquivo JAR não será colocado no diretório WEB-INF / lib.

Para um aplicativo Web, se o servidor de aplicativos já fornecer o JAR (ou sua funcionalidade), use "fornecido", caso contrário, use "compilar".

Aqui está a referência.

Owen Cao
fonte
11
Você não está respondendo à pergunta do OP? ' Qual a diferença no uso do escopo maven compilado e fornecido quando o artefato é construído como um JAR ? 'Observe que o autor afirma explicitamente que sabe a diferença ao se empacotar como guerra.
Alberto
posso usar o fornecido se estiver referenciando outro JAR implementado no mesmo servidor de aplicativos?
Samy Omar
1
Portanto, para ficar claro, uma dependência fornecida não é adicionada ao caminho de classe quando mvn exec:javaé executada, mas uma dependência compilada.
Jamie
Eu fiz esta pergunta - stackoverflow.com/questions/37360132/… O problema foi resolvido alterando o escopo de fornecido para compilar. Mas não vejo diferença entre jar compilado com escopo "fornecido" e jar compilado com escopo "compilar". Você poderia explicar o porquê?
Pavel_K
22

Se você planeja gerar um único arquivo JAR com todas as suas dependências (o típico xxxx-all.jar), o escopo fornecido é importante, porque as classes nesse escopo não serão compactadas no JAR resultante.

Veja maven-assembly-plugin para mais informações

jfcorugedo
fonte
7
dependência fornecida ==> a dependência NÃO será empacotada.
Gab是好人
3
A confusão do OP é claramente resolvida quando você empacota maven-assembly-plugin, interessante que as respostas mais votadas não a mencionam.
Henrique G. Abreu
Eu não entendo essa resposta. Parece mais um comentário.
reinierpost
11
  • compilar

Disponibilize no caminho da classe, não adicione essa dependência no jar final, se for jar normal; mas adicione este jar ao jar se o jar final for um jar único (por exemplo, jar executável)

  • forneceu

A dependência estará disponível no ambiente de tempo de execução; portanto, não inclua essa dependência em nenhum caso; mesmo que não em jar único (ou seja, jar executável etc)

Vijay
fonte
3

Para um arquivo jar, a diferença está no caminho de classe listado no arquivo MANIFEST.MF incluído no jar, se addClassPath estiver definido como true na configuração do maven-jar-plugin. dependências 'compilar' aparecerão no manifesto, dependências 'fornecidas' não.

Uma das minhas irritações é que essas duas palavras devem ter o mesmo tempo. Compilado e fornecido, ou compilado e fornecido.

Rick
fonte
0

Quando você define o escopo do maven como provided, significa que, quando o plug-in for executado, a versão das dependências reais usada dependerá da versão do Apache Maven que você instalou.

Vishwa Ratna
fonte
0

Se o arquivo jar for como o arquivo jar executável por boot de primavera, o escopo de todas as dependências deverá compileincluir todos os arquivos jar.

Porém, se o arquivo jar for usado em outros pacotes ou aplicativos, ele não precisará incluir todas as dependências no arquivo jar, porque esses pacotes ou aplicativos podem fornecer outras dependências.

Todos
fonte