Maven에서 Java 버전 지정-속성과 컴파일러 플러그인의 차이점


178

나는 maven에 익숙하지 않고 멀티 모듈 프로젝트를 실험하는 동안 부모 maven pom의 모든 자식 모듈에 대해 Java 버전을 어떻게 지정할 수 있는지 궁금해하기 시작했습니다. 오늘까지 나는 단지 사용했다 :

<properties>
    <java.version>1.8</java.version>
</properties>

그러나 연구 할 때 maven 컴파일러 플러그인에서 다음과 같이 Java 버전을 지정할 수도 있음을 발견했습니다.

<plugins>
    <plugin>    
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

그런 다음 이것을 플러그인 관리 태그로 감싸서 하위 폼을 사용할 수있게합니다. 첫 번째 질문은 속성과 maven 컴파일러 플러그인에서 Java 버전을 설정하는 것의 차이점무엇입니까?

나는 명확한 대답을 찾을 수 없었지만 연구 과정에서 다음과 같은 방법으로 Java 버전을 지정할 수 있음을 발견했습니다.

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

명시 적으로 선언하지 않아도 컴파일러 플러그인이 있음을 제안합니다. 로 mvn 패키지 출력 실행

maven-compiler-plugin:3.1:compile (default-compile) @ testproj ---

그리고 내가 선언하지 않은 다른 플러그인들. 그렇다면 플러그인이 기본이며 maven pom의 숨겨진 부분입니까? 속성과 maven 플러그인 구성 요소에서 소스 / 대상을 설정하는 데 차이점이 있습니까?

다른 질문은-어떤 방법을 사용해야합니까 (그리고 같지 않은 경우)? 멀티 모듈 프로젝트에 가장 적합한 것은 무엇이며 pom에 지정된 Java 버전이 JAVA_HOME에 지정된 버전과 다른 경우 어떻게됩니까?

답변:


289

JDK 버전을 지정하는 방법은 무엇입니까?

1) <java.version>Maven 문서에는 언급되어 있지 않습니다.
스프링 부트 특이성입니다.
소스와 대상 자바 버전을 같은 버전으로 설정하여 둘 다 java 1.8을 지정할 수 있습니다.

<properties>
     <java.version>1.8</java.version>
</properties>   

Spring Boot를 사용하는 경우 자유롭게 사용하십시오.

2) maven-compiler-plugin또는 maven.compiler.source/ maven.compiler.target속성을 사용하여 및를 지정 source하는 target것은 같습니다.

<plugins>
    <plugin>    
        <artifactId>maven-compiler-plugin</artifactId>
        <configuration>
            <source>1.8</source>
            <target>1.8</target>
        </configuration>
    </plugin>
</plugins>

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

받는있어서 동등 컴파일러 플러그인 메이븐 문서 사람 <source><target>속성 컴파일러 구성 요소를 사용 maven.compiler.source하고 maven.compiler.target그들이 정의되어 있으면.

출처

-sourceJava 컴파일러 의 인수
기본값은 1.6입니다.
사용자 속성은 다음과 같습니다 maven.compiler.source.

표적

-targetJava 컴파일러 의 인수
기본값은 1.6입니다.
사용자 속성은 다음과 같습니다 maven.compiler.target.

기본 값 소개 source하고 target, 참고 이후 3.8.0받는다는 컴파일러는 기본 값에서 변경 1.51.6 .

3) maven-compiler-plugin 3.6및 이후 버전은 새로운 방법을 제공합니다.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.8.0</version>
    <configuration>
        <release>9</release>
    </configuration>
</plugin>

당신은 또한 선언 할 수 있습니다 :

<properties>
    <maven.compiler.release>9</maven.compiler.release>
</properties>

그러나 현재 maven-compiler-plugin사용중인 기본 버전이 최근의 충분한 버전에 의존하지 않기 때문에 현재 작동 하지 않습니다.

Maven release인수는 다음을 전달합니다 release. 새로운 JVM 표준 옵션 Java 9에서 전달할 수 입니다.

특정 VM 버전에 대해 공개되고 지원되며 문서화 된 API에 대해 컴파일합니다.

이 방법은 source, targetbootstrapJVM 옵션에 동일한 버전을 지정하는 표준 방법을 제공합니다 .
를 지정하는 bootstrap것은 교차 컴파일에 대한 좋은 습관이며 교차 컴파일을 수행하지 않아도 손상되지 않습니다.


JDK 버전을 지정하는 가장 좋은 방법은 무엇입니까?

첫 번째 방법은<java.version> )은 Spring Boot를 사용하는 경우에만 허용됩니다.

Java 8 이하의 경우 :

