Maven 부모 pom 대 모듈 pom


284

다중 프로젝트 빌드에서 부모 폼을 구조화하는 몇 가지 방법이있는 것 같습니다. 각각의 장점 / 단점이 무엇인지에 대해 누군가가 생각하는지 궁금합니다.

부모 폼폼을 갖는 가장 간단한 방법은 프로젝트의 루트에 넣는 것입니다.

myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

여기서 pom.xml은 상위 프로젝트이며 -core -api 및 -app 모듈을 설명합니다.

다음 방법은 부모를 다음과 같이 자체 하위 디렉토리로 분리하는 것입니다.

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/

부모 pom에 여전히 모듈이 포함되어 있지만 상대적입니다 (예 : ../myproject-core)

마지막으로 모듈 정의와 부모가 다음과 같이 분리되는 옵션이 있습니다.

myproject/
  mypoject-parent/
    pom.xml
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml

상위 pom에 "공유"구성 (dependencyManagement, 속성 등)이 있고 myproject / pom.xml에 모듈 목록이있는 경우.

의도는 대규모 빌드로 확장 가능해야하므로 많은 프로젝트 및 아티팩트로 확장 가능해야합니다.

몇 가지 보너스 질문 :

  • 소스 제어, 배포 디렉토리, 공통 플러그인 등 다양한 공유 구성을 정의하는 가장 좋은 곳은 어디입니까 (부모를 가정하고 있지만 종종 물 렸으며 각 프로젝트에서 끝나지 않았습니다. 일반적인 것).
  • maven-release plugin, hudson 및 nexus는 다중 프로젝트를 설정하는 방법을 어떻게 처리합니까?

편집 : 각 하위 프로젝트에는 자체 pom.xml이 있으며 간결하게 유지하기 위해 생략했습니다.


