Ostrzeżenie „niemapowalny znak do kodowania” w Javie

112

Obecnie pracuję nad projektem Java, który emituje następujące ostrzeżenie podczas kompilacji:

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

Nie jestem pewien, jak SO wyrenderuje postać przed datą, ale powinien to być symbol praw autorskich i jest wyświetlany w ostrzeżeniu jako znak zapytania w diamentie.

Warto zauważyć, że znak pojawia się poprawnie w artefakcie wyjściowym, ale ostrzeżenia są uciążliwe i plik zawierający tę klasę może pewnego dnia zostać dotknięty przez edytor tekstu, który zapisuje kodowanie niepoprawnie ...

Jak mogę wstawić ten znak do ciągu znaków „copyright”, aby kompilator był zadowolony, a symbol został zachowany w pliku bez potencjalnych problemów z ponownym kodowaniem?

seanhodges
źródło
zainteresuj się tym, jakie bajty składają się na znak praw autorskich, tj. hexdump AppDBCore.javajakoś wątpię w to, \u00a9a zamiast tego jest to coś, co częściowo działa dla ciebie z powodu konfiguracji systemu. Powyższy znak zapytania jest używany do zastąpienia przychodzącego znaku, którego wartość jest nieznana lub niereprezentowalna w Unicode hexutf8.com/ ...
jar

Odpowiedzi:

56

Użyj formatu zmiany znaczenia „\ uxxxx”.

Według Wikipedii symbolem praw autorskich jest unicode U + 00A9, więc wiersz powinien brzmieć:

String copyright = "\u00a9 2003-2008 My Company. All rights reserved.";
Jon Skeet
źródło
13
Uważaj na \ uNNNN znaki ... są one analizowane przed wykonaniem analizy leksykalnej. Na przykład, jeśli umieścisz ten komentarz / * c: \ unit * / w swoim kodzie, nie będzie on już kompilowany, ponieważ „nit” nie jest poprawną liczbą szesnastkową.
Peter Štibraný
3
Absolutnie. (Jest to lepiej obsługiwane w C #, gdzie ucieczka unicode jest stosowana tylko w niektórych kontekstach - ale jest też niebezpieczna sekwencja ucieczki \ x, która jest okropna.)
Jon Skeet
5
To brzmi bardziej jak plaster niż lekarstwo. Wydaje się, że prawdziwym problemem jest to, że mówisz javacowi, aby spodziewał się plików źródłowych w UTF-8, gdy tak naprawdę są one w kodowaniu jednobajtowym, takim jak ISO-8859-1 lub Windows-1252.
Alan Moore
6
@Alan M: Z mojego doświadczenia wynika, że ​​o wiele łatwiej jest upewnić się, że nie będziesz mieć problemu, przechowując pliki źródłowe w ASCII, niż upewnić się, że używasz właściwego kodowania wszędzie tam, gdzie Twoje źródło może być kompilowane (Ant, Eclipse, IDEA itp.).
Jon Skeet
6
@Jon, to podstawowa wada w Javie; fakt, że jednostka źródłowa Java jest zakodowana w UTF-8, ISO 8859-1, CP1252, MacRoman lub czymkolwiek, jest traktowana jako metadane zewnętrzne w stosunku do jednostki źródłowej, która tego potrzebuje. Zmusza to do pamiętania o naprawieniu pliku ant lub konfiguracji Eclipse itp. Jak słusznie zauważyłeś, jest to absolutnie najgorszy sposób, aby to zrobić, ponieważ informacje są kruche i łatwo je utracić. Języki, które przechowują metadane (metadane kodowania) i dane (czytaj: kod źródłowy) razem w jednym miejscu, są w tym znacznie bardziej niezawodne. To jedyne rozsądne podejście.
tchrist
91

Spróbuj z: javac -encoding ISO-8859-1 nazwa_pliku.java

Fernando Nah
źródło
1
Podoba mi się to rozwiązanie. Dodałem „-encoding UTF-8” jako argument kompilatora w moim mrówkowym build.xml i nadal otrzymuję „ostrzeżenie: niemapowalny znak do kodowania ASCII”. Jeśli zmodyfikuję go na „-encoding jjjj”, nie będzie się kompilował, narzekając „błąd: nieobsługiwane kodowanie: jjjj”, więc wiem, że rozpoznaje UTF-8, ale nadal wygląda na to, że pliki .java są traktowane jako ascii. Westchnienie.
dfrankow
1
Wypróbowałem parametr „encoding” zadania ant javac, ten sam problem. Rozpoznaje parametr, ale w jakiś sposób go ignoruje.
dfrankow
20
@dfrankow: musisz dodać <compilerarg line="-encoding utf-8"/>pod odpowiednim <javac>wywołaniem w swoim Build.xmlpliku. To zły sposób, ale nie masz wyboru. Zobacz mój długi komentarz u góry.
tchrist
Miałem ten sam problem kiedy dodałem compilearg w skrypcie mrówka to działało ok, budowałem to z linii poleceń windowsa dziwne jest to że budowałem z zaćmienia to wyskoczyło bez kompilacji, wygląda na to że zaćmienie to obchodzi prawa do kodowania.
simonC
To mi pomogło :) dla MAC OSX
Arun Abraham
44

Jeśli używasz Mavena, ustaw <encoding>jawnie w konfiguracji wtyczki kompilatora, np