다른 두 가지 방법 : maven.compiler.source/ maven.compiler.target속성 평가 또는 를 사용하여 maven-compiler-plugin, 둘 중 하나를 사용할 수 있습니다. 마지막으로 두 솔루션이 동일한 속성과 동일한 메커니즘, 즉 maven 코어 컴파일러 플러그인에 의존하기 때문에 사실에는 아무런 변화가 없습니다.

컴파일러 플러그인에서 Java 버전 이외의 다른 속성이나 동작을 지정할 필요가없는 경우이 방법을 사용하면보다 간결하므로이 방법을 사용하는 것이 좋습니다.

<properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

자바 9에서 :

그만큼 release인수 (세 번째 점)는 소스와 대상에 대해 동일한 버전을 사용하려는 경우 적극 고려하는 방법입니다.

JAVA_HOME의 JDK와 pom.xml에 지정된 버전간에 버전이 다른 경우 어떻게됩니까?

에서 참조한 JDK JAVA_HOME가 pom에 지정된 버전과 호환 되는 경우 문제가되지 않지만보다 나은 크로스 컴파일 호환성을 위해 bootstrapJVM 옵션을 경로 값으로 추가하는 것에 대해 생각 하십시오.rt.jartarget 버전 하십시오 .

고려해야 할 중요한 사항은 Maven 구성 의 sourcetarget버전이에서 참조하는 JDK 버전보다 우수하지 않아야한다는 것 JAVA_HOME입니다.
JDK의 이전 버전은 사양을 모르기 때문에 최신 버전으로 컴파일 할 수 없습니다.

사용 된 JDK에 따라 소스, 대상 및 릴리스 지원 버전에 대한 정보를 얻으려면 java 컴파일 (소스, 대상 및 릴리스 지원 버전)을 참조하십시오 .


JAVA_HOME이 참조하는 JDK의 경우를 처리하는 방법이 pom에 지정된 Java 대상 및 / 또는 소스 버전과 호환되지 않습니까?

예를 들어, JAVA_HOMEJDK 1.7을 참조하고 pom.xml의 컴파일러 구성에서 JDK 1.8을 소스 및 대상으로 지정하는 경우 설명 된대로 JDK 1.7이 .
그것의 관점에서 볼 때, 그것은 알려지지 않은 JDK 버전입니다.
이 경우 다음과 같은 방법으로 JDK를 지정하도록 Maven 컴파일러 플러그인을 구성해야합니다.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <compilerVersion>1.8</compilerVersion>      
        <fork>true</fork>
        <executable>D:\jdk1.8\bin\javac</executable>                
    </configuration>
</plugin>

maven compiler plugin 예제에 더 자세한 내용이있을 수 있습니다 .


요청하지는 않지만 소스를 지정하지만 대상을 지정하지 않은 경우 더 복잡 할 수 있습니다. 소스 버전에 따라 대상에서 다른 버전을 사용할 수 있습니다. 규칙은 구체적입니다. 크로스 컴파일 옵션 부분 에서 규칙을 읽을 수 있습니다 .


컴파일러 플러그인이 packagepom.xml에 지정되지 않은 경우에도 Maven 목표 실행시 출력에서 ​​추적되는 이유는 무엇 입니까?

Maven 목표에 필요한 모든 작업을 수행하기 위해 코드를 컴파일하고보다 일반적으로 수행하려면 Maven에 도구가 필요합니다. 그래서, 핵심 메이븐 플러그인을 사용 (당신에 의해 핵심 Maven 플러그인을 인식 그 groupId: org.apache.maven.plugins) 필요한 작업을 수행하는 : 컴파일러 플러그인을 컴파일 클래스, 테스트를 실행하기위한 테스트 플러그인 등을위한 ... 그래서 들어, 당신이없는 경우에도 이 플러그인을 선언하면 Maven 수명주기의 실행에 바인딩됩니다.
Maven 프로젝트의 루트 디렉토리에서 다음 명령을 실행할 수 있습니다.mvn help:effective-pom 하여 최종 pom을 효과적으로 사용할 수 있습니다. 사용 된 버전, 구성 및 수명주기의 각 단계에 대해 실행 된 목표와 함께 Maven의 플러그인 (pom.xml에 지정되었거나 지정되지 않음)과 같은 다른 정보를 볼 수 있습니다.

mvn help:effective-pom명령 의 출력 에서 <build><plugins>요소 에 이러한 핵심 플러그인이 선언되어 있음을 확인할 수 있습니다. 예를 들면 다음과 같습니다.

