Aviso de “caractere não mapeável para codificação” em Java

112

Atualmente, estou trabalhando em um projeto Java que emite o seguinte aviso ao compilar:

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

Não tenho certeza de como o SO renderizará o caractere antes da data, mas deve ser um símbolo de copyright e é exibido no aviso como um ponto de interrogação em um losango.

É importante notar que o caractere aparece no artefato de saída corretamente, mas os avisos são um incômodo e o arquivo que contém esta classe pode um dia ser alterado por um editor de texto que salva a codificação incorretamente ...

Como posso injetar esse caractere na string de "direitos autorais" para que o compilador fique satisfeito e o símbolo seja preservado no arquivo sem possíveis problemas de recodificação?

Seanhodges
fonte
esteja interessado em saber quais bytes compõem esse caractere de copyright, ou seja hexdump AppDBCore.java, de alguma forma duvido \u00a9disso e, em vez disso, é algo que funciona parcialmente para você por causa da configuração do sistema. O ponto de interrogação acima é usado para substituir um caractere de entrada cujo valor é desconhecido ou não representável em Unicode hexutf8.com/…
jar

Respostas:

56

Use o formato de escape "\ uxxxx".

De acordo com a Wikipedia , o símbolo de direitos autorais é unicode U + 00A9, portanto, sua linha deve ser:

String copyright = "\u00a9 2003-2008 My Company. All rights reserved.";
Jon Skeet
fonte
13
Cuidado com \ uNNNN caracteres ... eles são analisados ​​antes de fazer a análise lexical. Por exemplo, se você colocar este comentário / * c: \ unit * / em seu código, ele não irá mais compilar, porque "nit" não é o número hexadecimal correto.
Peter Štibraný
3
Absolutamente. (Isso é melhor tratado em C #, onde o escape de unicode só é aplicado em certos contextos - mas também existe a perigosa sequência de escape \ x, que é horrível.)
Jon Skeet
5
Isso soa mais como um band-aid do que uma cura. O verdadeiro problema parece ser que você está dizendo ao javac para esperar os arquivos de origem em UTF-8 quando, na verdade, eles estão em uma codificação de byte único como ISO-8859-1 ou windows-1252.
Alan Moore
6
@Alan M: Na minha experiência, é muito mais fácil ter certeza de que você não terá problemas em manter os arquivos de origem em ASCII do que usar a codificação correta em todos os lugares em que sua origem for compilada (Ant, Eclipse, IDÉIA etc).
Jon Skeet
6
@Jon, essa é uma falha fundamental em Java; o fato de a unidade de origem Java ser codificada em UTF-8, ISO 8859-1, CP1252, MacRoman ou qualquer outro, é tratado em metadados externos à unidade de origem que precisa deles. Isso força você a se lembrar de consertar seu arquivo Ant ou configuração do Eclipse, etc. Como você corretamente apontou, esta é absolutamente a pior maneira de fazer isso, porque a informação é frágil e facilmente perdida. Linguagens que mantêm os metadados (metadados de codificação) e os dados (leia-se: código-fonte) juntos em um só lugar são muito mais robustas nisso. É a única abordagem sensata.
tchrist
91

Tente com: javac -encoding ISO-8859-1 file_name.java

Fernando Nah
fonte
1
Eu gosto dessa solução. Eu adicionei "-encoding UTF-8" como um compilador no meu ant build.xml e ainda recebo "aviso: caractere não mapeável para codificação ASCII". Se eu modificá-lo para "-encoding jjjj", ele não compilará, reclamando "erro: codificação não suportada: jjjj", então sei que ele está reconhecendo UTF-8, mas ainda parece que os arquivos .java são tratados como ascii. Suspiro.
dfrankow
1
Tentei o parâmetro "encoding" da tarefa ant javac, mesmo problema. Ele reconhece o parâmetro, mas então o ignora de alguma forma.
dfrankow
20
@dfrankow: você deve adicionar <compilerarg line="-encoding utf-8"/>sob a <javac>chamada aplicável em seu Build.xmlarquivo. Esta é uma maneira ruim de fazer isso, mas você não tem escolha. Veja meu longo comentário no topo.
tchrist
Eu tive o mesmo problema quando adicionei o compilearg no script de formiga e funcionou ok, eu estava construindo isso a partir de uma linha de comando do windows, o estranho é que eu estava construindo a partir do eclipse ele avariou sem a compilação, parece que aquele eclipse que se importa da codificação certa.
simonC
Isso me ajudou :) para MAC OSX
Arun Abraham
44

