Web resources filtering with Maven war plugin does

2019-03-08 10:33发布

I'm trying to filter a Spring configuration file using Maven filtering. My POM is configured like this:

        ...
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-war-plugin</artifactId>
          <version>2.2</version>
          <configuration>
            <webResources>
              <resource>
                <filtering>true</filtering>
                <targetPath>WEB-INF/context</targetPath>
                <directory>src/main/webapp/WEB-INF/context</directory>
                <includes>
                  <include>applicationContext.xml</include>
                </includes>
              </resource>
            </webResources>
          </configuration>
        </plugin>
        ...

and

  <profiles>
    <profile>
        <id>desarrollo</id>
         <activation>
          <activeByDefault>true</activeByDefault>
        </activation>
        <build>
            <filters>
              <filter>src/main/properties/dev.properties</filter>
            </filters>
      </build>
    </profile>
    <profile>
        <id>pruebas</id>
        <build>
            <filters>
              <filter>src/main/properties/test.properties</filter>
            </filters>
      </build>
    </profile>
            ...

It works great when invoking Maven directly.

Unfortunately, when hot-deploying the webapp in Tomcat 6 with Eclipse WTP and m2e it always picks the unfiltered version of applicationContext.xml. (The file applicationContext.xml in the folder target/m2e-wtp/web-resources/WEB-INF/context is never filtered)

I can't find any useful documentation on the subject. I'm not even sure if it is implemented in m2e.

Is something wrong with my configuration or this is an unimplemented feature?

6条回答
【Aperson】
2楼-- · 2019-03-08 10:57

Well, finally I got it.

First of all, I did what khmarbaise pointed out. I moved applicationContext.xml to the resources folder. War plugin webResources are meant to work with external resources, and filtering a file in the destination folder itself was not the best practice. I updated the POM to reflect the new configuration

    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>

and

        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-war-plugin</artifactId>
            <version>2.2</version>
            <configuration>
                <webResources>
                    <resource>
                        <filtering>true</filtering>
                        <targetPath>WEB-INF/context</targetPath>
                        <directory>src/main/resources/WEB-INF/context</directory>
                        <includes>
                            <include>applicationContext.xml</include>
                        </includes>
                    </resource>
                </webResources>
            </configuration>
        </plugin>

So, half of the credit for him. But that's was not enough, it still didn't worked. I realized that Maven/m2e was indeed filtering my file, but it didn't get my defined properties files. After some testing I found out that m2e is ignoring the activeByDefault option in the profiles activation section.

So, I added my default profile to the project Maven configuration and then it worked

enter image description here

查看更多
干净又极端
3楼-- · 2019-03-08 11:00

Have you tried to put the resources under src/main/resources/WEB-INF/... instead of and configured the resources area to filter the resources instead of putting configuration into a non default maven location.

查看更多
孤傲高冷的网名
4楼-- · 2019-03-08 11:01

I had a similar problem with filtering the web.xml. I solved the problem by reimporting the whole project in eclipse.

The reason was a corrupt /.settings/org.eclipse.wst.common.component file. In this file the order of the files copied to the local web servers deploy directory is defined. For example:

<?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">
  <wb-module deploy-name="liquidvote-rest">
    <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>
    <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>
    <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/java"/>
    <wb-resource deploy-path="/WEB-INF/classes" source-path="/src/main/resources"/>
    <property name="context-root" value="myapp"/>
    <property name="java-output-path" value="/myapp/target/classes"/>
  </wb-module>
</project-modules>

If the web.xml or application.xml exists in several directories it will be taken from the first directory found. Therefore its important that

    <wb-resource deploy-path="/" source-path="/target/m2e-wtp/web-resources"/>

is the first entry.

You will find more informations at http://wiki.eclipse.org/M2E-WTP_FAQ in the section "What is this web resources folder?"

查看更多
甜甜的少女心
5楼-- · 2019-03-08 11:05

I've tried everything described above without success. The files were filtered and generated correctly at the "m2e-wtp" folder, but for some reason Eclipse was copying files from "target/classes".

Thus, I've changed my pom.xml, changing the destination folder from "m2e-wtp" to "target/classes", like code ahead.

Important: everytime you need to run a maven build on project, you must change the pom in order to build de project.

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <version>2.4</version>  
    <configuration>
        <failOnMissingWebXml>false</failOnMissingWebXml>
        <filters>
            <filter>${project.basedir}/src/main/filters/${build.profile.id}/config.properties</filter>
        </filters>
        <webResources>
            <resource>
                <filtering>true</filtering>
                <directory>${project.basedir}/src/main/resources</directory>
                <targetPath>${project.basedir}/target/classes</targetPath>
                <includes>
                    <include>*.properties</include>
                    <include>*.xml</include>
                    <include>META-INF/spring/*.xml</include>
                </includes>
            </resource>
        </webResources>
    </configuration>
</plugin>
查看更多
Deceive 欺骗
6楼-- · 2019-03-08 11:13

Today I had similar problem when several jars were included into war. I set the filtering on,and compared the original jars with filtered. They seem to be same,but this is not true. I tried to rename jar to zip and I was not able to unpack the content due to corrupted structure inside jar(zip) whereas the original one were ok. It is also mentioned here adding filtering web resources where is said that filtering has to be set false to prevent corrupting your binary files.

查看更多
祖国的老花朵
7楼-- · 2019-03-08 11:15

I just had a similar problem. My solution is not elegant and I am not proud of it, but let's say it is acceptable. In my case I have a spring boot mvc application with swagger application (for testers to test our API). The thing is we are using this app in two environments, so I created two profiles - dev and test. In dev env we would like to fire application from eclipse with just "run as" so the context path is blank (I know it can be set in spring java config, but it is not the only placeholder we would like to switch) and in test env the application is run in our customized version of tomcat... so the context path is the same as war file name.

and here is the problem - swagger is calling rest docs on this context path and it depends on spring profile. So we have a web resource that needs to be filtered. At first I tried to use m2e-wtp filtering:

...
<build>
<plugins>
<plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <configuration>
                    <webResources>
                        <resource>
                            <filtering>true</filtering>
                            <directory>src/main/webapp</directory>
                            <includes>
                                <include>**/scripts.js</include>
                            </includes>
                        </resource>
                    </webResources>
                </configuration>
            </plugin>
...

it was working but only run in embedded in eclipse tomcat or from commandline java -jar it was not working with "run as" from eclipse.

The resource was filtered and I saw them in web-resource in target, but eclipse seems to be running on a source code directly or is making a copy I do not know... it cannot see filtered resources... so I thought that I will make something like this:

<resources>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
            <resource>
                <filtering>true</filtering>
                <directory>src/main/resources/webapp/swagger</directory>
                <targetPath>${basedir}/src/main/webapp/swagger</targetPath>
                <includes>
                    <include>scripts.js</include>
                </includes>
            </resource>
        </resources>

It is not most fortunate solution, because it is modifing code and not the target, but at least it is working. If anyone would have any suggestions how to make it work without code modifications I would be greateful.

查看更多
登录 后发表回答