Avertissement "caractère non mappable pour le codage" en Java

112

Je travaille actuellement sur un projet Java qui émet l'avertissement suivant lorsque je compile:

/src/com/myco/apps/AppDBCore.java:439: warning: unmappable character for encoding UTF8
    [javac]         String copyright = "� 2003-2008 My Company. All rights reserved.";

Je ne sais pas comment SO rendra le caractère avant la date, mais il devrait s'agir d'un symbole de copyright et s'affiche dans l'avertissement sous la forme d'un point d'interrogation dans un losange.

Il est à noter que le caractère apparaît correctement dans l'artefact de sortie, mais les avertissements sont une nuisance et le fichier contenant cette classe peut un jour être touché par un éditeur de texte qui enregistre de manière incorrecte l'encodage ...

Comment puis-je injecter ce caractère dans la chaîne "copyright" pour que le compilateur soit satisfait et que le symbole soit conservé dans le fichier sans problèmes de réencodage potentiels?

seanhodges
la source
être intéressé à savoir quels octets constituent ce caractère de copyright, c'est-à-dire que hexdump AppDBCore.javaj'en doute d'une manière ou d'une autre \u00a9et c'est quelque chose qui fonctionne partiellement pour vous à cause de la configuration de votre système. Le point d'interrogation ci-dessus est utilisé pour remplacer un caractère entrant dont la valeur est inconnue ou non représentable dans Unicode hexutf8.com
jar

Réponses:

56

Utilisez le format d'échappement "\ uxxxx".

Selon Wikipédia , le symbole du droit d'auteur est unicode U + 00A9, votre ligne doit donc lire:

