在maven中配置不同文件类型的编码?

时间:2012-06-21 18:42:25

标签: maven encoding

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

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

在子项目中,我有一个 test.properties 文件,它是一个普通的java properties file,默认编码= 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

2 个答案:

答案 0 :(得分:5)

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

  • 这不是显而易见的,但在作者的示例中,默认资源复制目标resources仍然启用并且除了两个定义的目标外还会运行!
  • 您会注意到作者使用了生命周期阶段generate-resources而不是默认的process-resources。这是解决上述第一点的一个技巧;通过使两个copy-resources目标在较早的生命周期阶段发生,资源根据给定的规则进行复制,然后当default-resources目标出现时,原始资源复制保持不变,显然是因为它overwrite设置默认值为false。但disable altogether执行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>

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

答案 1 :(得分:2)

你是正确的,你必须配置执行......如果你遵循标准的目录布局但是你似乎要放置来自{{1的文件} {} {} {}} {}} {} {}} {}}} {...}} {...}}} {...}}} {...}} {...}} {...}} {

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