Diferenças entre dependencyManagement e dependencies no Maven

Qual é a diferença entre dependencyManagement e dependencies ? Eu vi os documentos no site do Apache Maven. Parece que uma dependência definida sob o dependencyManagement pode ser usada em seus módulos filhos sem especificar a versão.

Por exemplo:

Um projeto pai (Pro-par) define uma dependência sob o dependencyManagement :

    junit junit 3.8    

Então no filho do Pro-par, eu posso usar o junit:

    junit junit   

No entanto, gostaria de saber se é necessário definir junit no pom pai? Por que não defini-lo diretamente no módulo necessário?

    O Dependency Management permite consolidar e centralizar o gerenciamento de versões de dependência sem adicionar dependencies herdadas por todas as crianças. Isso é especialmente útil quando você tem um conjunto de projetos (ou seja, mais de um) que herda um pai comum.

    Outro caso de uso extremamente importante do dependencyManagement é o controle de versões de artefatos usados ​​em dependencies transitivas. Isso é difícil de explicar sem um exemplo. Felizmente, isso é ilustrado na documentação.

    Estou elegantemente atrasado para essa questão, mas acho que vale a pena uma resposta mais clara do que a aceita (o que é correto, mas não enfatiza a parte realmente importante, da qual você precisa se dedicar).

    No POM pai, a principal diferença entre e é esta:

    Artefatos especificados na seção SEMPRE serão incluídos como uma dependência do (s) módulo (s) filho (s).

    Os artefatos especificados na seção só serão incluídos no módulo filho se também forem especificados na seção do próprio módulo filho. Por que é bom você perguntar? porque você especifica a versão e / ou escopo no pai, e você pode deixá-los fora quando especificar as dependencies no POM filho. Isso pode ajudá-lo a usar versões unificadas para dependencies de módulos filhos, sem especificar a versão em cada módulo filho.

    É como você disse; dependencyManagement é usado para puxar todas as informações de dependência em um arquivo POM comum, simplificando as referências no arquivo POM filho.

    Torna-se útil quando você tem vários atributos que não deseja redigitar em vários projetos filhos.

    Finalmente, dependencyManagement pode ser usado para definir uma versão padrão de um artefato para uso em vários projetos.

    A documentação no site Maven é horrível. O que o dependencyManagement faz é simplesmente mover suas definições de dependência (versão, exclusões, etc) para o pom pai, então nos poms filhos você só precisa colocar o groupId e o artifactId. É isso (exceto para pais pomcha e afins, mas isso não é realmente complicado – dependencyManagement ganha sobre dependencies no nível pai – mas se tem uma pergunta sobre isso ou importa, a documentação do Maven é um pouco melhor).

    Depois de ler todos os ‘a’, ‘b’, ‘c’ lixo no site Maven e ficar confuso, eu reescrevi o exemplo deles. Portanto, se você tivesse dois projetos (proj1 e proj2) que compartilham uma dependência comum (betaShared), você poderia mover essa dependência para o pom pai. Enquanto você está nisso, você também pode mover quaisquer outras dependencies (alpha e charlie), mas somente se isso fizer sentido para o seu projeto. Então, para a situação descrita nas frases anteriores, aqui está a solução com dependencyManagement na pom pai:

           alpha alpha 1.0   zebra zebra     charlie  charlie 1.0 war runtime    betaShared betaShared 1.0 bar runtime         alpha alpha    betaShared betaShared bar         charlie charlie war    betaShared betaShared bar     

    Ainda há uma coisa que não está suficientemente destacada, na minha opinião, e isso é inheritance indesejada .

    Aqui está um exemplo incremental:

    Eu declaro em meu parent pom:

       com.google.guava guava 19.0   

    estrondo! Eu tenho isso nos meus módulos Child A , Child B e Child C :

    • Implicidade herdada por poms infantis
    • Um único lugar para gerenciar
    • Não há necessidade de redeclarar nada em poms infantis
    • Eu ainda posso redelcare e replace a version 18.0 em um Child B se eu quiser.

    Mas e se eu acabar não precisando de goiaba no Child C e nem nos futuros módulos Child D e Child E ?

    Eles ainda herdarão e isso é indesejado! Isso é como o cheiro do código Java God Object, onde você herda alguns bits úteis de uma class e uma tonelada de coisas indesejadas também.

    É aqui que entra em jogo. Quando você adiciona isso ao seu pai, todos os seus módulos filhos PARE de vê-lo . E assim você é forçado a entrar em cada módulo individual que precisa e declará-lo novamente ( Child A e Child B , sem a versão).

    E, obviamente, você não faz isso para Child C e, portanto, seu módulo permanece enxuto.

    Se a dependência foi definida no elemento dependencyManagement do pom de nível superior, o projeto filho não precisou listar explicitamente a versão da dependência. se o projeto filho definisse uma versão, ela replaceia a versão listada na seção dependencyManagement do POM de nível superior. Ou seja, a versão dependencyManagement é usada apenas quando o filho não declara uma versão diretamente.

    Existem algumas respostas que descrevem as diferenças entre as e com o maven.

    No entanto, alguns pontos elaborados abaixo de forma concisa:

    1. permite consolidar todas as dependencies (usadas no nível pom infantil) usadas em diferentes módulos – clareza , gerenciamento de versão de dependência central
    2. permite facilmente atualizar / rebaixar as dependencies com base na necessidade; em outro cenário, isso precisa ser exercido em cada nível de pom da criança – consistência
    3. dependencies fornecidas na tag são sempre importadas, enquanto as dependencies fornecidas no na pom pai serão importadas somente se o child pom tiver a respectiva input na sua tag .

    No POM pai, a principal diferença entre e é esta:

    Artefatos especificados na seção SEMPRE serão incluídos como uma dependência do (s) módulo (s) filho (s).

    Os artefatos especificados na seção só serão incluídos no módulo filho se também forem especificados na seção do próprio módulo filho. Por que é bom você perguntar? porque você especifica a versão e / ou escopo no pai, e você pode deixá-los fora quando especificar as dependencies no POM filho. Isso pode ajudá-lo a usar versões unificadas para dependencies de módulos filhos, sem especificar a versão em cada módulo filho.

    No Eclipse, há mais um recurso no dependencyManagement . Quando as dependencies são usadas sem elas, as dependencies não encontradas são observadas no arquivo pom. Se dependencyManagement for usado, as dependencies não resolvidas permanecerão despercebidas no arquivo pom e os erros aparecerão apenas nos arquivos java. (importações e tal …)