String copyright = "\u00a9 2003-2008 My Company. All rights reserved.";
Jon Skeet
la source
13
Soyez prudent avec les caractères \ uNNNN ... ils sont analysés avant de faire une analyse lexicale. Par exemple, si vous mettez ce commentaire / * c: \ unit * / dans votre code, il ne se compilera plus, car "nit" n'est pas un nombre hexadécimal correct.
Peter Štibraný
3
Absolument. (Ceci est mieux géré en C #, où l'échappement Unicode n'est appliqué que dans certains contextes - mais il y a aussi la dangereuse séquence d'échappement \ x, ce qui est horrible.)
Jon Skeet
5
Cela ressemble plus à un pansement qu'à un remède. Le vrai problème semble être que vous dites à javac d'attendre des fichiers source en UTF-8 alors qu'ils sont vraiment dans un codage à un octet comme ISO-8859-1 ou Windows-1252.
Alan Moore
6
@Alan M: D'après mon expérience, il est beaucoup plus facile de s'assurer que vous n'aurez pas de problème en conservant les fichiers source en ASCII que de vous assurer d'utiliser le bon encodage partout où votre source pourrait être compilée (Ant, Eclipse, IDÉE, etc.).
Jon Skeet
6
@Jon, c'est une faille fondamentale en Java; le fait que l'unité source Java soit encodée en UTF-8, ISO 8859-1, CP1252, MacRoman, ou autre, est traitée au niveau des métadonnées externes à l'unité source qui en a besoin. Cela vous oblige à vous rappeler de réparer votre fichier fourmi ou votre configuration Eclipse, etc. Comme vous le faites remarquer à juste titre, c'est absolument la pire façon de le faire, car les informations sont fragiles et facilement perdues. Les langages qui conservent les métadonnées (codage des métadonnées) et les données (lire: code source) ensemble en un seul endroit sont beaucoup plus robustes à cet égard. C'est la seule approche sensée.
tchrist
91

Essayez avec: javac -encoding ISO-8859-1 nom_fichier.java

Fernando Nah
la source
1
J'aime cette solution. J'ai ajouté "-encoding UTF-8" comme un argument de compilation dans mon fichier build.xml et j'obtiens toujours "warning: unmappable character for encoding ASCII". Si je le modifie en "-encoding jjjj", il ne compilera pas, se plaignant de "erreur: encodage non pris en charge: jjjj", donc je sais qu'il reconnaît UTF-8, mais il semble toujours être traité comme des fichiers .java comme ascii. Soupir.
dfrankow
1
J'ai essayé le paramètre "encoding" de la tâche ant javac, même problème. Il reconnaît le paramètre, mais l'ignore ensuite d'une manière ou d'une autre.
dfrankow
20
@dfrankow: vous devez ajouter <compilerarg line="-encoding utf-8"/>sous l' <javac>appel applicable dans votre Build.xmldossier. C'est une mauvaise façon de le faire, mais vous n'avez pas le choix. Voir mon long commentaire en haut.
tchrist
J'ai eu le même problème quand j'ai ajouté la compilation dans le script de fourmi, cela fonctionnait bien, je construisais ceci à partir d'une ligne de commande Windows, le problème étrange est que je construisais depuis eclipse, il a sombré dans le ciel sans la compilation, ça ressemble à cette éclipse qui s'en soucie du droit de codage.
simonC
Cela m'a aidé :) pour MAC OSX
Arun Abraham
44

Si vous utilisez Maven, définissez <encoding>explicitement le dans la configuration du plugin du compilateur, par exemple

<build>
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>2.3.2</version>
            <configuration>
                <encoding>UTF-8</encoding>
            </configuration>
        </plugin>
Thomas Leonard
la source
C'est la bonne approche si les gens utilisent maven pour construire leur projet, merci pour le partage.
Shamik
2
Le plugin javadoc se plaindra également du caractère non mappable. Il est préférable de définir la project.build.sourceEncodingpropriété.
Emmanuel Bourg
J'utilisais déjà la propriété project.build.sourceEncoding, mais d'une manière ou d'une autre, elle ne correspondait pas correctement à la propriété d'encodage du compilateur. Le définir explicitement a fait l'affaire
Federico Bonelli
32

Cela m'a aidé:

Tout ce que vous avez à faire est de spécifier une variable d'environnement appelée JAVA_TOOL_OPTIONS. Si vous définissez cette variable sur -Dfile.encoding = UTF8, chaque fois qu'une JVM est démarrée, elle récupérera ces informations.

Source: http://whatiscomingtomyhead.wordpress.com/2012/01/02/get-rid-of-unmappable-character-for-encoding-cp1252-once-and-for-all/

soirée
la source
wow ça marche, je viens d'ajouter ceci à mon .bashrc, et cela a résolu mon problème.
cowboi-peng
A très bien fonctionné, à partir de la ligne de commande, j'ai entré pour construire: javac MyJavaFile.java -encoding utf-8 -cp .;lib\*puis lors de son exécution, je n'ai pas eu besoin d'ajouter cette partie d'encodage supplémentaire.
Azurespot le
23

mettez cette ligne dans votre fichier .gradle au-dessus de la configuration Java.

apply plugin: 'java'
compileJava {options.encoding = "UTF-8"}   
Alobes5
la source
Vous voudrez peut-être définir l'encodage pour compileTestJavaet pour javadocaussi
Frank Neblung
8

La plupart du temps, cette erreur de compilation survient lors de la compilation de fichiers Unicode (encodé en UTF-8)

javac -encoding UTF-8 HelloWorld.java

et aussi Vous pouvez ajouter cette option de compilation à votre IDE ex: Intellij idea
(File> settings> Java Compiler) ajouter comme paramètre de ligne de commande supplémentaire

entrez la description de l'image ici

-encoding: encoding Définit le nom de codage du fichier source, tel que EUC-JP et UTF-8 .. Si -encoding n'est pas spécifié, le convertisseur par défaut de la plate-forme est utilisé. ( DOC )

Alupotha
la source
8

Étapes Gradle

Si vous utilisez Gradle, vous pouvez trouver la ligne qui applique le plugin java:

apply plugin: 'java'

Ensuite, définissez le codage de la tâche de compilation sur UTF-8:

compileJava {options.encoding = "UTF-8"}   

Si vous avez des tests unitaires, vous voudrez probablement les compiler également avec UTF-8:

compileTestJava {options.encoding = "UTF-8"}

Exemple général de Gradle

Cela signifie que le code de gradle global ressemblerait à ceci:

apply plugin: 'java'
compileJava {options.encoding = "UTF-8"}
compileTestJava {options.encoding = "UTF-8"}
Luke Machowski
la source
2

Cela a fonctionné pour moi -

    <?xml version="1.0" encoding="utf-8" ?>
<project name="test" default="compile">
    <target name="compile">
        <javac srcdir="src" destdir="classes" 
                           encoding="iso-8859-1" debug="true" />
    </target>
</project>
Dxx0
la source
1

Si vous utilisez eclipse (Eclipse peut mettre du code utf8 pour vous même si vous écrivez le caractère utf8. Vous verrez le caractère utf8 normal lorsque vous programmez mais l'arrière-plan sera du code utf8);

  1. Sélectionnez un projet
  2. Faites un clic droit et sélectionnez Propriétés
  3. Sélectionnez Ressource sur le panneau de ressources (menu en haut à droite qui s'est ouvert après 2.)
  4. Vous pouvez voir dans le panneau de ressources , Encodage de fichier texte , sélectionnez l'autre que vous voulez

PS: cela ira si vous avez une valeur statique dans le code. Par exemple String test = "İİİİİııııııçççç";

baybora.oren
la source
1
Votre description de «Vous verrez un caractère [a] utf8 normal lorsque vous [êtes] en train de programmer mais [le] fond sera du code utf8» n'a aucun sens. Voir également mon long commentaire en réponse à la question ci-dessus.
tchrist
Je l'ai changé en ISO-8859-1, mais j'ai quand même eu une erreur de compilation concernant "caractère non mappable pour encoder UTF8".
pacoverflow
1

J'ai eu le même problème, où l'index des caractères signalé dans le message d'erreur java était incorrect. Je l'ai réduit aux doubles guillemets juste avant que la position signalée soit hex 094 (annuler au lieu de guillemets, mais représentée comme une citation) au lieu de hex 022. Dès que j'ai échangé pour la variante hex 022 tout allait bien.

Kelvin Goodson
la source
1

Si vous utilisez Maven Build à partir de l'invite de commande, vous pouvez également utiliser la commande suivante:

                    mvn -Dproject.build.sourceEncoding=UTF-8
5122014009
la source
1

Pour ceux qui se demandent pourquoi cela se produit sur certains systèmes et pas sur d'autres (avec la même source, les mêmes paramètres de construction, etc.), vérifiez votre LANGvariable d'environnement . J'obtiens l'avertissement / l'erreur quand LANG=C.UTF-8, mais pas quand LANG=en_US.UTF-8.

Jakar
la source