16

我使用maven-resource-plugin来过滤我的 maven 项目中的一些资源。在我的父项目中,我有:

<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

在一个子项目中,我有一个test.properties文件,它是一个普通的java 属性文件,默认编码 = ISO-8859-1。该文件包含:

aboutText=Version ${project.version} © 2012 blabla

为了确保此文件正确过滤,我已将 maven-resource-plugin 拆分为单独的执行,每个执行都有其编码:

  <plugin>
    <artifactId>maven-resources-plugin</artifactId>
    <configuration>
      <nonFilteredFileExtensions>
        <nonFilteredFileExtension>ico</nonFilteredFileExtension>
        <nonFilteredFileExtension>jar</nonFilteredFileExtension>
      </nonFilteredFileExtensions>
    </configuration>
    <executions>
      <execution>
        <id>filter-properties-files</id>
        <phase>generate-resources</phase>
        <goals>
          <goal>copy-resources</goal>
        </goals>
        <configuration>
          <!-- java properties files are encoded in ISO-8859-1 so when 
            filtering those files we stick with that encoding. -->
          <encoding>ISO-8859-1</encoding>
          <outputDirectory>${basedir}/after</outputDirectory>
          <resources>
            <resource>
              <filtering>true</filtering>
              <directory>${basedir}/before</directory>
              <includes>
                <include>**/*.properties</include>
              </includes>
            </resource>
          </resources>
        </configuration>
      </execution>
      <execution>
        <id>filter-non-properties-files</id>
        <phase>generate-resources</phase>
        <goals>
          <goal>copy-resources</goal>
        </goals>
        <configuration>
          <encoding>${project.build.sourceEncoding}</encoding>
          <outputDirectory>${basedir}/after</outputDirectory>
          <resources>
            <resource>
              <filtering>true</filtering>
              <directory>${basedir}/before</directory>
              <includes>
                <include>**/*.product</include>
                <include>**/*.inf</include>
              </includes>
            </resource>
          </resources>
        </configuration>
      </execution>
    </executions>
  </plugin>

这似乎有点矫枉过正,我觉得我要么没有正确使用插件,要么应该以另一种方式处理这个问题。也许坚持直接在属性文件中编码特殊字符:

aboutText=Version ${project.version} \u00a9 2012 blabla

?

4

2 回答 2

5

这个问题本身就是一个非常宝贵的答案,因为显然作者提供的复杂过程是为各种过滤文件类型配置不同编码的唯一方法。然而,给出的示例是针对作者的非标准用例的,并且忽略了一些重要细节,没有这些细节,该示例的实际使用充满了陷阱:

  • 这并不明显,但在作者的示例中,默认的资源复制目标resources仍然启用并在两个定义的目标之外运行!
  • 您会注意到作者使用了生命周期阶段generate-resources而不是默认的process-resources. 这是绕过上述第一点的技巧;通过使这两个copy-resources目标发生在较早的生命周期阶段,根据给定的规则复制资源,然后当default-resources目标出现时,原始资源复制保持不变,显然是因为它的overwrite设置 defaults false。但最好完全禁用执行default-resources
  • 作者提供了一份outputDirectory声明。很自然地认为作者提供这个只是因为需要一个自定义的输出目录;毕竟,resources目标为此设置提供了默认值。但奇怪的是,对于copy-resources目标,这个设置实际上是必需的!但是,有一个标准的 Maven 变量${project.build.outputDirectory}可以用作值。

基于作者自己在问题中的示例,这里是一种使用 ISO-8859-1 过滤属性文件的剪切和粘贴方式,复制其他文件而不过滤,并防止发生默认资源复制;全部使用标准源和目标目录:

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-resources-plugin</artifactId>
  <version>2.7</version>
  <executions>
    <execution>
      <!-- Turn off default resource copying. -->
      <id>default-resources</id>
      <phase />
    </execution>
    <execution>
      <!-- Filter resources in properties files. -->
      <id>filter-properties-files</id>
      <phase>process-resources</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <encoding>ISO-8859-1</encoding>
        <outputDirectory>${project.build.outputDirectory}</outputDirectory>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
              <include>**/*.properties</include>
            </includes>
          </resource>
        </resources>
      </configuration>
    </execution>
    <execution>
      <!-- Do not do property substitution in files that are not properties files, such as binary files. -->
      <id>copy-other-resources</id>
      <phase>process-resources</phase>
      <goals>
        <goal>copy-resources</goal>
      </goals>
      <configuration>
        <outputDirectory>${project.build.outputDirectory}</outputDirectory>
        <resources>
          <resource>
            <directory>src/main/resources</directory>
            <filtering>false</filtering>
            <excludes>
              <exclude>**/*.properties</exclude>
            </excludes>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

更新:经过更多研究,我相信与其禁用默认执行,不如简单地修改默认执行以忽略属性文件,并添加对属性文件的过滤作为附加执行。此外,如果使用resources目标而不是copy-resources,则无需指示输出目录或阶段,因为resources:resources会自动绑定到process-resources阶段并输出到${project.build.outputDirectory}。请注意,我已经更新到插件的 3.1.0 版本,因此可能其中一些选项在我上面使用的版本中不可用。我还没有测试过这个新的、更短的配置。

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-resources-plugin</artifactId>
  <version>3.1.0</version>
  <executions>
    <execution>
      <!-- Ignore properties files by default. -->
      <id>default-resources</id>
      <configuration>
        <resources>
          <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <excludes>
              <exclude>**/*.properties</exclude>
            </excludes>
          </resource>
        </resources>
      </configuration>
    </execution>
    <execution>
      <!-- Filter resources in properties files using ISO-8859-1. -->
      <id>filter-properties-files</id>
      <goals>
        <goal>resources</goal>
      </goals>
      <configuration>
        <encoding>ISO-8859-1</encoding>
        <resources>
          <resource>
            <directory>${project.basedir}/src/main/resources</directory>
            <filtering>true</filtering>
            <includes>
              <include>**/*.properties</include>
            </includes>
          </resource>
        </resources>
      </configuration>
    </execution>
  </executions>
</plugin>

也许有人可以测试这个新配置并让我知道它是否与我上面给出的原始配置相同。

于 2014-10-06T23:34:13.033 回答
2

你是对的,你必须配置执行......如果你遵循标准目录布局,你可以使用两个执行而不是你似乎正在使用的三个,但你似乎将文件${basedir}/before放入${basedir}/after其中,因此默认执行resources:resources再加上向该部分添加多个resourcesbuild不适合您。

过滤文件的编码是原始pom模型规范中的疏忽,可能会在某些尚未指定的 Maven 版本中得到修复

于 2012-09-17T11:43:25.237 回答