50

I've recently had to switch encoding of webapp I'm working on from ISO-xx to utf8. Everything went smooth, except properties files. I added -Dfile.encoding=UTF-8 in eclipse.ini and normal files work fine. Properties however show some strange behaviour.

If I copy utf8 encoded properties from Notepad++ and paste them in Eclipse, they show and work fine. When I reopen properties file, I see some Unicode characters instead of proper ones, like:

Zur\u00EF\u00BF\u00BDck instead of Zurück

but app still works fine. If I start to edit properties, add some special characters and save, they display correctly, however they don't work and all previously working special characters don't work any more.

When I compare local version with CVS I can see special characters correctly on remote file and after update I'm at start again: app works, but Eclipse displays Unicode chars.

I tried changing file encoding by right clicking it and selecting „Other: UTF8” but it didn't help. It also said: „determined from content: ISO-8859-1”

I'm using Java 6 and Jboss Developer based on Eclipse 3.3

I can live with it by editing properties in Notepad++ and pasting them in Eclipse, but I would be grateful if someone could help me with fixing this in Eclipse.

BuZZ-dEE
  • 6,075
  • 12
  • 66
  • 96
TJL
  • 6,330
  • 8
  • 34
  • 36

13 Answers13

69

Answer for "pre-Java-9" is below. As of Java 9, properties files are saved and loaded in UTF-8 by default, but falling back to ISO-8859-1 if an invalid UTF-8 byte sequence is detected. See the Java 9 release notes for details.


Properties files are ISO-8859-1 by definition - see the docs for the Properties class.

Spring has a replacement which can load with a specified encoding, using PropertiesFactoryBean.

EDIT: As Laurence noted in the comments, Java 1.6 introduced overloads for load and store which take a Reader/Writer. This means you can create a reader for the file with whatever encoding you want, and pass it to load. Unfortunately FileReader still doesn't let you specify the encoding in the constructor (aargh) so you'll be stuck with chaining FileInputStream and InputStreamReader together. However, it'll work.

For example, to read a file using UTF-8:

Properties properties = new Properties();
InputStream inputStream = new FileInputStream("path/to/file");
try {
    Reader reader = new InputStreamReader(inputStream, "UTF-8");
    try {
        properties.load(reader);
    } finally {
        reader.close();
    }
} finally {
   inputStream.close();
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 5
    In Java 1.6 you can use other encodings by using the methods that use Reader/Writer instead of InputStream/OutputStream. – Laurence Gonsalves May 14 '09 at 15:10
  • A more general solution than the one in the accepted answer, therefore better :) – Radu Murzea Feb 02 '13 at 19:28
  • @JonSkeet I have been working on this problem for weeks. Thank you so much! – Fering Mar 18 '19 at 18:37
  • As of Java 9+, properties files should be encoded in UTF-8: https://docs.oracle.com/javase/9/intl/internationalization-enhancements-jdk-9.htm#JSINT-GUID-974CF488-23E8-4963-A322-82006A7A14C7 – Rune Aamodt Oct 22 '20 at 10:01
  • 1
    @RuneAamodt: Although I'm glad to see ISO-8859-1 is still supported when reading. Will update my answer. – Jon Skeet Oct 22 '20 at 10:14
54

Don't waste your time, you can use Resource Bundle plugin in Eclipse

Basic Screen Shot

Old Sourceforge page

BuZZ-dEE
  • 6,075
  • 12
  • 66
  • 96
bora.oren
  • 3,439
  • 3
  • 33
  • 31
  • 3
    This is a hugely useful plugin, thanks for the tip! So bad it does not have an install URL, but just dropping it on the plugins folder does the trick. – chesterbr Jan 07 '10 at 04:43
  • 3
    Does this use the native2ascii tool for non-unicode characters internally or I should manually escape unicode symbols? – Ivaylo Slavov Nov 21 '11 at 12:05
  • @baybora.oren: I expanded the .zip in the eclipse folder plugin, but I don't see any change in the ide (I shutdown and restart eclipse). Any hint? – Sefran2 Jun 11 '14 at 15:17
  • @cricket check eclipse version maybe it is not compatible with that eclipse you use – bora.oren Jul 03 '14 at 12:08
12

It is not a problem with Eclipse. If you are using the Properties class to read and store the properties file, the class will escape all special characters.

From the class documentation:

When saving properties to a stream or loading them from a stream, the ISO 8859-1 character encoding is used. For characters that cannot be directly represented in this encoding, Unicode escapes are used; however, only a single 'u' character is allowed in an escape sequence. The native2ascii tool can be used to convert property files to and from other character encodings.

From the API, store() method:

Characters less than \u0020 and characters greater than \u007E are written as \uxxxx for the appropriate hexadecimal value xxxx.

Mario Ortegón
  • 18,670
  • 17
  • 71
  • 81
  • 4
    NetBeans nicely displays properties files that have \uXXXX escapes and lets you edit them with UTF characters properly displayed. Why doesn't Eclipse? In my opinion this _is_ a problem with Eclipse. – Chrissi Feb 19 '14 at 14:22
  • +1: the so quantum of solace for having been skeet'd – rexford Sep 22 '14 at 13:03
11
Properties props = new Properties();
URL resource = getClass().getClassLoader().getResource("data.properties");         
props.load(new InputStreamReader(resource.openStream(), "UTF8"));

