web-dev-qa-db-fra.com

Maven: Le codage source en UTF-8 ne fonctionne pas?

je convertis un projet de Ant en Maven et j'ai des problèmes avec un test unitaire spécifique qui traite des caractères UTF-8. Le problème concerne la chaîne suivante:

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

Le problème est que le test unitaire échoue, car la chaîne est lue comme suit:

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

La classe Java est enregistrée en UTF-8 et je spécifie également l'encodage de construction en UTF-8 dans le pom.xml.

Voici un extrait de mon 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>

Est-ce que j'ai râté quelque chose? Ce serait formidable si quelqu'un pouvait m'aider ici.

Mise à jour

Concernant le code de test:

@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 );

}

La logique suivante n'est pas vraiment pertinente (?) Car après le premier sysout le "?" sont imprimés à la place des caractères corrects (et donc les tests suivants échouent). Il n'y a pas non plus d'utilisation d'un encodage de plateforme par défaut.

Le test convertit chaque caractère en fonction du fichier TransformationMap.properties, qui se présente sous la forme suivante (juste un extrait):

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

Il convient de noter que le test s'exécute sans problème lorsque je crée le projet avec Ant.

34
softandsafe

J'ai moi-même trouvé une "solution":

J'ai dû passer l'encodage dans le plugin maven-surefire, mais l'habituel

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

n'a pas fonctionné. Je n'ai toujours aucune idée pourquoi, mais quand je passe les arguments de ligne de commande dans le plugin, les tests fonctionnent comme ils le devraient:

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

Merci pour toutes vos réponses et commentaires supplémentaires!

108
softandsafe
  1. Lors du débogage des problèmes Unicode, assurez-vous de tout convertir en ASCII afin de pouvoir lire et comprendre ce qui se trouve à l'intérieur d'une chaîne sans deviner. Cela signifie que vous devez utiliser, par exemple, StringEscapeUtils de commons-lang pour transformer ä en \u00e4. De cette façon, vous pouvez être sûr que vous voyez ? car la console ne peut pas imprimez-le. Et vous pouvez distinguer "" (\u0020) de "" (\u00a0)

    Dans le cas de test, vérifiez la version d'échappement des entrées le plus tôt possible pour vous assurer que les données correspondent réellement à ce que vous attendez.

    Le code ci-dessus devrait donc être:

    assertEquals("\u010d\u00e4\u....", escape(l_string));
    
  2. Assurez-vous d'utiliser le codage correct pour les E/S de fichiers. N'utilisez jamais l'encodage par défaut de Java, utilisez toujours InputStreamReader/OutputStreamWriter et spécifiez l'encodage à utiliser.

  3. Le POM semble correct. Exécutez mvn avec -X Pour vous assurer qu'il récupère les bonnes options et exécute le Java utilisant les bonnes options. mvn help:effective-pom Pourrait également Aidez-moi.

  4. Démontez le fichier de classe pour vérifier les chaînes. Java utilisera ? Pour indiquer qu'il n'a pas pu lire quelque chose.

    Si vous obtenez le ? De System.out.println( ">>> " + l_string );, cela signifie que le code n'a pas été compilé avec UTF-8 ou que le fichier source a peut-être été enregistré avec un autre encodage Unicode (UTF-16 ou similaire) .

    Une autre source de problèmes pourrait être le fichier de propriétés. Assurez-vous qu'il a été enregistré avec ISO-8859-1 et qu'il n'a pas été modifié par le processus de compilation.

  5. Assurez-vous que Maven compile réellement votre fichier. Utilisez mvn clean Pour forcer une recompilation complète.

9
Aaron Digulla

cela fonctionne pour moi:

...
 <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>
4
Eric Martinez

Votre problème n'est pas l'encodage du fichier source (et donc la chaîne à l'intérieur de votre fichier de classe) mais le problème est l'encodage de System.out implicite PrintStream. Il utilise file.encoding qui représente l'encodage système, et c'est dans Windows la page de code ANSI.

Vous devrez configurer un PrintWriter avec la page de codes OEM (ou vous utilisez la classe qui est destinée à cela: Console ).

Voir également divers bugs à ce sujet dans: http://bugs.Java.com/bugdatabase/view_bug.do?bug_id=4153167

3
eckes

J'ai eu un problème très résilient de ce type et j'ai mis une variable environnementale

MAVEN_OPTS=-Dfile.encoding=UTF-8

résolu le problème pour moi.

0
David Vonka