...
<plugin>
   <artifactId>maven-clean-plugin</artifactId>
   <version>2.5</version>
   <executions>
     <execution>
       <id>default-clean</id>
       <phase>clean</phase>
       <goals>
         <goal>clean</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
 <plugin>
   <artifactId>maven-resources-plugin</artifactId>
   <version>2.6</version>
   <executions>
     <execution>
       <id>default-testResources</id>
       <phase>process-test-resources</phase>
       <goals>
         <goal>testResources</goal>
       </goals>
     </execution>
     <execution>
       <id>default-resources</id>
       <phase>process-resources</phase>
       <goals>
         <goal>resources</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
 <plugin>
   <artifactId>maven-compiler-plugin</artifactId>
   <version>3.1</version>
   <executions>
     <execution>
       <id>default-compile</id>
       <phase>compile</phase>
       <goals>
         <goal>compile</goal>
       </goals>
     </execution>
     <execution>
       <id>default-testCompile</id>
       <phase>test-compile</phase>
       <goals>
         <goal>testCompile</goal>
       </goals>
     </execution>
   </executions>
 </plugin>
  ...

Maven 문서에 Maven lifeycle을 소개 하면 자세한 정보를 얻을 수 있습니다 .

그럼에도 불구하고 다른 값으로 기본값을 구성하려는 경우 (예를 들어, pom.xml에서 maven-compiler 플러그인을 선언하여 사용할 JDK 버전을 조정했을 때) 플러그인을 선언 할 수 있습니다. Maven 라이프 사이클에서 기본적으로 사용되지 않는 플러그인 실행을 추가하려고합니다.


광범위한 설명에 감사드립니다. 이제 훨씬 더 명확 해졌습니다. 또한 <java.version>에 대해-일부 코드 스 니펫에서 이것을 보았을 것입니다. 어쩌면 그것은 일부 사용자 정의 속성 일 것이고 Java 버전을 선언하는 방법이라고 잘못 가정했습니다 <maven.compiler.x>. 지금부터 속성에 충실 할 것 입니다.
Plebejusz

당신은 기쁨으로 환영합니다. :) 처음에는 그렇게 많이 개발하려는 의도는 아니었지만 시작했을 때 나는 멈출 수 없었습니다. 당신과 좋은 메이븐을 참조하십시오!
davidxxx

1
" JAVA_HOME의 JDK가 pom의 지정된 버전과 호환되는 경우 문제가되지 않습니다. "(필수) 사실이 아닙니다. 참조를 위해이 스택 오버 플로우 스레드를 확인하십시오.
A_Di-Matteo

2
@Robin A. Meade 의견에 감사드립니다. 스프링 부트를 사용하지만 몰랐습니다. 개인적으로 나는 그것을 사용할 무언가로 사용하거나 참조하기에 충분한 표준을 찾지 못했습니다. 스프링 부트는 매우 흥미로운 것들을 제공하지만 어떤 경우에는 그 기능이 매우 불분명하다. 소스와 대상 jdk를 모두 채우지 않도록 표준 maven 속성의 이름을 재정의하면 응용 프로그램에 대해 한 번만 수행되므로 실제로 나쁜 생각처럼 보입니다. 응용 프로그램에서 간단한 xml 줄을 절약하는 표준을 잃습니다. 우와! 무슨 아이디어 ...
davidxxx

1
@ MasterJoe2 10 버전의 공식 javac 문서 : docs.oracle.com/javase/10/tools/javac.htm#JSWOR627 에서 찾을 수 있습니다 . 답변이 너무
커짐

3

위의 솔루션 중 어느 것도 나를 위해 즉시 효과가 없었습니다. 그래서 나는 다음을 수행했다.

  1. 추가

    <properties> <maven.compiler.target>1.8</maven.compiler.target> <maven.compiler.source>1.8</maven.compiler.source> </properties>

    pom.xml에서

  2. 로 이동 Project Properties > Java Build Path한 다음을 가리키는 JRE 시스템 라이브러리를 제거했습니다 JRE1.5.

  3. 프로젝트를 강제 업데이트했습니다.


Java 10 이상에 어떤 버전을 지정합니까? 10입니까 아니면 1.10입니까?
MasterJoe2

Java 9 이상 버전의 @ MasterJoe2에서는 버전 번호를 그대로 (<version> 10 </ version>) 작성해야하며 아래 버전의 경우 버전 앞에 1을 추가해야합니다 (<version> 1.5 </ version>)
ikbel benab

0

대안을 고려하십시오.

<properties>
    <javac.src.version>1.8</javac.src.version>
    <javac.target.version>1.8</javac.target.version>
</properties>

그것은 같은 것이어야 maven.compiler.source/maven.compiler.target하지만 위의 해결책은 나를 위해 작동합니다. 그렇지 않으면 두 번째 것은 부모 사양을 얻습니다 (나는 .pom의 matrioska가 있습니다)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.