각 모듈에 자체 폼폼이 있습니까? 내 프로젝트에는 부모 폼폼이 있지만 모듈에는 폼폼도 있습니다. (아마도
네가

아, 그래요. 편집하고 업데이트하겠습니다. 각 서브 모듈에는 자체 pom이 있습니다.
Jamie McCrindle

3
업데이트와 마찬가지로 두 번째 옵션의 이점은 하위 모듈이 Eclipse에서 별도의 프로젝트 인 경우 첫 번째 및 세 번째 예제의 루트 pom.xml을 포함하기 어려운 Eclipse에서 관리하기 쉽다는 것입니다.
Jamie McCrindle

답변:


166

내 생각에,이 질문에 대답하려면 프로젝트 수명주기와 버전 관리 측면에서 생각해야합니다. 다시 말해서, 부모 pom은 자체 수명주기를 가지고 있습니까? 즉 다른 모듈과 별도로 분리 될 수 있습니까?

대답이 ' '인 경우 (질문이나 의견에 언급 된 대부분의 프로젝트의 경우) 부모 pom은 VCS와 Maven 관점에서 자신의 모듈을 필요로하므로 결국 끝납니다. VCS 수준에서 다음과 같이하십시오.

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
`-- projectA
    |-- branches
    |-- tags
    `-- trunk
        |-- module1
        |   `-- pom.xml
        |-- moduleN
        |   `-- pom.xml
        `-- pom.xml

이것은 체크 아웃을 약간 아프게 만들고이를 처리하는 일반적인 방법은 사용하는 것 svn:externals입니다. 예를 들어, trunks디렉토리를 추가하십시오 .

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks

다음과 같은 외부 정의를 사용하십시오.

parent-pom http://host/svn/parent-pom/trunk
projectA http://host/svn/projectA/trunk

체크 아웃 trunks하면 다음과 같은 로컬 구조 (패턴 # 2)가 발생합니다.

root/
  parent-pom/
    pom.xml
  projectA/

선택적으로, 심지어을 추가 할 수 있습니다 pom.xml에서 trunks디렉토리 :

root
|-- parent-pom
|   |-- branches
|   |-- tags
|   `-- trunk
|       `-- pom.xml
|-- projectA
|   |-- branches
|   |-- tags
|   `-- trunk
|       |-- module1
|       |   `-- pom.xml
|       |-- moduleN
|       |   `-- pom.xml
|       `-- pom.xml
`-- trunks
    `-- pom.xml

이것은 pom.xml일종의 "가짜"폼폼입니다.이 파일은 절대 릴리스되지 않습니다.이 파일은 릴리스되지 않았기 때문에 실제 버전을 포함하지 않으며 모듈 목록 만 포함합니다. 이 파일을 사용하면 체크 아웃하면 다음 구조 (패턴 # 3)가됩니다.

root/
  parent-pom/
    pom.xml
  projectA/
  pom.xml

이 "해킹"을 통해 결제 후 루트에서 원자로 빌드를 시작하고 훨씬 편리하게 만들 수 있습니다. 실제로 이것은 대규모 빌드를 위해 maven 프로젝트와 VCS 저장소를 설정하는 방법입니다 . 작동하고 확장 가능하며 필요한 모든 유연성을 제공합니다.

대답이 아니오 (초기 질문으로 돌아 가면)라면 패턴 # 1로 살 수 있다고 생각합니다 (가장 간단한 일을 할 수 있음).

이제 보너스 질문에 대해 :

  • 소스 제어, 배포 디렉토리, 공통 플러그인 등 다양한 공유 구성을 정의하는 가장 좋은 곳은 어디입니까 (부모를 가정하고 있지만 종종 물 렸으며 각 프로젝트에서 끝나지 않았습니다. 일반적인 것).

솔직히, 나는 여기서 일반적인 대답을하지 않는 방법을 모른다. 어쨌든 자식 폼은 항상 상속 된 설정을 무시할 수 있습니다.

  • maven-release plugin, hudson 및 nexus는 다중 프로젝트를 설정하는 방법을 어떻게 처리합니까?

내가 사용하는 설정은 언급 할 필요가 없습니다.

실제로 maven-release-plugin이 패턴 # 1을 처리하는 방법이 궁금합니다 (특히 <parent>릴리스시 SNAPSHOT 종속성을 가질 수 없기 때문에 섹션 을 다루는 경우 ). 이것은 닭고기 나 계란 문제처럼 들리지만 그것이 효과가 있고 테스트하기에는 너무 게으른 지 기억이 나지 않습니다.


그것이 어떻게 확장되는지 볼 수 있듯이 아주 좋습니다. svn : externals는 성가신 것에 대한 나의 관심에 답합니다.
Jamie McCrindle

@jamie Glad 당신이 도움이된다고 생각합니다.
Pascal Thivent

1
"해킹"을 작동시키는 방법에 대해 자세히 설명해 주시겠습니까? 트렁크 프로젝트를 가지고 있으며 "리액터 빌드 시작"으로 -pl 옵션을 대상으로 할 것으로 예상하지만이 옵션은 루트 레벨의 빌드에서 전달되지 않기 때문에 구조에서 릴리스를 수행 할 때 문제가됩니다. release-Plugin의 <arguments /> 옵션에 넣을 수 있습니다. 따라서 release : perform은 루트 레벨 폼폼에서 작동하려고하기 때문에 실패합니다.
Jan

svn : externals 핵은 내가 오랫동안 본 가장 유용한 svn 핵입니다. 동일한 저장소 내에 프로젝트 별 분기가있는 프로젝트에 매우 유용합니다.
omerkudat

1
안녕하세요 파스칼, 모듈 섹션에 언급 된 프로젝트가 <parent>로 부모 -pom을 사용하지 않고 다른 프로젝트 -parent-pom-pom을 사용하는 경우 버전 #을 어떻게 처리합니까? 이러한 프로젝트의 이슈 (해당 프로젝트의 <부모> 섹션에있는 이슈의 버전 번호 또는 이러한 프로젝트를 모듈로 나열하는 프로젝트의 버전 번호)에 대해 어떤 버전을 얻을 수 있습니까? stackoverflow.com/questions/25918593/…
AKS

34

내 경험과 Maven 모범 사례에는 두 가지 종류의 "부모 폼폼"이 있습니다.

  • "회사"상위 pom-이 pom에는 모든 pom을 상속하고 복사 할 필요가없는 회사 특정 정보 및 구성이 포함되어 있습니다. 이러한 정보는 다음과 같습니다.

    • 리포지토리
    • 배포 관리 섹션
    • 공통 플러그인 구성 (예 : maven-compiler-plugin 소스 및 대상 버전)
    • 조직, 개발자 등

    모든 회사 폼이 상속되므로이 부모 폼폼을 준비하는 것은주의해서 수행해야합니다. 따라서이 폼은 성숙하고 안정적이어야합니다.

  • 부모 pom의 두 번째 종류는 다중 모듈 부모입니다. 첫 번째 솔루션을 선호합니다-이것은 다중 모듈 프로젝트의 기본 Maven 규칙이며 VCS 코드 구조를 나타냅니다.

의도는 대규모 빌드로 확장 가능해야하므로 많은 프로젝트 및 아티팩트로 확장 가능해야합니다.

Mutliprojects에는 나무 구조가 있으므로 부모 수준의 한 수준으로 화살을 arrow 지 않아도됩니다. 귀하의 요구에 적합한 프로젝트 구조를 찾으십시오-고전적인 exmample은 mutimodule 프로젝트를 무섭게 만드는 방법입니다

distibution/
documentation/
myproject/
  myproject-core/
  myproject-api/
  myproject-app/
  pom.xml
pom.xml

몇 가지 보너스 질문 :

  • 소스 제어, 배포 디렉토리, 공통 플러그인 등 다양한 공유 구성을 정의하는 가장 좋은 곳은 어디입니까 (부모를 가정하고 있지만 종종 물 렸으며 각 프로젝트에서 끝나지 않았습니다. 일반적인 것).

이 구성은 "회사"상위 pom과 프로젝트 상위 pom으로 현명하게 분할해야합니다. 프로젝트와 관련된 모든 것은 "회사"상위로 이동하고 현재 프로젝트와 관련된 것은 프로젝트로 이동합니다.

  • maven-release plugin, hudson 및 nexus는 다중 프로젝트를 설정하는 방법을 어떻게 처리합니까?

회사 상위 폼폼을 먼저 해제해야합니다. 다중 프로젝트의 경우 표준 규칙이 적용됩니다. CI 서버는 프로젝트를 올바르게 구축하기 위해 모든 것을 알아야합니다.


1
따라서 두 가지 유형의 상위 프로젝트 / 폼이 있습니다. <modules> 선언이없는 것. 이것은 상속에 사용되는 것입니다. 그리고 <multimodule> 선언을 가진 부모 프로젝트. 이것은 서브 모듈이 상속하지 않는 것입니다. 홀드 프로젝트의 빌드를 관리하는 것입니다. 내가 맞아?
lisak

22
  1. 독립적 인 부모는 연결되지 않은 구성 요소간에 구성 및 옵션을 공유하는 가장 좋은 방법입니다. Apache에는 법적 고지 사항 및 일반적인 패키징 옵션을 공유하기위한 부모 pom 프로젝트가 있습니다.

  2. javadoc 집계 또는 릴리스 패키징과 같이 최상위 레벨 프로젝트에 실제 작업이있는 경우 해당 작업을 수행하는 데 필요한 설정과 상위를 통해 공유하려는 설정간에 충돌이 발생합니다. 부모 전용 프로젝트는이를 피합니다.

  3. 일반적인 패턴 (현재 # 1 무시)은 코드가있는 프로젝트에서 상위 프로젝트를 상위 프로젝트로 사용하고 최상위 레벨을 상위로 사용하는 것입니다. 이를 통해 핵심 내용을 모두 공유 할 수 있지만 # 2에 설명 된 문제를 피할 수 있습니다.

  4. 상위 구조가 디렉토리 구조와 동일하지 않으면 사이트 플러그인이 매우 혼란스러워집니다. 집계 사이트를 구축하려면이 문제를 해결하기 위해 약간의 조정을 수행해야합니다.

  5. Apache CXF 는 # 2의 패턴입니다.


2
나는 ibilio를 살펴 보았고 많은 프로젝트들이 "독립적 인"부모 pom을 선호하는 것으로 보인다. 최대 절전 모드, ActiveMQ, Jetty, XStream 등은 사실상의 메커니즘임을 시사합니다.
Jamie McCrindle

2
독립 부모의 또 다른 단점은 maven release plugin이 부모가 릴리스 전에 버전에 고정되기를 원한다는 것 같습니다. 부모가 너무 많이 바뀌지 않아야하기 때문에 아마도 큰 문제는 아닙니다.
Jamie McCrindle

9

세 번째 접근 방식에는 하나의 작은 캐치가 있습니다. 집계 POM (myproject / pom.xml)에는 일반적으로 상위가 없으므로 구성을 공유하지 않습니다. 즉, 모든 집계 POM에는 기본 리포지토리 만 있습니다.

Central의 플러그인 만 사용하는 경우에는 문제가되지 않지만 내부 저장소에서 plugin : goal 형식을 사용하여 플러그인을 실행하면 실패합니다. 예를 들어, goal 제공 foo-maven-plugin의 groupId를 가질 수 있습니다 . 과 같은 명령을 사용하여 프로젝트 루트에서 실행하려고 하면 집계 모듈에서 실행되지 않습니다 ( 호환성 참조 ).org.examplegenerate-foomvn org.example:foo-maven-plugin:generate-foo

몇 가지 솔루션이 가능합니다.

  1. Maven Central에 플러그인을 배포하십시오 (항상 가능한 것은 아님).
  2. 모든 집계 POM에 저장소 섹션을 지정하십시오 ( DRY 원칙 위반 ).
  3. 이 내부 저장소를 settings.xml (~ / .m2 / settings.xml의 로컬 설정 또는 /conf/settings.xml의 전역 설정)에 구성하십시오. settings.xml이 없으면 빌드가 실패합니다 (회사 외부에서 절대로 구축해서는 안되는 대규모 사내 프로젝트의 경우 괜찮을 수 있음).
  4. 집계 POM에서 저장소 설정이있는 상위를 사용하십시오 (상위 POM이 너무 많을 수 있음).
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.