Подтвердить что ты не робот

Maven: Исходная кодировка в UTF-8 не работает?

Я преобразовываю проект из Ant в Maven, и у меня возникают проблемы с конкретным unit test, который имеет дело с символами UTF-8. Проблема заключается в следующей строчке:

String l_string = "ČäÁÓý\n€řЖжЦ\n№ЯФКЛ";

Проблема в том, что unit test завершается с ошибкой, потому что строка читается следующим образом:

?äÁÓý
€????
?????

Класс java сохраняется как UTF-8, и я также указываю кодировку сборки UTF-8 в pom.xml.

Вот выдержка из моего pom.xml:

...

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

...

<build>
<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>3.1</version>
        <configuration>
            <source>1.6</source>
            <target>1.6</target>
            <encoding>${project.build.sourceEncoding}</encoding>
        </configuration>
    </plugin>
    <plugin>
        <artifactId>maven-assembly-plugin</artifactId>
        <version>2.4</version>
        <configuration>
            <descriptorRefs>
                <descriptorRef>jar-with-dependencies</descriptorRef>
            </descriptorRefs>
        </configuration>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.15</version>
    </plugin>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-report-plugin</artifactId>
      <version>2.15</version>
    </plugin>
 </plugins>
</build>

Мне что-то здесь не хватает? Было бы здорово, если бы кто-то помог мне здесь.

Обновление

Что касается тестового кода:

@Test
public void testTransformation()
{

    String l_string = "ČäÁÓý\n€řЖжЦ\n№ЯФКЛ";
    System.out.println( ">>> " + l_string );
     c_log.info( l_string );
    StringBuffer l_stringBuffer = new StringBuffer();
    int l_stringLength = l_string.length();

    String l_fileName = System.getProperty( "user.dir" ) + File.separator + "transformation" + File.separator + "TransformationMap.properties";
    Transformation.init( l_fileName );

    Properties l_props = Transformation.getProps();
    for ( int i = 0; i < l_stringLength; i++ )
    {
        char l_char = l_string.charAt( i );
        int l_intValue = (int) l_char;
        if ( l_intValue <= 255 )
        {
            l_stringBuffer.append( l_char );
        }
        else
        {
            l_stringBuffer.append( l_props.getProperty( String.valueOf( l_char ), "" ) );
        }
    }
    c_log.info( l_stringBuffer.toString() );
    byte[] l_bytes = l_string.getBytes();
    byte[] l_transformedBytes = Transformation.transform( l_bytes );
    assertNotNull( l_transformedBytes );

}

Следующая логика не актуальна (?), потому что после первого sysout ранее упомянутого "?" вместо правильных символов (и, следовательно, следующие тесты не работают). Также не используется кодировка платформы по умолчанию.

Тест преобразует каждый символ в соответствии с файлом TransformationMap.properties, который находится в следующем виде (только выдержка):

Ý=Y
ý=y
Ž=Z
ž=z
°=.
€=EUR

Следует отметить, что тест выполняется без каких-либо проблем при создании проекта с помощью Ant.

4b9b3361

Ответ 1

Я сам нашел "решение":

Мне пришлось передать кодировку в плагин maven-surefire, но обычный

<encoding>${project.build.sourceEncoding}</encoding>

не работает. Я до сих пор не знаю, почему, но когда я передаю аргументы командной строки в плагин, тесты работают так, как они должны:

<plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.15</version>
      <configuration>
        <argLine>-Dfile.encoding=UTF-8</argLine>
      </configuration>
</plugin>

Спасибо за ваши ответы и дополнительные комментарии!

Ответ 2

  • При отладке проблем с Unicode убедитесь, что вы конвертируете все в ASCII, чтобы вы могли читать и понимать, что внутри строки, без догадок. Это означает, что вы должны использовать, например, StringEscapeUtils из commons-lang3, чтобы превратить ä в \u00e4. Таким образом, вы можете быть уверены, что видите ?, потому что консоль не может ее распечатать. И вы можете отличить "(\u0020) от" " (\u00a0)

    В тестовом примере проверьте ускоренную версию входов как можно раньше, чтобы убедиться, что данные на самом деле вы ожидаете.

    Итак, код выше должен быть:

    assertEquals("\u010d\u00e4\u....", escape(l_string));
    
  • Убедитесь, что вы используете правильную кодировку для ввода-вывода файлов. Никогда не используйте стандартную кодировку Java, всегда используйте InputStreamReader/OutputStreamWriter и укажите используемую кодировку.

  • POM выглядит правильно. Запустите mvn с помощью -X, чтобы убедиться, что он выбирает правильные параметры и запускает компилятор Java, используя правильные параметры. mvn help:effective-pom также может помочь.

  • Разберите файл класса, чтобы проверить строки. Java будет использовать ? для обозначения того, что он не мог что-то прочитать.

    Если вы получаете ? из System.out.println( ">>> " + l_string );, это означает, что код не был скомпилирован с помощью UTF-8 или что исходный файл, возможно, был сохранен с помощью другой кодировки Unicode (UTF-16 или аналогичный).

    Другим источником проблем может быть файл свойств. Убедитесь, что он был сохранен с ISO-8859-1 и что он не был изменен процессом компиляции.

  • Убедитесь, что Maven фактически компилирует ваш файл. Используйте mvn clean, чтобы принудительно выполнить полную перекомпиляцию.

Ответ 3

Ваша проблема заключается не в кодировании исходного файла (и, следовательно, в String внутри вашего файла класса), но проблема - это кодировка System.out implicite PrintStream. Он использует file.encoding, который представляет Системную кодировку, и это в Windows кодовая страница ANSI.

Вам нужно будет установить PrintWriter с кодовой страницей OEM (или вы используете класс, который предназначен для этого: Console).

См. также различные ошибки в этом: http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4153167

Ответ 4

это работает для меня:

...
 <properties>
        **<project.build.sourceEncoding>ISO-8859-1</project.build.sourceEncoding>
        <project.reporting.outputEncoding>ISO-8859-1</project.reporting.outputEncoding>**
    </properties>
...
  <build>
    <finalName>Project</finalName>

    <sourceDirectory>src</sourceDirectory>
    <plugins>
      <plugin>
        <artifactId>maven-compiler-plugin</artifactId>
        <version>2.3.2</version>
        <configuration>
          <source>1.6</source>
          <target>1.6</target>
          **<encoding>${project.build.sourceEncoding}</encoding>**
        </configuration>
      </plugin>
      <plugin>
        <artifactId>maven-war-plugin</artifactId>
        <version>2.2</version>
        <configuration>
          <warSourceDirectory>WebContent</warSourceDirectory>
        </configuration>
      </plugin>
    </plugins>
  </build>

Ответ 5

У меня была действительно устойчивая проблема такого рода и установка переменной окружения

MAVEN_OPTS=-Dfile.encoding=UTF-8

исправил проблему для меня.