Настроить кодировку для разных типов файлов в maven?

Я использую 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

?

Ответы

Ответ 1

Вопрос является бесценным ответом сам по себе, поскольку, по-видимому, сложная процедура, которую предоставляет автор, является единственным способом настройки различных кодировок для различных типов фильтрованных файлов. Однако приведенный пример специфичен для автора нестандартного прецедента и замаскирует несколько важных деталей, без которых фактическое использование примера чревато gotchas:

  • Это не очевидно, но в примере автора цель по умолчанию для копирования ресурсов 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>

Ответ 2

Вы правы, что вам нужно настроить выполнение... Вы можете избавиться от двух исполнений, а не трех, которые вы, кажется, используете, если вы следовали стандартным макетам каталога, но вы, кажется, помещаете файлы из ${basedir}/before в ${basedir}/after, поэтому выполнение по умолчанию resources:resources в сочетании с добавлением нескольких resources в раздел build не будет работать для вас.

Кодировка фильтрованных файлов была надзором в исходной спецификации модели pom и, скорее всего, будет исправлена ​​в некоторой еще не уточненной версии Maven