Menu

#125 Add Japanese Windows support

None
closed
nobody
None
5
2019-05-18
2010-05-11
No

This is a feature request for Japanese Windows support. Attached is a patch that implements this support.

There are two files in the patch. The first is the standard translated DNSServer.properties file (DNSServer_ja.properties). The second is an altered version of the ResolverConfig class.

A bit of explanation regarding the source code change. In the case of Japanese Windows, simply having the translated messages file is not sufficient. The reason is that in Japanese Windows NT, Windows XP, and Windows Server 2003 the output of the "ipconfig" command is in English. However, in Japanese Windows Vista, Windows Server 2008, and Windows 7 the output of the "ipconfig" command is in Japanese (kanji).

The original ResolverConfig class loads the DNSServer.properties localized file, and uses the strings inside to match/parse the output of the "ipconfig" command. This works for newer versions of Japanese Windows, where the output is Japanese, but fails for NT/XP/2003 because the strings don't match. The change mode to ResolverConfig is to first attempt to parse the output of "ipconfig" using the localized messages, but if that fails it will now fallback to the root bundle (English). This seems like a good idea anyway. In the case of Japanese (and probably other Asian languages), this new behavior should cover all versions of Windows.

Discussion

  • Brett Wooldridge

    Japanese language support patch

     
  • Brian Wellington

    The patch uses Locale.ROOT, which was added in Java 6; dnsjava only requires Java 1.4. The patch also duplicates code, which seems suboptimal.

    I'm attaching an alternate patch to ResolverConfig, which I think will work, but I have no way to test it.

     
  • Brian Wellington

    ResolverConfig patch

     
  • Brett Wooldridge

    The patch doesn't work because the BufferedInputStream is not resettable. The stream in question comes from a Process invocation and therefore does not support mark or reset. An exception is thrown.

    That is why the original patch reads from InputStream and writes into a ByteArrayOutputStream. The ByteArrayOutputStream's bytes are then used to create two [ByteArray]InputStream's to feed into the parsing (twice if necessary).

     
  • Brett Wooldridge

    There is also an issue with specifying Locale.US in the second patch. Because there is no DNSServer_en_US.properties file, Java falls back to the "local" bundle -- again getting the Japanese bundle. The fix for this would be to add the aforementioned DNSServer_en_US.properties file. Barring Java 6 and Locale.ROOT there is no other way around it.

     
  • Brian Wellington

    I'm confused. The BufferedInputStream class is documented as "A BufferedInputStream adds functionality to another input stream-namely, the ability to buffer the input and to support the mark and reset methods.", which is exactly what it's being used for. At least that's what it's supposed to be doing, but the patch is incorrectly calling mark() and reset() on the wrong stream. Does it work if you change those calls to be on the correct stream?

    As for Locale.US, it seemed to work for me, but it could be platform specific. Does using new Locale("", "") instead work? It's more or less how Locale.ROOT is defined.

     
  • Brett Wooldridge

    Three things.

    1. Marking and resetting the BufferedInputStream works. Almost. In your patch the reset() will still throw an exception because the stream is being closed in the finally block of findWin() during the first invocation.

    2. Constructing new Locale("", "") works. The ResourceBundle is able to load the root bundle in that case.

    3. The default buffer size of BufferedInputStream is 8k (8192 bytes). If the output of "ipconfig" is larger than that, the stream cannot be properly reset for a second pass parse. For most cases one would think 8k would be sufficient, but with the growing popularity of virtualization, not quite so. We have a machine with 256 virtual interfaces. On that machine, "ipconfig /all" returns about 80k of data. I don't know what a "safe" default is, but maybe try 96k (98304 bytes). Or better, I would recommend using a System property to control the size. Something like:

    new BufferedInputStream(in, Integer.getInteger("org.xbill.DNS.windows.parse.buffer", 8192);

    If the property is present it will be parsed (as an int), if not defined or not an integer, 8192 will be used.

     
  • Brett Wooldridge

    Minor correction for JDK 1.4.

    new BufferedInputStream(in,
    Integer.getInteger("org.xbill.DNS.windows.parse.buffer", 8192);

    Should be:
    new BufferedInputStream(in,
    Integer.getInteger("org.xbill.DNS.windows.parse.buffer", 8192).intValue());

    The former relies on auto-boxing (unboxing). The later works in 1.4+.

     
  • Brian Wellington

    Attaching a new patch. This removes the close in findWin, which shouldn't be needed anyway (as garbage collection will handle it), and adds a size parameter (I used 128K) to the BufferedInputStream constructor.

    If this works, I'll commit the changes.

     
  • Brian Wellington

    ResolverConfig patch, 2nd version

     
  • Brett Wooldridge

    The patch works.

    The only reason I think 8K is actually a better default is that some user's might use dnsjava in memory constrained applications. For most purposes even 8K is overkill, it's just on Windows systems with a large number of interfaces that presents a problem. For example, on my Windows desktop, the output of ipconfig is less than 512 bytes. Still, 8K seems a reasonable default that would work for 99.9% of user's.

     
  • Brian Wellington

    Committed, with the default changed to 8K.

     
  • Brian Wellington

    • status: open --> closed
     
  • Ingo

    Ingo - 2019-05-18

    Ticket moved from /p/dnsjava/feature-requests/15/