Works like a charm

:-)

  • Unfortunately props.load, in 1.6, requires an InputStream and specifically indicates it expects old-school ISO-8859-1 –  Oct 09 '11 at 15:35
4

There is much easier way:

props.load(new InputStreamReader(new FileInputStream("properties_file"), "UTF8"));
4
Properties props = new Properties();
URL resource = getClass().getClassLoader().getResource("data.properties");         
props.load(new InputStreamReader(resource.openStream(), "UTF8"));

this works well in java 1.6. How can i do this in 1.5, Since Properties class does not have a method to pars InputStreamReader.

Grzegorz Rożniecki
  • 27,415
  • 11
  • 90
  • 112
Hirantha
  • 41
  • 1
4

There are too many points in the process you describe where errors can occur, so I won't try to guess what you're doing wrong, but I think I know what's happening under the hood.

EF BF BD is the UTF-8 encoded form of U+FFFD, the standard replacement character that's inserted by decoders when they encounter malformed input. It sounds like your text is being saved as ISO-8859-1, then read as if it were UTF-8, then saved as UTF-8, then converted to the Properties format using native2ascii using the platform default encoding (e.g., windows-1252).

ü              => 0xFC                // save as ISO-8859-1
0xFC           => U+FFFD              // read as UTF-8
U+FFFD         => 0xEF 0xBF 0xBD      // save as UTF-8
0xEF 0xBF 0xBD => \u00EF\u00BF\u00BD  // native2ascii

I suggest you leave the "file.encoding" property alone. Like "file.separator" and "line.separator", it's not nearly as useful as you would expect it to be. Instead, get into the habit of always specifying an encoding when reading and writing text files.

Alan Moore
  • 73,866
  • 12
  • 100
  • 156
3

You can define UTF-8 .properties files to store your translations and use ResourceBundle, to get values. To avoid problems you can change encoding:

String value = RESOURCE_BUNDLE.getString(key); 
return new String(value.getBytes("ISO-8859-1"), "UTF-8");
gopeca
  • 1,601
  • 12
  • 12
3

Just another Eclipse plugin for *.properties files:

Properties Editor

btpka3
  • 3,720
  • 2
  • 23
  • 26
1

This seems to work only for some characters ... including special characters for German, Portuguese, French. However, I ran into trouble with Russian, Hindi and Mandarin characters. These are not converted to Properties format 'native2ascii', instead get saved with ?? ?? ??
The only way I could get my app to display these characters correctly is by putting them in the properties file translated to UTF-8 format - as \u0915 instead of क, or \u044F instead of я. Any advice?

  • You could use Spring's org.springframework.context.support.ReloadableResourceBundleMessageSource which supports UTF-8 encoded property files. We use Spring to manage translations in English, German, French and Chinese in spring-mvc based web applications. – rexford Sep 22 '14 at 13:11
1

I recommend you to use Attesoro (http://attesoro.org/). Is simple and easy to use. And is made in java.

htobon
  • 163
  • 1
  • 7
0

I found a solution to this problem. You need to write file (*.properties) use standard "Properties", example:

Properties properties = new Properties();
properties.put("DB_DRIVER", "com.mysql.cj.jdbc.Driver");
    properties.put("DB_URL", "jdbc:mysql://localhost:3306/world");
    properties.put("DB_USERNAME", "root");
    properties.put("DB_PASSWORD", "1111");
    properties.put("DB_AUTO_RECONNECT", "true");
    properties.put("DB_CHARACTER_ENCODING", "UTF-8");
    properties.put("DB_USE_UNICODE", "true");
    
    
    try {
        properties.store(new FileWriter("src/connectionDB/base/db.properties"), "Comment writes");
    } catch (IOException e) {
        System.out.println(e.getMessage());
    }

then, you can read file without mistakes:

try {           
        properties.load(new FileReader("src\\connectionDB\\base\\db.properties"));          
        properties.list(System.out);
    } catch (IOException ex) {
        System.out.println(ex.getMessage());
    }   

or

        try {
        String str = new String(Files.readAllBytes(Paths.get("src/connectionDB/base/db.properties")), StandardCharsets.UTF_8);
        properties.load(new StringReader(str));
        properties.list(System.out);
    } catch (IOException e) {
        System.out.println(e.getMessage());
    }

or

    InputStream inputStream = getClass().getClassLoader().getResourceAsStream("connectionDB/base/db.properties");
    try {
        Reader reader = new InputStreamReader(inputStream, "UTF-8");
        try {           
            properties.load(reader);
            properties.list(System.out);
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    } catch (UnsupportedEncodingException e1) {
        // TODO Auto-generated catch block
        e1.printStackTrace();
    }

never mind.... then close the code that creates this file and use file *.properties

  • your answer looks good, but the text explaining the solution is not clear enough. Can you rephrase it so that the text is easier to understand? – stefan.m Jan 04 '23 at 12:56
-1

If the properties are for XML or HTML, it's safest to use XML entities. They're uglier to read, but it means that the properties file can be treated as straight ASCII, so nothing will get mangled.

Note that HTML has entities that XML doesn't, so I keep it safe by using straight XML: http://www.w3.org/TR/html4/sgml/entities.html

David Leppik
  • 3,194
  • 29
  • 18