2012-10-04 17 views
8

मैं एक जावा webapp परियोजना है कि मैं ग्रहण में विकसित (अधिक सटीक MyEclipse 10) है और का उपयोग कर निर्माण Maven 3.मैवेन बिल्ड के दौरान WAR फ़ाइल में फ़ाइलों को ओवरराइट कैसे करें?

मैं निम्नलिखित लेआउट (केवल मेरी समस्या के लिए प्रासंगिक फ़ाइलों सहित है:

project root 
|-- src 
| |-- main 
| | |-- java 
| | |-- resources 
| | | |-- log4j.xml 
| | | +-- struts.properties 
| | |-- webapp 
| | | |-- META-INF 
| | | | +--context.xml 
| | |-- config 
| | | |-- test 
| | | | |--log4j.xml 
| | | | |--struts.properties 
| | | | +--context.xml 
| | | +-- prod 
| | | | |--log4j.xml 
| | | | |--struts.properties 
| | | | +--context.xml 
| +--test 
+--pom.xml 

जैसा कि आप देख सकते हैं, मैंने कई कॉन्फ़िगरेशन फाइलें शामिल की हैं। जो परियोजना प्रक्षेपण के भीतर उनके उचित स्थान पर हैं, यानी src/main/resources और src/main/webapp के अंदर वे हैं जिन्हें मैं नियमित रूप से उपयोग करता हूं जब मैं MyEclipse में काम करता हूं। मैं MyEclipse कनेक्टर का उपयोग कर सकता हूं मेरे देव मशीन पर टॉमकैट उदाहरण जैसे एक तैनाती को स्वचालित रूप से अपडेट करने के लिए। मैं बस "रन सर्वर" पर क्लिक करता हूं और मैं कर सकता हूं बग। वास्तव में इस संदर्भ में मेवेन का उपयोग करने की आवश्यकता नहीं है।

फिर, जब मैं परीक्षण या उत्पादन जैसे किसी अन्य वातावरण के लिए रिलीज बनाना चाहता हूं, तो मैं mvn -P test clean install चलाता हूं और यह एक अच्छा युद्ध बनाता है।

मेरा लक्ष्य अंतिम WAR के अंदर कॉन्फ़िगरेशन फ़ाइलों को src/config/{environment}/ में प्रतिस्थापित करना है।

मैं अपने pom.xml में प्रोफाइल की स्थापना की है:

<profiles> 
    <profile> 
     <id>test</id> 
     <properties> 
      <environment>test</environment> 
     </properties> 
    </profile> 

    <profile> 
     <id>prod</id> 
     <properties> 
      <environment>prod</environment> 
     </properties> 
    </profile> 
</profiles> 

फिर, मैं युद्ध के अंदर सही स्थान (या अस्थायी फ़ोल्डर के लिए (environment चर का उपयोग कर) निर्दिष्ट प्रोफ़ाइल से इन संसाधनों को कॉपी करने की कोशिश है कि एक युद्ध में ज़िप किया गया हो जाएगा):

<webResources> 
    <resource> 
     <directory>/src/main/config/${environment}</directory> 
     <targetPath>META-INF/</targetPath> 
     <includes> 
      <include>context.xml</include> 
     </includes> 
    </resource> 
    <resource> 
     <directory>src/main/config/${environment}</directory> 
     <targetPath>WEB-INF/classes/</targetPath> 
     <includes> 
      <include> 
       struts.properties 
      </include> 
      <include> 
       log4j.xml 
      </include> 
     </includes> 
    </resource> 
</webResources> 

अब इस काम करने के लिए, सिवाय इसके कि "मानक" संसाधनों इस के बाद निर्देशिका को कॉपी कर रहे हैं लगता है, इसलिए वे इन फ़ाइलों को अधिलेखित। तो मैं हमेशा उदा। कहते हैं से बजाय एक के src/main/resources से log4j.xmlsrc/main/configuration/prod/

Maven उत्पादन से निकालें:

[INFO] Processing war project 
[INFO] Copying webapp webResources [D:\workspace\MyProject/src/main/config/prod] to [D:\workspaces\SITEL\Webfauna\target\Webfauna] 
[INFO] Copying webapp webResources [D:\workspace\MyProject\src/main/config/prod] to [D:\workspaces\SITEL\Webfauna\target\Webfauna] 
[INFO] Copying webapp resources [D:\workspace\MyProject\src\main\webapp] 

आप अंतिम पंक्ति पर देख सकते हैं, src/main/webapp से सामान के बाद की नकल की है, इस प्रकार अपने कस्टम फ़ाइलों को अधिलेखित: (

मेरा प्रश्न: कैसे Maven "सक्रिय प्रोफ़ाइल से" फ़ाइलों का उपयोग करने के लिए और किसी तरह "प्राकृतिक" फाइल के ऊपर लिख

उत्तर

9

दूसरा Q/A given by user944849 में बताया के रूप में, सबसे सरल समाधान को फिल्टर करने की मूल फ़ाइलें, जिससे उनका के फ़ोल्डर से फ़ाइलों से बदला जा सकता है किया गया था।

मानक संसाधनों के लिए तो मैं जोड़ लिया है छानने:

<resources> 
     <resource> 
      <directory>src/main/resources</directory> 
      <excludes> 
       <!-- Exclude those since they are copied from the profile folder for the build --> 
       <exclude>log4j.xml</exclude> 
       <exclude>struts.properties</exclude> 
      </excludes> 
      <filtering>false</filtering> 
     </resource> 
    </resources> 

और वेब संसाधनों की:

<warSourceExcludes>**/context.xml</warSourceExcludes> 

तो अब 3 फ़ाइलें युद्ध फ़ोल्डर में कॉपी नहीं किए जाते। अगले चरण (वेब ​​स्रोत) में उन्हें सक्रिय प्रोफ़ाइल के फ़ोल्डर से कॉपी किया गया है।

मैंने सामान्य मानों वाली 3 फाइलों वाला एक डिफ़ॉल्ट फ़ोल्डर भी जोड़ा। इस डिफ़ॉल्ट फ़ोल्डर की फ़ाइलों की भी प्रतिलिपि बनाई गई है, लेकिन प्रोफ़ाइल के फ़ोल्डर के बाद ही। चूंकि संसाधनों को अधिलेखित नहीं किया जाता है, इसलिए वे केवल तभी कॉपी किए जाएंगे जब वे पहले से मौजूद न हों। यह उपयोगी है यदि आप प्रोफाइल सक्रिय किए बिना बनाते हैं, या यदि आप समझदार डिफ़ॉल्ट मान परिभाषित कर सकते हैं, तो प्रत्येक प्रोफ़ाइल को फ़ाइल को दोहराने की आवश्यकता नहीं है यदि यह समान है। config फ़ोल्डर की

संरचना:

-- config 
    |-- test 
    | |--log4j.xml 
    | | |--struts.properties 
    | | +--context.xml 
    | +-- prod 
    | | |--log4j.xml 
    | | +--context.xml 
    | +-- default 
    |  |--log4j.xml 
    |  |--struts.properties 
    |  +--context.xml 
... 

और मेरे pom.xml की webResources अनुभाग:

<webResources> 
    <!-- Resources from the activated profile folder --> 
    <resource> 
     <directory>/src/main/config/${environment}</directory> 
     <targetPath>META-INF/</targetPath> 
     <includes> 
      <include>context.xml</include> 
     </includes> 
    </resource> 
    <resource> 
     <directory>src/main/config/${environment}</directory> 
     <targetPath>WEB-INF/classes/</targetPath> 
     <includes> 
      <include> 
       struts.properties 
      </include> 
      <include> 
       log4j.xml 
      </include> 
     </includes> 
    </resource> 
    <!-- Default resources in case some file was not defined in the profile folder --> 
    <!-- Files are not overwritten so default files will be copied only if it does not exist already --> 
    <resource> 
     <directory>/src/main/config/default</directory> 
     <targetPath>META-INF/</targetPath> 
     <includes> 
      <include>context.xml</include> 
     </includes> 
    </resource> 
    <resource> 
     <directory>src/main/config/default</directory> 
     <targetPath>WEB-INF/classes/</targetPath> 
     <includes> 
      <include> 
       struts.properties 
      </include> 
      <include> 
       log4j.xml 
      </include> 
     </includes> 
    </resource> 
</webResources> 
+0

जानकारी का शानदार टुकड़ा। मैं सटीक समाधान की तलाश में था और इसे मिला। बहुत बहुत धन्यवाद। –

1

मैं आपको लगता है मजबूर करने के लिए युद्ध फाइलों को ओवरले करने की जरूरत है। या तो जार की बजाय टाइप युद्ध के हर प्रोफाइल में निर्भरता पैदा करना, जो आपकी वर्तमान युद्ध फ़ाइल में फ़ाइलों को ओवरले करेगा।

एक और संभावना मेवेन-युद्ध-प्लगइन के overlay configuration हो सकती है।

इसलिए प्रोफ़ाइल उन फ़ाइलों को सक्रिय करेगी जिन्हें आप वर्तमान में कॉपी करना चाहते हैं। प्लगइन साइट पर quite some documentation के साथ-साथ कुछ उदाहरण

आशा है कि काम करता है!

+0

लेकिन मेरी कस्टम कॉन्फ़िगरेशन फ़ाइलें बाहरी युद्ध का हिस्सा नहीं हैं, इसलिए मुझे यकीन नहीं है कि मैं उन्हें ओवरले के रूप में कैसे लागू कर सकता हूं ... विश्वास नहीं! –

+0

मुझे लगता है कि यदि आप मेवेन-वॉर-प्लगइन और ओवरले का उपयोग कर रहे हैं तो आपको बाहरी युद्ध फ़ाइल का उपयोग करने की आवश्यकता नहीं है। आईडी/artifactId/groupId पैरामीटर वैकल्पिक प्रतीत होते हैं, इसलिए आपको पर्यावरण कॉन्फ़िगरेशन को एक अलग मॉड्यूल में रखने की आवश्यकता नहीं है। – wemu

+0

युद्ध-प्लगइन पैकेज चरण में चल रहा है: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference जबकि संसाधन प्लगइन प्रक्रिया-संसाधनों में पहले चलाता है। मुझे नहीं लगता कि रास्ता युद्ध-प्लगइन को चालित करने के लिए काम करेगा। – wemu

1

इनमें से किसी भी प्रश्न/उत्तर पर एक नज़र डालें। कोई आपके लिए काम कर सकता है।

Run an ant task in maven build phase before war is packaged?

Files got overwritten in maven project when building a war

+0

प्रश्न 1: यदि संभव हो तो मैं देशी मेवेन पसंद करूंगा ... –

+2

प्रश्न 2: यहां कुछ पर। मैं 'पैकेजिंग एक्सक्लूस' का उपयोग करने की कोशिश कर रहा था लेकिन यह काम नहीं किया। ऐसा लगता है कि 'warSourceExcludes' चाल चल सकता है। –

1

एक और प्रयास :)

मैं चारों ओर ओवरले के साथ खेला है पैरामीटर। मुझे लगता है कि वेबपैप फ़ोल्डर के अंदर एक और युद्ध फ़ाइल में आपके पास वेबपैप फ़ोल्डर के भीतर फ़ाइलों को प्रतिस्थापित करता है। तो यह आपके सेटअप के लिए सही बात नहीं है।

फिर भी जैसा कि ऊपर उल्लेख webResource पैरामीटर ऐसा कर सकते हैं:

<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/xsd/maven-4.0.0.xsd"> 
<modelVersion>4.0.0</modelVersion> 

<groupId>org.mimacom.maven.examples</groupId> 
<artifactId>mimacom-war-overlays</artifactId> 
<version>1.0.0-SNAPSHOT</version> 
<packaging>war</packaging> 

<name>${project.artifactId}</name> 

<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 
    <project.build.compiler.version>1.6</project.build.compiler.version> 
    <junit.version>4.9</junit.version> 
</properties> 

<build> 
    <pluginManagement> 
     <plugins> 
      <plugin> 
       <groupId>org.apache.maven.plugins</groupId> 
       <artifactId>maven-compiler-plugin</artifactId> 
       <version>2.5.1</version> 
       <configuration> 
        <source>${project.build.compiler.version}</source> 
        <target>${project.build.compiler.version}</target> 
        <encoding>${project.build.sourceEncoding}</encoding> 
       </configuration> 
      </plugin> 
     </plugins> 
    </pluginManagement> 

    <plugins> 
     <plugin> 
      <groupId>org.apache.maven.plugins</groupId> 
      <artifactId>maven-war-plugin</artifactId> 
      <version>2.3</version> 
     </plugin> 
    </plugins> 
</build> 

<dependencies> 
    <dependency> 
     <groupId>junit</groupId> 
     <artifactId>junit</artifactId> 
     <version>${junit.version}</version> 
    </dependency> 
</dependencies> 

<profiles> 
    <profile> 
     <id>prod</id> 
     <build> 
      <plugins> 
       <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-war-plugin</artifactId> 
        <version>2.3</version> 
        <configuration> 
         <webResources> 
          <resource> 
           <directory>src/main/config/prod</directory> 
          </resource> 
         </webResources> 
         <!--<includes>--> 
          <!--<include>${basedir}/environments/overlay-1/css/styles.css</include>--> 
         <!--</includes>--> 
         <!--<overlays>--> 
          <!--<overlay>--> 
           <!--<includes>--> 
            <!--../environments/overlay-1/css/**--> 
           <!--</includes>--> 
          <!--</overlay>--> 
         <!--</overlays>--> 
        </configuration> 
       </plugin> 
      </plugins> 
     </build> 
    </profile> 
    <profile> 
     <id>test</id> 
     <build> 
      <plugins> 
       <plugin> 
        <groupId>org.apache.maven.plugins</groupId> 
        <artifactId>maven-war-plugin</artifactId> 
        <version>2.3</version> 
        <configuration> 
         <webResources> 
          <resource> 
           <directory>src/main/config/test</directory> 
          </resource> 
         </webResources> 
        </configuration> 
       </plugin> 
      </plugins> 
     </build> 
    </profile> 

</profiles> 

सक्रिय प्रोफाइल युद्ध फाइल करने के लिए अतिरिक्त फ़ोल्डर जोड़ना होगा। तो यह चाल करना चाहिए!

1

मुझे लगता है कि आप एक ही संसाधन का उपयोग करेंगे लेकिन प्रत्येक प्रोफ़ाइल (परीक्षण और प्रोड) में विभिन्न कॉन्फ़िगरेशन के साथ।

तो, मैं सुझाव है कि आप इस तरह के एक विन्यास का उपयोग करें:

<profiles> 
<profile> 
    <id>test</id> 
    <activation> 
     <activeByDefault>true</activeByDefault> 
     <property> 
      <name>env</name> 
      <name>test</name> 
     </property> 
    </activation> 
    <build> 
     <filters> 
      <filter>test.properties</filter> 
     </filters> 
    </build> 
</profile> 

<profile> 
    <id>prod</id> 
    <activation> 
     <property> 
      <name>env</name> 
      <value>prod</value> 
     </property> 
    </activation> 
    <build> 
     <filters> 
      <filter>prod.properties</filter> 
     </filters> 
    </build> 
</profile> 
</profiles> 

इस परिदृश्य में, मैं दो प्रोफाइल है, हर एक को "env" पैरामीटर का उपयोग कर सक्रिय है। प्रत्येक प्रोफ़ाइल में आपके संसाधनों को फ़िल्टर करने के लिए एक फ़ाइल है, अपनी log4j.xml, struts.properties, context.xml फ़ाइलों को src/main/संसाधनों में डालें और प्रत्येक प्रोफ़ाइल में सही कॉन्फ़िगरेशन का उपयोग करने के लिए चर का उपयोग करें।

उम्मीद है कि मदद करता है।

0

ऊपर दिए गए समाधानों का एक सरल संस्करण यहां है जो केवल pom.xml में डाले गए एक साधारण स्निपेट पर निर्भर करता है।

बिल्ड के साथ डिफ़ॉल्ट (स्थानीय कार्य केंद्र) webapp:

mvn war:exploded 

की तरह लक्ष्य वेब-INF/कक्षाएं निर्देशिका के लिए संसाधनों-prod एक वातावरण-विशिष्ट निर्देशिका से फ़ाइलों को कॉपी करने के लिए एक वातावरण कमांड लाइन पैरामीटर जोड़ें:

mvn war:exploded -Denvironment=prod 

pom.xml की परियोजना तत्व के अंदर इस जोड़ें:

<!-- this profile will allow files in environment-specific folders like resources-prod or resources-test 
    to be added to the resulting war's classpath under WEB-INF/classes 
    to activate the profile, simply add '-Denvironment=prod' to your maven build command 
    this also works fine with war:inplace and war:exploded 
--> 
<profile> 
    <id>environment-specific</id> 
    <activation> 
     <property> 
      <name>environment</name> 
     </property> 
    </activation> 
    <build> 
    <plugins> 
     <plugin> 
     <groupId>org.apache.maven.plugins</groupId> 
     <artifactId>maven-war-plugin</artifactId> 
     <version>2.4</version> 
     <configuration> 
      <webResources> 
       <!-- note the order of the following resource elements are important. 
        if there are duplicate files, the first file copied will win 
       --> 
       <resource> 
        <!-- this is relative to the pom.xml directory -->       
        <directory>resources-${environment}</directory> 
        <!-- override default destination at root of war --> 
        <targetPath>WEB-INF/classes</targetPath> 
       </resource> 
       <resource> 
        <directory>src/main/resources</directory> 
        <targetPath>WEB-INF/classes</targetPath> 
       </resource> 
      </webResources> 
     </configuration> 
     </plugin>    
    </plugins> 
    </build> 
</profile> 

अधिक जानकारी और link to working example