Se você estiver usando o Maven, defina <encoding>explicitamente na configuração do plug-in do compilador, por exemplo

<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
fonte
Esta é a abordagem certa se as pessoas estão usando o maven para construir seu projeto, obrigado por compartilhar.
Shamik
2
O plugin javadoc também reclamará do caractere não mapeável. É preferível definir a project.build.sourceEncodingpropriedade.
Emmanuel Bourg
Eu já estava usando a propriedade project.build.sourceEncoding, mas de alguma forma ela não foi mapeada corretamente na propriedade de codificação do compilador. Configurá-lo explicitamente funcionou
Federico Bonelli,
32

Isso me ajudou:

Tudo que você precisa fazer é especificar uma variável de ambiente chamada JAVA_TOOL_OPTIONS. Se você definir essa variável como -Dfile.encoding = UTF8, toda vez que uma JVM for iniciada, ela coletará essas informações.

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

noite
fonte
uau, funciona. Acabei de adicionar isso ao meu .bashrc e resolvi meu problema.
cowboi-peng
Funcionou muito bem, a partir da linha de comando entrei para construir: javac MyJavaFile.java -encoding utf-8 -cp .;lib\*Então, ao executá-lo, não precisei adicionar aquela parte extra de codificação.
Azurespot
23

coloque esta linha no seu arquivo .gradle acima do Java conf.

apply plugin: 'java'
compileJava {options.encoding = "UTF-8"}   
Alobes5
fonte
Você pode querer definir a codificação para compileTestJavae para javadoctambém
Frank Neblung
8

Na maioria das vezes, esse erro de compilação ocorre durante a compilação de arquivos Unicode (codificado em UTF-8)

javac -encoding UTF-8 HelloWorld.java

e também você pode adicionar esta opção de compilação ao seu IDE ex: Intellij idea
(Arquivo> configurações> Compilador Java) adicionar como parâmetro de linha de comando adicional

insira a descrição da imagem aqui

-encoding: encoding Defina o nome da codificação do arquivo de origem, como EUC-JP e UTF-8. Se -encoding não for especificado, o conversor padrão da plataforma será usado. ( DOC )

Alupotha
fonte
8

Gradle Steps

Se você estiver usando o Gradle, poderá encontrar a linha que aplica o plug-in java:

apply plugin: 'java'

Em seguida, defina a codificação da tarefa de compilação como UTF-8:

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

Se você tiver testes de unidade, provavelmente também deseja compilá-los com UTF-8:

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

Exemplo geral do Gradle

Isso significa que o código geral do Gradle seria mais ou menos assim:

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

Isso funcionou para mim -

    <?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
fonte
1

Se você usar o eclipse (o Eclipse pode colocar o código utf8 para você mesmo que você escreva o caractere utf8. Você verá o caractere utf8 normal ao programar, mas o plano de fundo será o código utf8);

  1. Selecione o Projeto
  2. Clique com o botão direito e selecione Propriedades
  3. Selecione Recurso no Painel de Recursos (parte superior do menu direito que é aberto após 2.)
  4. Você pode ver no Painel de Recursos , Codificação de Arquivo de Texto , selecione outro que você deseja

PS: isso vai funcionar se você valorar estático no código. Por exemplo String test = "İİİİİıııııııçççççç";

baybora.oren
fonte
1
Sua descrição de “Você verá o caractere normal [a] utf8 quando [estiver] programando, mas [o] plano de fundo será o código utf8” não faz sentido. Além disso, veja meu longo comentário em resposta à pergunta acima.
tchrist de
Eu mudei para ISO-8859-1, mas ainda recebo um erro de compilação sobre "caractere não mapeável para codificação UTF8".
pacoverflow
1

Eu tive o mesmo problema, onde o índice de caracteres relatado na mensagem de erro java estava incorreto. Eu reduzi para os caracteres de aspas duplas antes de a posição relatada ser hex 094 (cancelar em vez de aspas, mas representado como uma aspa) em vez de hex 022. Assim que troquei pela variante hex 022, tudo estava bem.

Kelvin Goodson
fonte
1

Se estiver usando o Maven Build a partir do prompt de comando, também poderá usar o seguinte comando:

                    mvn -Dproject.build.sourceEncoding=UTF-8
5122014009
fonte
1

Para aqueles que estão se perguntando por que isso acontece em alguns sistemas e não em outros (com a mesma fonte, parâmetros de construção e assim por diante), verifique sua LANGvariável de ambiente . Recebo o aviso / erro quando LANG=C.UTF-8, mas não quando LANG=en_US.UTF-8.

Jacar
fonte