Maven:UTF-8 中的源编码不起作用?

问题描述 投票:0回答:6

我正在将项目从 Ant 转换为 Maven,并且在处理 UTF-8 字符的特定单元测试中遇到问题。问题在于以下字符串:

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

问题是单元测试失败,因为String被读取如下:

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

java 类保存为 UTF-8,我还在 pom.xml 中将构建编码指定为 UTF-8。

这是我的 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 );

}

以下逻辑并不真正相关(?),因为在第一个系统输出之后前面提到的“?”打印而不是正确的字符(因此以下测试失败)。也没有使用默认平台编码。

测试根据TransformationMap.properties文件对每个字符进行转换,其形式如下(仅摘录):

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

需要注意的是,当我使用Ant构建项目时,测试运行没有任何问题。

java maven encoding utf-8
6个回答
150
投票

我自己找到了“解决方案”:

我必须将编码传递到 maven-surefire-plugin 中,但通常

<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>

感谢您的所有回复和附加评论!


10
投票
  1. 调试 Unicode 问题时,请确保将所有内容都转换为 ASCII,以便您无需猜测即可阅读和理解字符串内部的内容。这意味着您应该使用

    commons-lang3
    中的 StringEscapeUtils
    ä
    转换为
    \u00e4
    。这样,您就可以确保看到
    ?
    ,因为控制台无法打印它。并且您可以区分“ ” (
    \u0020
    ) 和“ ” (
    \u00a0
    )

    在测试用例中,尽早检查输入的转义版本,以确保数据确实是您所期望的。

    所以上面的代码应该是:

    assertEquals("\u010d\u00e4\u....", escape(l_string));
    
  2. 确保对文件 I/O 使用正确的编码。切勿使用 Java 的默认编码,始终使用

    InputStreamReader
    /
    OutputStreamWriter
    并指定要使用的编码。

  3. POM 看起来正确。与

    mvn
    一起运行
    -X
    以确保它选择正确的选项并使用正确的选项运行 Java 编译器。
    mvn help:effective-pom
    也可能有帮助。

  4. 反汇编类文件以检查字符串。 Java 将使用

    ?
    来表示它无法读取某些内容。

    如果您从

    ?
    中得到
    System.out.println( ">>> " + l_string );
    ,这意味着代码不是使用 UTF-8 编译的,或者源文件可能是使用其他 Unicode 编码(UTF-16 或类似编码)保存的。

    问题的另一个来源可能是属性文件。确保它是用 ISO-8859-1 保存的,并且没有被编译过程修改。

  5. 确保 Maven 确实编译了您的文件。使用

    mvn clean
    强制完全重新编译。


6
投票

我遇到了此类真正有弹性的问题并设置环境变量

MAVEN_OPTS=-Dfile.encoding=UTF-8

为我解决了这个问题。


4
投票

您的问题不是源文件的编码(因此也是类文件中的字符串),而是问题是

System.out
的隐式
PrintStream
的编码。它使用
file.encoding
表示系统编码,这在 Windows 中是 ANSI 代码页。

您必须使用 OEM 代码页设置

PrintWriter
(或者您使用专用于此目的的类: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>

0
投票

以下工作对我来说没有任何问题:

       <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>3.1.0</version>
          <configuration>
            <test>com.testsuite.JunitTestSuite</test>
            *<argLine>${argLine} -Dfile.encoding=UTF-8</argLine>*
          </configuration>
        </plugin>
© www.soinside.com 2019 - 2024. All rights reserved.