2009-08-05 14 views
47

मेरे पास मेवेन द्वारा निर्मित कई परियोजनाएं हैं, और मैं उनमें से कुछ सामान्य गुणों को साझा करना चाहता हूं - वसंत संस्करण, mysql ड्राइवर संस्करण, svn base url, आदि - इसलिए मैं उन्हें एक बार अपडेट कर सकता हूं और यह सभी परियोजनाओं पर दिखाई देगा।कई मैवेन परियोजनाओं के बीच आम गुणों को कैसे साझा करें?

मैंने सभी गुणों के साथ एक सुपर पोम रखने का विचार किया, लेकिन यदि मैं किसी एक समस्या को बदलता हूं तो मुझे या तो इसके संस्करण को बढ़ाने की आवश्यकता है (और सभी पोम्स को इससे प्राप्त करने के लिए) या इसे सभी से हटाने के लिए डेवलपर्स मशीनें जो मैं नहीं करना चाहता हूं।

इन पैरामीटर को बाहरी रूप से पोम में निर्दिष्ट कर सकते हैं? मैं अभी भी एक पैरेंट पोम में बाहरी स्थान परिभाषा चाहता हूं।

+1

जाओ सुपर पोम मार्ग है, और जब कभी आप सुपर पोम संस्करण संख्या को अद्यतन, निष्पादित करें: 'mvn एन संस्करणों: अद्यतन-बाल-modules' http://stackoverflow.com/questions/30571/# 1172805 – Tim

+0

