2012-10-04 9 views
8

Ich habe ein Java-Webapp Projekt, das ich in Eclipse entwickeln (genauer MyEclipse 10) und bauen mit Maven 3.Wie überschreiben Dateien in der WAR-Datei während Maven Build?

Ich habe folgendes Layout (einschließlich nur die relevanten Dateien zu meinem Problem:

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 

Wie Sie sehen können, habe ich eine Reihe von Konfigurationsdateien hinzugefügt, von denen ich an der richtigen Stelle innerhalb des Projekts struture bin, dh innerhalb src/main/resources und src/main/webapp. Ich kann MyEclipse-Konnektoren verwenden, die ich routinemäßig verwende um zB eine Tomcat-Instanz auf meinem Dev-Rechner automatisch zu aktualisieren, klicke ich einfach auf "run server" und ich kann de Fehler. In diesem Zusammenhang muss Maven überhaupt nicht verwendet werden.

Wenn ich dann ein Release für eine andere Umgebung wie Test oder Produktion erstellen möchte, starte ich mvn -P test clean install und es baut eine schöne WAR.

Mein Ziel ist es, die Konfigurationsdateien in der endgültigen WAR durch diejenigen in src/config/{environment}/ zu ersetzen.

Ich habe eingestellt Profile in meine pom.xml:

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

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

Dann versuche ich, diese Ressourcen aus dem angegebenen Profil zu kopieren (die environment Variable) an die richtige Stelle im Innern des IST (oder der temporäre Ordner, wird in einen Krieg gezippt):

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

Nun scheint diese Ausnahme zu arbeiten, dass die „Standard“ Ressourcen nach diesem in das Verzeichnis kopiert werden, so dass sie überschreiben diese Dateien. So komme ich immer mit z. die log4j.xml von src/main/resources statt der von etwa src/main/configuration/prod/

Auszug aus dem Maven-Ausgang:

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

Wie Sie nach dem Einschalten der letzten Zeile, Sachen von src/main/webapp kopiert werden sehen können, so meine benutzerdefinierten Dateien überschrieben werden: (

Meine Frage: Wie Maven zu zwingen, die Dateien zu verwenden „aus dem aktivierten Profil“ und ERSETZEN irgendwie die „natürlichen“ Dateien

Antwort

9

Wie in der zweiten Q/A given by user944849 zeigte, war die einfachste Lösung, um die ursprünglichen Dateien zu filtern, so dass sie durch die Dateien aus dem Profil des Ordners ersetzt werden kann.

So habe ich hinzugefügt Filterung Standard Ressourcen:

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

Und zu den Web-Ressourcen:

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

So, jetzt die 3-Dateien werden nicht in den Krieg Ordner kopiert. Im nächsten Schritt (webResources) werden sie aus dem Ordner des aktiven Profils kopiert.

Ich habe auch einen Standardordner hinzugefügt, der die 3 Dateien mit gemeinsamen Werten enthält. Die Dateien aus diesem Standardordner werden ebenfalls kopiert, aber nur nach den Ordnern des Profils. Da die Ressourcen nicht überschrieben werden, werden sie nur kopiert, wenn sie nicht bereits vorhanden sind. Dies ist nützlich, wenn Sie ohne aktiviertes Profil erstellen oder wenn Sie sinnvolle Standardwerte definieren können, muss nicht jedes Profil die Datei replizieren, wenn sie identisch ist.

Struktur des Konfigurationsordner:

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

Und der webResources Abschnitt meines pom.xml:

<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

Brilliantes Stück Information. Ich suchte nach der genauen Lösung und bekam es. Danke vielmals. –

1

ich glaube, Sie? müssen die Kriegsdateien überlagern. Entweder wird in jedem Profil vom Typ WAR anstelle von jar eine Abhängigkeit erstellt, die die Dateien in Ihrer aktuellen WAR-Datei überlagert.

Eine andere Möglichkeit könnte die overlay configuration des maven-war-plugins sein.

also das Profil würde die Dateien aktivieren, die Sie über die aktuellen kopiert haben wollen. Es gibt quite some documentation auf der Plugin-Seite sowie einige Beispiele

Hoffe, dass funktioniert!

+0

Aber meine benutzerdefinierten Konfigurationsdateien sind nicht Teil einer externen WAR, also bin ich mir nicht sicher, wie ich sie als Overlay anwenden könnte ... nicht überzeugt! –

+0

Ich denke, du brauchst keine externe Kriegsdatei, wenn du das maven-war-plugin und die Overlays verwendest. Die Parameter id/artifactId/groupId scheinen optional zu sein, sodass Sie die Umgebungskonfiguration nicht in ein separates Modul einfügen müssen. – wemu

+0

Das War-Plugin scheint in der Paketphase zu laufen: http://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html#Lifecycle_Reference, während das Ressourcen-Plugin früher in Prozess-Ressourcen läuft. Ich denke nicht, dass es so funktionieren wird, um das Kriegs-Plugin auszutricksen. – wemu

1

ein weiterer Versuch :)

ich um mit dem Overlay gespielt haben Parameter. Ich denke, das ersetzt nur Dateien innerhalb des Webapp-Ordners, die Sie in einer anderen WAR-Datei innerhalb des Webapp-Ordners haben. Das ist also nicht das Richtige für dein Setup.

Doch die oben genannten WebResource Parameter kann dies tun:

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

Die aktivierten Profile zusätzliche Ordner in die WAR-Datei hinzufügen. Das sollte es also tun!

1

Ich sehe, dass Sie die gleichen Ressourcen verwenden würden, aber mit unterschiedlicher Konfiguration in jedem Profil (Test und prod).

Also, ich schlage vor, Sie eine Konfiguration wie folgt zu verwenden:

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

In diesem Szenario Ich habe zwei Profile, die jeweils unter Verwendung von „env“ Parameter aktiviert. Jedes Profil verfügt über eine Datei zum Filtern Ihrer Ressourcen, legen Sie Ihre log4j.xml-, struts.properties-, context.xml-Dateien in src/main/resources ab und verwenden Sie Variablen, um die richtige Konfiguration in jedem Profil zu verwenden.

Hoffe, dass hilft.

0

Hier ist eine einfachere Version der obigen Lösungen, die nur auf einem einfachen Snippet basiert, das in pom.xml eingefügt wird.

Erstellen Sie den Standard (lokale Workstation) Webapp mit:

mvn war:exploded 

einen Umgebung Befehlszeilenparameter hinzufügen Dateien aus einem umgebungsspezifischen Verzeichnis wie Ressourcen-prod auf das Ziel WEB-INF/classes Verzeichnis zu kopieren:

mvn war:exploded -Denvironment=prod 

Fügen Sie diese innerhalb des Projektelement von 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> 

Mehr Infos und link to working example.

Verwandte Themen