<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
źródło
To właściwe podejście, jeśli ludzie używają mavena do tworzenia swoich projektów, dziękuję za udostępnienie.
Shamik
2
Wtyczka javadoc będzie również narzekać na niemożliwy do odwzorowania znak. Lepiej jest ustawić project.build.sourceEncodingwłaściwość.
Emmanuel Bourg
Używałem już właściwości project.build.sourceEncoding, ale w jakiś sposób nie została ona poprawnie odwzorowana na właściwość kodowania kompilatora. Ustawienie tego jednoznacznie załatwiło sprawę
Federico Bonelli
32

Pomogło mi to:

Wszystko, co musisz zrobić, to określić zmienną środowiskową o nazwie JAVA_TOOL_OPTIONS. Jeśli ustawisz tę zmienną na -Dfile.encoding = UTF8, za każdym razem, gdy JVM zostanie uruchomiony, będzie pobierać te informacje.

Źródło: http://whatiscomingtomyhead.wordpress.com/2012/01/02/get-rid-of-unmappable-character-for-encoding-cp1252-once-and-for-all/

nightlyop
źródło
wow, to działa Po prostu dodałem to do mojego .bashrc i naprawiło to mój problem.
cowboi-peng
Działało świetnie, z wiersza poleceń wszedłem do kompilacji: javac MyJavaFile.java -encoding utf-8 -cp .;lib\*Następnie podczas uruchamiania nie musiałem dodawać tej dodatkowej części kodującej.
Azurespot
23

umieść tę linię w swoim pliku .gradle powyżej konfiguracji Java.

apply plugin: 'java'
compileJava {options.encoding = "UTF-8"}   
Aloby 5
źródło
Możesz ustawić kodowanie compileTestJavai javadocjak dobrze
Frank Neblung
8

W większości przypadków ten błąd kompilacji pojawia się podczas kompilacji pliku w formacie Unicode (zakodowanym w UTF-8)

javac -encoding UTF-8 HelloWorld.java

a także Możesz dodać tę opcję kompilacji do swojego IDE np .: Intellij idea
(Plik> ustawienia> Kompilator Java) dodaj jako dodatkowy parametr wiersza poleceń

wprowadź opis obrazu tutaj

-encoding: encoding Ustawia nazwę kodowania pliku źródłowego, na przykład EUC-JP i UTF-8 .. Jeśli -encoding nie jest określone, używany jest domyślny konwerter platformy. ( DOC )

Alupotha
źródło
8

Gradle Steps

Jeśli używasz Gradle, możesz znaleźć wiersz, który stosuje wtyczkę java:

apply plugin: 'java'

Następnie ustaw kodowanie dla zadania kompilacji na UTF-8:

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

Jeśli masz testy jednostkowe, prawdopodobnie chcesz je skompilować również z UTF-8:

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

Ogólny przykład Gradle

Oznacza to, że ogólny kod gradle wyglądałby mniej więcej tak:

apply plugin: 'java'
compileJava {options.encoding = "UTF-8"}
compileTestJava {options.encoding = "UTF-8"}
Łukasza Machowskiego
źródło
2

To zadziałało dla mnie -

    <?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
źródło
1

Jeśli używasz eclipse (Eclipse może umieścić kod utf8 za Ciebie, nawet jeśli napiszesz znak utf8. Podczas programowania zobaczysz normalny znak utf8, ale tło będzie kodem utf8);

  1. Wybierz projekt
  2. Kliknij prawym przyciskiem myszy i wybierz Właściwości
  3. Wybierz zasób w panelu zasobów (w prawym górnym rogu menu otwartego po 2.)
  4. Możesz zobaczyć w panelu zasobów , kodowanie pliku tekstowego , wybierz inne, które chcesz

PS: to będzie w porządku, jeśli masz statyczną wartość w kodzie. Na przykład Test String = "İİİİİııııııççççç";

baybora.oren
źródło
1
Twój opis „Zobaczysz normalny znak [a] utf8 podczas programowania, ale [] tło będzie kodem utf8” nie ma sensu. Zobacz także mój długi komentarz w odpowiedzi na powyższe pytanie.
tchrist
Zmieniłem go na ISO-8859-1, ale nadal otrzymywałem błąd kompilacji dotyczący „niemapowalnego znaku do kodowania UTF8”.
pacoverflow,
1

Miałem ten sam problem, gdzie indeks znaków zgłoszony w komunikacie o błędzie java był niepoprawny. Zawęziłem to do znaków podwójnego cudzysłowu tuż przed zgłoszoną pozycją szesnastkową 094 (anuluj zamiast cudzysłowu, ale przedstawioną jako cudzysłów) zamiast szesnastkowego 022. Jak tylko zamieniłem wariant szesnastkowy 022, wszystko było w porządku.

Kelvin Goodson
źródło
1

Jeśli używasz Maven Build z wiersza poleceń, możesz również użyć następującego polecenia:

                    mvn -Dproject.build.sourceEncoding=UTF-8
5122014009
źródło
1

Dla tych, którzy zastanawiają się, dlaczego tak się dzieje w niektórych systemach, a nie w innych (z tym samym źródłem, parametrami kompilacji itd.), Sprawdź swoją LANGzmienną środowiskową . Otrzymuję ostrzeżenie / błąd kiedy LANG=C.UTF-8, ale nie kiedy LANG=en_US.UTF-8.

jakar
źródło