@ टिम समस्या यह है कि मेरे पास कई सुपर पोम्स (सामान्य परिभाषाएं -> वसंत परियोजनाएं -> वेबपैप्स/सेवाएं -> वास्तविक मॉड्यूल का पदानुक्रम है। संस्करण प्लगइन AFAIK यह कैस्केड अपडेट नहीं करता है। –

उत्तर

13

ध्यान दें कि मेरे पास मूल विचार कुछ ऐसा है जो मैं कर रहा हूं, लेकिन मुझे एक बेहतर विचार मिल गया है जिसे मैंने नीचे सूचीबद्ध किया है। नए विचार काम नहीं करते हैं, तो मैं दोनों विचारों को पूर्णता के लिए यहां रखना चाहता था।


मुझे लगता है कि आप इस समस्या को माता-पिता पोम का उपयोग कर हल कर सकते हैं, लेकिन आप एक Maven भंडार और एक सीआई निर्माण उपकरण की आवश्यकता है।

मुझे कई परियोजनाएं मिली हैं जो सभी माता-पिता पीओएम से मूल गुण प्राप्त करते हैं। हम जावा 1.5 का उपयोग करते हैं, ताकि निर्माण संपत्ति वहां स्थापित हो। सब कुछ यूटीएफ -8 है। मैं जिन रिपोर्टों को चलाने की इच्छा रखता हूं, सोनार सेटअप इत्यादि माता-पिता पीओएम के अंदर है।

मान लीजिए कि आपकी परियोजना संस्करण नियंत्रण में है और आपके पास सीआई उपकरण है, जब आप चेक इन करते हैं, तो आपका सीआई उपकरण पीओएम प्रोजेक्ट में बना सकता है और मैवेन रिपोज़ में स्नैपशॉट को तैनात कर सकता है। यदि आपकी परियोजनाएं मूल पीओएम के स्नैपशॉट संस्करण को इंगित करती हैं, तो वे यह सत्यापित करने के लिए भंडार की जांच करेंगे कि उनके पास नवीनतम संस्करण है ... यदि वे नवीनतम संस्करण डाउनलोड नहीं करते हैं। इसलिए यदि आप माता-पिता को अपडेट करते हैं, तो अन्य सभी परियोजनाएं अपडेट हो जाएंगी।

चाल, मुझे लगता है कि एक स्नैपशॉट के साथ रिलीज हो रहा है। मैं कहूंगा कि आपकी रिलीज आपके बदलावों से बहुत कम बार आ रही हैं। तो आप अपने पीओएम की रिहाई करते हैं, फिर अपने पीओएम अपडेट करें जो उनसे प्राप्त होते हैं और उन्हें संस्करण नियंत्रण में जांचते हैं। देवताओं को पता है कि उन्हें एक अद्यतन करने की आवश्यकता है और वहां से जाना है।

आप नए पीओएम को भंडार में मजबूर करने के लिए बस वहां ट्रिगर कर सकते हैं और फिर सभी देवताओं ने निर्माण पर स्वचालित रूप से परिवर्तनों को उठाया है।


मैंने नवीनतम/रिलीज कीवर्ड विचार हटा दिया है क्योंकि वे मूल पीओएम के लिए काम नहीं करते हैं। वे केवल निर्भरताओं या प्लगइन्स के लिए काम करते हैं। समस्या क्षेत्र DefaultMavenProjectBuilder में है। अनिवार्य रूप से यह निर्धारित करने में परेशानी है कि कौन सा भंडार माता-पिता को यह निर्धारित करने के लिए है कि नवीनतम या रिलीज़ संस्करण क्या है। निश्चित नहीं है कि यह निर्भरता या प्लगइन्स के लिए अलग क्यों है।


ऐसा लगता है जैसे माता-पिता पीओएम में प्रत्येक परिवर्तन पर पीओएम अपडेट करने से कम दर्दनाक होगा।

22

Properties Maven plugin का उपयोग करने के लिए आप क्या कर सकते हैं। यह आपको अपनी प्रॉपर्टी को बाहरी फाइल में परिभाषित करने देगा, और प्लगइन इस फाइल को पढ़ेगा।

इस कॉन्फ़िगरेशन के साथ

:

<build> 
    <plugins> 
     <plugin> 
      <groupId>org.codehaus.mojo</groupId> 
      <artifactId>properties-maven-plugin</artifactId> 
      <version>1.0-alpha-1</version> 
      <executions> 
       <execution> 
        <phase>initialize</phase> 
        <goals> 
         <goal>read-project-properties</goal> 
        </goals> 
        <configuration> 
         <files> 
          <file>my-file.properties</file> 
         </files> 
        </configuration> 
       </execution> 
      </executions> 
     </plugin> 
    </plugins> 
</build> 

और अगर आपके पास, में अपने गुण निम्नलिखित लाइनों दायर:

spring-version=1.0 
mysql-version=4.0.0 

तो यह एक ही बात के रूप में यदि आप ने लिखा अपने pom.xml में है, , निम्नलिखित पंक्तियां:

<properties> 
    <spring-version>1.0</spring-version> 
    <mysql-version>4.0.0</mysql-version> 
</properties> 

इस प्लगइन का उपयोग करके, आपके पास कई लाभ होंगे:

  • सेट आसानी से गुण
  • की एक लंबी सूची माता पिता pom.xml को संशोधित किए बिना इन गुणों के मूल्यों को संशोधित करें।
+0

इस प्लगइन को कितना परिपक्व है एक अल्फा -1 संस्करण है? –

+1

इस बग के अनुसार यह अभी भी मेरे लिए उपयोग योग्य नहीं है, क्योंकि मैं अभिभावक पोम में मंदी करना चाहता हूं: http://jira.codehaus.org/browse/MOJO-1303 –

+0

क्या आप प्रदान कर सकते हैं एक पूर्ण 'pom.com', जहां आप 'वसंत-संस्करण' का उल्लेख करते हैं? http://stackoverflow.com/qu में चर्चाओं के मुताबिक estions/849389/कैसे-पढ़ने-एक-बाहरी-गुण-फ़ाइल-इन-मेवेन संभव नहीं है निर्भरता के संस्करण को परिभाषित करना। सही? –

7

मुझे लगता है कि गुण-मेवेन-प्लगइन लंबी अवधि का सही दृष्टिकोण है, लेकिन जैसा कि आपने उस उत्तर का जवाब दिया है, यह गुणों को विरासत में रहने की अनुमति नहीं देता है। मेवेन-साझा-io में कुछ सुविधाएं हैं जो आपको प्रोजेक्ट क्लासपाथ पर संसाधन खोजने की अनुमति देती हैं। मैंने नीचे कुछ कोड शामिल किया है जो प्लगइन की निर्भरताओं में गुण फ़ाइलों को खोजने के लिए गुण प्लगइन को बढ़ाता है।

कॉन्फ़िगरेशन एक प्रॉपर्टी फ़ाइल का पथ घोषित करता है, क्योंकि डिस्क्रिप्टर प्रोजेक्ट प्लगइन कॉन्फ़िगरेशन पर घोषित किया जाता है, यह क्लासपाथ रिसोर्सलोकेटरस्ट्रेटी के लिए सुलभ है। कॉन्फ़िगरेशन को मूल परियोजना में परिभाषित किया जा सकता है, और सभी बाल परियोजनाओं द्वारा विरासत में प्राप्त किया जाएगा (यदि आप ऐसा करते हैं तो किसी भी फाइल को घोषित करने से बचें क्योंकि उन्हें नहीं मिलेगा, केवल फ़ाइलपैथ प्रॉपर्टी सेट करें)।

नीचे दी गई कॉन्फ़िगरेशन मानता है कि नाम.seller.rich:test-properties-descriptor.0.0.1 नामक एक और जार प्रोजेक्ट है जिसमें जार में पैक की गई बाहरी.प्रोपर्टीज नामक एक फ़ाइल है (यानी इसे src/मुख्य/संसाधन)।

<plugin> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>properties-ext-maven-plugin</artifactId> 
    <version>0.0.1</version> 
    <executions> 
    <execution> 
     <id>read-properties</id> 
     <phase>initialize</phase> 
     <goals> 
     <goal>read-project-properties</goal> 
     </goals> 
    </execution> 
    </executions>        
    <configuration> 
    <filePaths> 
     <filePath>external.properties</filePath> 
    </filePaths> 
    </configuration> 
    <dependencies> 
    <!-- declare any jars that host the required properties files here --> 
    <dependency> 
     <groupId>name.seller.rich</groupId> 
     <artifactId>test-properties-descriptor</artifactId> 
     <version>0.0.1</version> 
    </dependency> 
    </dependencies> 
</plugin> 

प्लगइन परियोजना के लिए पोम इस तरह दिखता है:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 
    <modelVersion>4.0.0</modelVersion> 
    <groupId>org.codehaus.mojo</groupId> 
    <artifactId>properties-ext-maven-plugin</artifactId> 
    <packaging>maven-plugin</packaging> 
    <version>0.0.1</version> 
    <dependencies> 
    <dependency> 
     <groupId>org.codehaus.mojo</groupId> 
     <artifactId>properties-maven-plugin</artifactId> 
     <version>1.0-alpha-1</version> 
    </dependency> 
    <dependency> 
     <groupId>org.apache.maven.shared</groupId> 
     <artifactId>maven-shared-io</artifactId> 
     <version>1.1</version> 
    </dependency> 
    </dependencies> 
</project> 

मोजो गुण प्लगइन के ReadPropertiesMojo एक अतिरिक्त "filepaths" संपत्ति के साथ, की एक प्रति आप रिश्तेदार पथ को परिभाषित करने की अनुमति है क्लासपाथ में बाहरी गुण फ़ाइल के लिए, यह फ़ाइलों की संपत्ति को वैकल्पिक बनाता है, और फ़ाइलों को ढूंढने के लिए readPropertyFiles() और getLocation() विधियों को जोड़ता है और किसी भी फ़ाइल को मर्ज करने से पहले फ़ाइलों को सरणी में डाल देता है। मैंने उन्हें स्पष्ट करने के लिए अपने परिवर्तनों पर टिप्पणी की है।

package org.codehaus.mojo.xml; 

/* 
* Licensed to the Apache Software Foundation (ASF) under one 
* or more contributor license agreements. See the NOTICE file 
* distributed with this work for additional information 
* regarding copyright ownership. The ASF licenses this file 
* to you under the Apache License, Version 2.0 (the 
* "License"); you may not use this file except in compliance 
* with the License. You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, 
* software distributed under the License is distributed on an 
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 
* KIND, either express or implied. See the License for the 
* specific language governing permissions and limitations 
* under the License. 
*/ 

import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.Enumeration; 
import java.util.List; 
import java.util.Properties; 

import org.apache.maven.plugin.AbstractMojo; 
import org.apache.maven.plugin.MojoExecutionException; 
import org.apache.maven.project.MavenProject; 
import org.apache.maven.shared.io.location.ClasspathResourceLocatorStrategy; 
import org.apache.maven.shared.io.location.FileLocatorStrategy; 
import org.apache.maven.shared.io.location.Location; 
import org.apache.maven.shared.io.location.Locator; 
import org.apache.maven.shared.io.location.LocatorStrategy; 
import org.apache.maven.shared.io.location.URLLocatorStrategy; 
import org.codehaus.plexus.util.cli.CommandLineUtils; 

/** 
* The read-project-properties goal reads property files and stores the 
* properties as project properties. It serves as an alternate to specifying 
* properties in pom.xml. 
* 
* @author <a href="mailto:[email protected]">Zarar Siddiqi</a> 
* @author <a href="mailto:[email protected]">Krystian Nowak</a> 
* @version $Id: ReadPropertiesMojo.java 8861 2009-01-21 15:35:38Z pgier $ 
* @goal read-project-properties 
*/ 
public class ReadPropertiesMojo extends AbstractMojo { 
    /** 
    * @parameter default-value="${project}" 
    * @required 
    * @readonly 
    */ 
    private MavenProject project; 

    /** 
    * The properties files that will be used when reading properties. 
    * RS: made optional to avoid issue for inherited plugins 
    * @parameter 
    */ 
    private File[] files; 

    //Begin: RS addition 
    /** 
    * Optional paths to properties files to be used. 
    * 
    * @parameter 
    */ 
    private String[] filePaths; 
    //End: RS addition 

    /** 
    * If the plugin should be quiet if any of the files was not found 
    * 
    * @parameter default-value="false" 
    */ 
    private boolean quiet; 

    public void execute() throws MojoExecutionException { 
     //Begin: RS addition 
     readPropertyFiles(); 
     //End: RS addition 

     Properties projectProperties = new Properties(); 
     for (int i = 0; i < files.length; i++) { 
      File file = files[i]; 

      if (file.exists()) { 
       try { 
        getLog().debug("Loading property file: " + file); 

        FileInputStream stream = new FileInputStream(file); 
        projectProperties = project.getProperties(); 

        try { 
         projectProperties.load(stream); 
        } finally { 
         if (stream != null) { 
          stream.close(); 
         } 
        } 
       } catch (IOException e) { 
        throw new MojoExecutionException(
          "Error reading properties file " 
            + file.getAbsolutePath(), e); 
       } 
      } else { 
       if (quiet) { 
        getLog().warn(
          "Ignoring missing properties file: " 
            + file.getAbsolutePath()); 
       } else { 
        throw new MojoExecutionException(
          "Properties file not found: " 
            + file.getAbsolutePath()); 
       } 
      } 
     } 

     boolean useEnvVariables = false; 
     for (Enumeration n = projectProperties.propertyNames(); n 
       .hasMoreElements();) { 
      String k = (String) n.nextElement(); 
      String p = (String) projectProperties.get(k); 
      if (p.indexOf("${env.") != -1) { 
       useEnvVariables = true; 
       break; 
      } 
     } 
     Properties environment = null; 
     if (useEnvVariables) { 
      try { 
       environment = CommandLineUtils.getSystemEnvVars(); 
      } catch (IOException e) { 
       throw new MojoExecutionException(
         "Error getting system envorinment variables: ", e); 
      } 
     } 
     for (Enumeration n = projectProperties.propertyNames(); n 
       .hasMoreElements();) { 
      String k = (String) n.nextElement(); 
      projectProperties.setProperty(k, getPropertyValue(k, 
        projectProperties, environment)); 
     } 
    } 

    //Begin: RS addition 
    /** 
    * Obtain the file from the local project or the classpath 
    * 
    * @throws MojoExecutionException 
    */ 
    private void readPropertyFiles() throws MojoExecutionException { 
     if (filePaths != null && filePaths.length > 0) { 
      File[] allFiles; 

      int offset = 0; 
      if (files != null && files.length != 0) { 
       allFiles = new File[files.length + filePaths.length]; 
       System.arraycopy(files, 0, allFiles, 0, files.length); 
       offset = files.length; 
      } else { 
       allFiles = new File[filePaths.length]; 
      } 

      for (int i = 0; i < filePaths.length; i++) { 
       Location location = getLocation(filePaths[i], project); 

       try { 
        allFiles[offset + i] = location.getFile(); 
       } catch (IOException e) { 
        throw new MojoExecutionException(
          "unable to open properties file", e); 
       } 
      } 

      // replace the original array with the merged results 
      files = allFiles; 
     } else if (files == null || files.length == 0) { 
      throw new MojoExecutionException(
        "no files or filePaths defined, one or both must be specified"); 
     } 
    } 
    //End: RS addition 

    /** 
    * Retrieves a property value, replacing values like ${token} using the 
    * Properties to look them up. Shamelessly adapted from: 
    * http://maven.apache. 
    * org/plugins/maven-war-plugin/xref/org/apache/maven/plugin 
    * /war/PropertyUtils.html 
    * 
    * It will leave unresolved properties alone, trying for System properties, 
    * and environment variables and implements reparsing (in the case that the 
    * value of a property contains a key), and will not loop endlessly on a 
    * pair like test = ${test} 
    * 
    * @param k 
    *   property key 
    * @param p 
    *   project properties 
    * @param environment 
    *   environment variables 
    * @return resolved property value 
    */ 
    private String getPropertyValue(String k, Properties p, 
      Properties environment) { 
     String v = p.getProperty(k); 
     String ret = ""; 
     int idx, idx2; 

     while ((idx = v.indexOf("${")) >= 0) { 
      // append prefix to result 
      ret += v.substring(0, idx); 

      // strip prefix from original 
      v = v.substring(idx + 2); 

      idx2 = v.indexOf("}"); 

      // if no matching } then bail 
      if (idx2 < 0) { 
       break; 
      } 

      // strip out the key and resolve it 
      // resolve the key/value for the ${statement} 
      String nk = v.substring(0, idx2); 
      v = v.substring(idx2 + 1); 
      String nv = p.getProperty(nk); 

      // try global environment 
      if (nv == null) { 
       nv = System.getProperty(nk); 
      } 

      // try environment variable 
      if (nv == null && nk.startsWith("env.") && environment != null) { 
       nv = environment.getProperty(nk.substring(4)); 
      } 

      // if the key cannot be resolved, 
      // leave it alone (and don't parse again) 
      // else prefix the original string with the 
      // resolved property (so it can be parsed further) 
      // taking recursion into account. 
      if (nv == null || nv.equals(nk)) { 
       ret += "${" + nk + "}"; 
      } else { 
       v = nv + v; 
      } 
     } 
     return ret + v; 
    } 

    //Begin: RS addition 
    /** 
    * Use various strategies to discover the file. 
    */ 
    public Location getLocation(String path, MavenProject project) { 
     LocatorStrategy classpathStrategy = new ClasspathResourceLocatorStrategy(); 

     List strategies = new ArrayList(); 
     strategies.add(classpathStrategy); 
     strategies.add(new FileLocatorStrategy()); 
     strategies.add(new URLLocatorStrategy()); 

     List refStrategies = new ArrayList(); 
     refStrategies.add(classpathStrategy); 

     Locator locator = new Locator(); 

     locator.setStrategies(strategies); 

     Location location = locator.resolve(path); 
     return location; 
    } 
    //End: RS addition 
} 
+5

क्या आपने कभी इसे पैच के रूप में प्रॉपर्टी मेवेन प्लगइन में सबमिट किया था? क्योंकि मेरे पास एक ही आवश्यकता है जहां मेरे पास एक जार के भीतर एक प्रॉपर्टी फ़ाइल है जिसे मैं एक xml फ़ाइल के साथ फ़िल्टर करने के लिए मेवेन-संसाधन-प्लगइन का उपयोग करना चाहता हूं। –

+0

यह एक अच्छा जवाब है, लेकिन मुझे कुछ परेशानी हो रही है, मेरे पास एक अभिभावक पोम है जहां मैंने इसके ठीक बाद फ़ाइल से संस्करणों में पढ़ा है और आवश्यक सेट विधियों को कॉल किया है, गुण सेट हो जाते हैं लेकिन जब निर्भरता को हल करने का समय आता है तो वे उपयोग न करें ... क्या मुझे इसे फिर से इंटरपोल करने के लिए मजबूर करने की आवश्यकता है, इसे 'project.getModel()। setProperties (propectProperties)' के साथ आज़माएं, लेकिन कोई भाग्य नहीं है कि मैं वास्तव में यह काम करना चाहता हूं: '( – sloven

संबंधित मुद्दे