Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UnsupportedEncodingException when running native-image generated binary #1370

Closed
hiroSzymon opened this issue Jun 10, 2019 · 5 comments
Closed
Assignees

Comments

@hiroSzymon
Copy link

Initial conditions:

  • Simple app where "new String(byte[] bytes, String charsetName)" [encoding = "ISO-8859-2"] compiled to native image both on Windows and Linux

Result:

  • java.io.UnsupportedEncodingException: ISO-8859-2
    at java.lang.StringCoding.decode(StringCoding.java:190)
    at java.lang.String.(String.java:426)
    at java.lang.String.(String.java:491)

App run with graalvm or openjdk works without any issues.
Changing case of "ISO" does not make any difference.
App source code in attachment.

Main.java.txt

@SergejIsbrecht
Copy link

SergejIsbrecht commented Jun 10, 2019

Looks like Charset cs = lookupCharset(csn) is null. Probably not all characters are included in the native-image generation:

static char[] decode(String charsetName, byte[] ba, int off, int len)
        throws UnsupportedEncodingException
    {
        StringDecoder sd = deref(decoder);
        String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;
        if ((sd == null) || !(csn.equals(sd.requestedCharsetName())
                              || csn.equals(sd.charsetName()))) {
            sd = null;
            try {
                Charset cs = lookupCharset(csn);
                if (cs != null)
                    sd = new StringDecoder(cs, csn);
            } catch (IllegalCharsetNameException x) {}
            if (sd == null)
                throw new UnsupportedEncodingException(csn); // line 190
            set(decoder, sd);
        }
        return sd.decode(ba, off, len);
    }

Substition

   @Substitute
    private static Charset lookup(String charsetName) {
        if (charsetName == null) {
            throw new IllegalArgumentException("Null charset name");
        }

        Map<String, Charset> charsets = ImageSingletons.lookup(LocalizationSupport.class).charsets;
        Charset result = charsets.get(charsetName.toLowerCase());

        if (result == null) {
            /* Only need to check the name if we didn't find a charset for it */
            checkName(charsetName);
        }
        return result;
    }

How to resolve the issue?
sergej@sergej-P50:~/Downloads$ native-image -H:+AddAllCharsets -cp . Main

Build on Server(pid: 26550, port: 36657)*
[main:26550]    classlist:   1,200.97 ms
[main:26550]        (cap):   1,085.48 ms
[main:26550]        setup:   2,152.92 ms
[main:26550]   (typeflow):   4,810.21 ms
[main:26550]    (objects):   2,286.15 ms
[main:26550]   (features):     154.27 ms
[main:26550]     analysis:   7,350.01 ms
[main:26550]     (clinit):     115.11 ms
[main:26550]     universe:     325.06 ms
[main:26550]      (parse):     557.86 ms
[main:26550]     (inline):   1,206.99 ms
[main:26550]    (compile):   4,398.51 ms
[main:26550]      compile:   6,491.95 ms
[main:26550]        image:   1,026.68 ms
[main:26550]        write:     105.20 ms
[main:26550]      [total]:  18,775.84 ms

Result:

sergej@sergej-P50:~/Downloads$ ./main 
AA

Tested on Linux sergej-P50 4.18.0-18-generic #19-Ubuntu SMP Tue Apr 2 18:13:16 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux with

sergej@sergej-P50:~/Downloads$ native-image --version
GraalVM Version 19.0.0 CE

@cstancu cstancu self-assigned this Jun 10, 2019
@hiroSzymon
Copy link
Author

hiroSzymon commented Jun 11, 2019

@SergejIsbrecht Your solution works flawlessly, thanks. However, I found another problem. LocalDate.now() returns 1970-01-01. I don't think it's somehow related to this issue, so should I open another one?
EDIT:
I dug further into the code, and found out, that the LocalDate issue is valid only on Windows, because of value returned by System.currentTimeMillis().

@SergejIsbrecht
Copy link

Please open a new issue. At first it sounded you used #currentTimeMillis in the static class init block. But if its only on widows it is probably a bug.

@christianwimmer
Copy link

Windows is not supported yet. There are many things that are not implemented yet for Windows, and we are actively working on it.

@cstancu
Copy link
Member

cstancu commented Aug 29, 2019

@SergejIsbrecht thanks for the suggestion. I am closing this issue since using the -H:+AddAllCharsets option fixes the originally reported problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants