मावेन में जावा संस्करण निर्दिष्ट करना - गुणों और संकलक प्लगइन के बीच अंतर


178

मैं मावेन के साथ बहुत अनुभवी नहीं हूं और मल्टी-मॉड्यूल प्रोजेक्ट के साथ प्रयोग करते समय मैंने यह सोचना शुरू कर दिया कि मैं अपने सभी बच्चे मॉड्यूल के लिए जावा संस्करण को माता-पिता मावेन पोम में कैसे निर्दिष्ट कर सकता हूं। आज तक मैं सिर्फ इस्तेमाल कर रहा था:

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

लेकिन जब मैंने पाया कि आप मावेन कंपाइलर प्लगइन में जावा संस्करण को भी निर्दिष्ट कर सकते हैं, जैसे:

<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>

जो सुझाव है कि संकलक प्लगइन वहाँ है, भले ही मैं स्पष्ट रूप से यह घोषित न करें। रनिंग mvan पैकेज आउटपुट के साथ

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

और कुछ अन्य प्लगइन्स जिन्हें मैंने घोषित नहीं किया था। तो क्या वे प्लगइन्स डिफ़ॉल्ट, मावेन पोम के छिपे हुए भाग हैं? क्या गुणों में और मावेन प्लगइन कॉन्फ़िगरेशन तत्व में बीट्वेन सेटिंग सोर्स / टारगेट में कोई अंतर है?

कुछ अन्य प्रश्न हैं - किस तरीके का उपयोग किया जाना चाहिए (और जब वे बराबर नहीं हैं)? मल्टी-मॉड्यूल प्रोजेक्ट के लिए कौन सा सबसे अच्छा है और अगर जावा में निर्दिष्ट जावा संस्करण JAVA_HOME में बताए गए संस्करण से भिन्न है तो क्या होगा?

जवाबों:


289

JDK संस्करण कैसे निर्दिष्ट करें?

1) <java.version>मावेन प्रलेखन में संदर्भित नहीं है।
यह एक स्प्रिंग बूट विशिष्टता है।
यह स्रोत और लक्ष्य जावा संस्करण को एक ही संस्करण के साथ सेट करने की अनुमति देता है जैसे कि यह दोनों के लिए जावा 1.8 निर्दिष्ट करने के लिए है:

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

यदि आप स्प्रिंग बूट का उपयोग करते हैं तो इसका बेझिझक उपयोग करें।

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यदि वे परिभाषित हैं।

स्रोत

-sourceजावा के लिए तर्क।
डिफ़ॉल्ट मान है: 1.6
उपयोगकर्ता संपत्ति है: maven.compiler.source

लक्ष्य

-targetजावा के लिए तर्क।
डिफ़ॉल्ट मान है: 1.6
उपयोगकर्ता संपत्ति है: maven.compiler.target

के लिए डिफ़ॉल्ट मानों के बारे में sourceऔर target, ध्यान दें कि maven संकलक के बाद से 3.8.0, डिफ़ॉल्ट मानों से बदल गया 1.5है1.6

3) मावेन-कंपाइलर-प्लगइन 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आपके द्वारा उपयोग किए जाने वाले डिफ़ॉल्ट संस्करण के रूप में काम नहीं करेगा, हाल ही में पर्याप्त संस्करण पर भरोसा नहीं करता है।

मावेन releaseतर्क बताता है release: एक नया JVM मानक विकल्प जिसे हम जावा 9 से पास कर सकते हैं:

एक विशिष्ट वीएम संस्करण के लिए सार्वजनिक, समर्थित और प्रलेखित एपीआई के खिलाफ संकलन।

यह तरीका source, targetऔर bootstrapJVM विकल्पों के लिए समान संस्करण को निर्दिष्ट करने का एक मानक तरीका प्रदान करता है ।
ध्यान दें कि bootstrapक्रॉस संकलनों के लिए एक अच्छा अभ्यास निर्दिष्ट है और यदि आप क्रॉस संकलन नहीं करते हैं तो यह चोट नहीं पहुंचेगी।


JDK संस्करण को निर्दिष्ट करने का सबसे अच्छा तरीका कौन सा है?

पहले तरीके ( <java.version>) की अनुमति केवल तभी दी जाती है जब आप स्प्रिंग बूट का उपयोग करते हैं।

जावा 8 और उससे नीचे के लिए:

दो अन्य तरीकों के बारे में: maven.compiler.source/ maven.compiler.targetसंपत्तियों का मूल्य निर्धारण या इसका उपयोग करके maven-compiler-plugin, आप एक या दूसरे का उपयोग कर सकते हैं। यह तथ्यों में कुछ भी नहीं बदलता है क्योंकि आखिरकार दो समाधान एक ही गुण और एक ही तंत्र पर निर्भर करते हैं: मावेन कोर कंपाइलर प्लगइन।

ठीक है, अगर आपको संकलक प्लगइन में जावा संस्करणों की तुलना में अन्य गुणों या व्यवहार को निर्दिष्ट करने की आवश्यकता नहीं है, तो इस तरह से उपयोग करना अधिक समझ में आता है क्योंकि यह अधिक संक्षिप्त है:

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

जावा 9 से:

releaseतर्क (तीसरा बिंदु) एक तरह से दृढ़ता से विचार करने के लिए आप स्रोत और लक्ष्य के लिए एक ही संस्करण उपयोग करना चाहते हैं है।

यदि संस्करण JDA_HOME में JDK के बीच भिन्न होता है और pom.xml में कौन-सा निर्दिष्ट है?

यह एक समस्या नहीं है अगर जेडीके द्वारा संदर्भित JAVA_HOMEपॉम में निर्दिष्ट संस्करण के साथ संगत है लेकिन एक बेहतर क्रॉस-संकलन संगतता सुनिश्चित करने के लिए bootstrapजेवीएम विकल्प rt.jarको targetसंस्करण के मार्ग के मूल्य के साथ जोड़ने के बारे में सोचें ।

एक महत्वपूर्ण बात पर विचार करना है कि है sourceऔर targetMaven विन्यास में संस्करण के द्वारा संदर्भित JDK संस्करण के लिए बेहतर नहीं होना चाहिए JAVA_HOME
JDK का एक पुराना संस्करण अधिक हाल के संस्करण के साथ संकलित नहीं कर सकता है क्योंकि यह इसके विनिर्देश को नहीं जानता है।

स्रोत के बारे में जानकारी प्राप्त करने के लिए, उपयोग किए गए JDK के अनुसार समर्थित संस्करणों को लक्षित और जारी करें, कृपया जावा संकलन का उल्लेख करें : स्रोत, लक्ष्य और समर्थित संस्करण जारी करें


JAVA_HOME द्वारा संदर्भित JDK के मामले को कैसे हैंडल करें जो pom में निर्दिष्ट जावा लक्ष्य और / या स्रोत संस्करणों के साथ संगत नहीं है?

उदाहरण के लिए, यदि आपका JAVA_HOMEJDK 1.7 को संदर्भित करता है और आप JDK 1.8 को स्रोत के रूप में निर्दिष्ट करते हैं और अपने pom.xml के संकलक विन्यास में लक्ष्य करते हैं, तो यह एक समस्या होगी क्योंकि जैसा कि समझाया गया है, JDK 1.7 यह नहीं जानता है कि इसका अनुपालन कैसे करें ।
अपने दृष्टिकोण से, यह एक अज्ञात JDK संस्करण है क्योंकि यह इसके बाद जारी किया गया था।
इस स्थिति में, आपको JDK को इस तरह निर्दिष्ट करने के लिए मावेन कंपाइलर प्लगइन को कॉन्फ़िगर करना चाहिए:

<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 संकलक प्लगइन के साथ उदाहरणों में अधिक विवरण हो सकते हैं ।


यह पूछा नहीं जाता है, लेकिन ऐसे मामले जो अधिक जटिल हो सकते हैं, जब आप स्रोत निर्दिष्ट करते हैं, लेकिन लक्ष्य नहीं। यह स्रोत संस्करण के अनुसार लक्ष्य में एक भिन्न संस्करण का उपयोग कर सकता है। नियम विशेष हैं: आप उनके बारे में क्रॉस-संकलन विकल्प भाग में पढ़ सकते हैं ।


कंपाइलर आउटपुट को मावेन packageगोल के निष्पादन पर आउटपुट में क्यों ट्रेस किया जाता है, भले ही आप इसे pom.xml में निर्दिष्ट न करें?

मावेन गोल के लिए आवश्यक सभी कार्यों को करने के लिए अपने कोड और अधिक सामान्यतः संकलित करने के लिए, मावेन को उपकरण की आवश्यकता होती है। इसलिए, यह कोर Maven प्लगइन्स का उपयोग करता है (आपके द्वारा एक कोर Maven प्लगइन पहचान इसकी groupId: org.apache.maven.plugins) आवश्यक कार्य करने के लिए: संकलन कक्षाएं, परीक्षण क्रियान्वित करने के लिए परीक्षण प्लगइन, और इतने के लिए ... तो के लिए संकलक प्लगइन है, भले ही आप नहीं है इन प्लगइन्स को घोषित करें, वे मावेन जीवन चक्र के निष्पादन के लिए बाध्य हैं।
अपने मावेन प्रोजेक्ट के रूट डायर पर, आप कमांड चला सकते हैं: mvn help:effective-pomअंतिम पोम को प्रभावी ढंग से उपयोग करने के लिए। आप अन्य जानकारी, मावेन द्वारा संलग्न प्लगइन्स (आपके 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>
  ...

आप मावेन प्रलेखन में मावेन जीवनकाल की शुरूआत में इसके बारे में अधिक जानकारी रख सकते हैं ।

फिर भी, आप इन प्लगइन्स को घोषित कर सकते हैं जब आप उन्हें अन्य मानों के साथ डिफ़ॉल्ट मानों के रूप में कॉन्फ़िगर करना चाहते हैं (उदाहरण के लिए, आपने यह तब किया था जब आपने अपने pom.xml में मावेन-कंपाइलर प्लगइन को JDK संस्करण को समायोजित करने के लिए उपयोग करने के लिए घोषित किया था) और जब आप Maven जीवनचक्र में डिफ़ॉल्ट रूप से उपयोग नहीं किए गए कुछ प्लगइन जोड़ना चाहते हैं।


व्यापक स्पष्टीकरण के लिए धन्यवाद, अब यह मेरे लिए बहुत स्पष्ट है। <Java.version> के बारे में भी - मैंने इसे कुछ कोड स्निपेट में देखा है, हो सकता है कि यह कुछ कस्टम प्रॉपर्टी थी और मैंने गलत तरीके से मान लिया कि यह जावा संस्करण घोषित करने का तरीका है, <maven.compiler.x>अब से प्रॉपर्टी पर चिपक जाएगा ।
प्लेबिजुस्स

आपका स्वागत है, खुशी के साथ :) शुरुआत में, यह इतना विकसित करने का मेरा उद्देश्य नहीं था लेकिन जब मैंने शुरू किया, तो मैं रोक नहीं सका :) के लिए `<java.version>` यह बहुत संभावना है। आप और अच्छा मावेन देखें!
davidxxx

1
" यह कोई समस्या नहीं है अगर आपके JAVA_HOME का JDK पोम में निर्दिष्ट संस्करणों के साथ संगत है " यह (जरूरी नहीं) सच है, संदर्भ के लिए इस स्टैक ओवरफ्लो थ्रेड की जांच करें
A_Di-Matoo

2
@ रबिन ए मीडे ने प्रतिक्रिया के लिए धन्यवाद दिया। मैं स्प्रिंग बूट का उपयोग करता हूं, लेकिन मुझे यह पता नहीं था। व्यक्तिगत रूप से मुझे ऐसा करने के लिए पर्याप्त मानक नहीं मिला या उपयोग के रूप में संदर्भित किया गया। स्प्रिंग बूट कुछ बहुत ही दिलचस्प चीजें प्रदान करता है, लेकिन कुछ मामलों में इसकी विशेषताएं बहुत ही निराशाजनक हैं। स्रोत और लक्ष्य jdk दोनों को नहीं भरने के लिए एक मानक मावेन संपत्ति के नाम को ओवरराइड करना वास्तव में एक बुरा विचार के रूप में प्रकट होता है क्योंकि यह एक आवेदन के लिए एक ही समय में प्रदर्शन किया जाता है। आप अपने आवेदन में एक साधारण xml लाइन को अलग करने के लिए मानक खो देते हैं। वाह! क्या विचार है ...
davidxxx

1
@ MasterJoe2 आप इसे 10 संस्करण के आधिकारिक javac प्रलेखन में पाते हैं: docs.oracle.com/javase/10/tools/javac.htm#JSWOR627 । मैंने उस उत्तर को दो भाग में विभाजित किया था जो बहुत बड़ा हो गया है, आप उस पर भी नज़र डाल सकते हैं: stackoverflow.com/questions/51692748/…
davidxxx

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, फिर जेआरई सिस्टम लाइब्रेरी को हटा दिया जो इंगित कर रहा था JRE1.5

  3. फोर्स ने प्रोजेक्ट को अपडेट किया।


आप जावा 10 और इसके बाद के संस्करण के लिए कौन सा संस्करण निर्दिष्ट करते हैं? क्या यह 10 या 1.10 है?
मास्टरजेओ

@ Java 9 और इसके बाद के संस्करणों से MasterJoe2 आपको संस्करण संख्या लिखने की आवश्यकता है जैसा कि यह है (<संस्करण> 10 </ संस्करण>), और नीचे दिए गए संस्करणों के लिए, आपको संस्करण के सामने 1. जोड़ना होगा (<संस्करण> 1.5 </ संस्करण>)
ikbel बेनाब

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 का एक matososka है)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.