Java char 'ß' in Gradle produces compiler error

Viewed 149

I just played a bit around with chars and found this problem. Here is the code:

public static void main(String[] args) {
    System.out.println("aß".toUpperCase(Locale.ROOT));
    System.out.println("ẞ");
    System.out.println("ẞ".equals("ß".toUpperCase()));
    System.out.println(Character.toUpperCase('ß'));
    System.out.println('ß');
}

Running this results in this error:

> Task :compileJava FAILED
1 actionable task: 1 executed
Main.java:45: error: unclosed character literal
        System.out.println(Character.toUpperCase('ß'));
                                                 ^
Main.java:45: error: unclosed character literal
        System.out.println(Character.toUpperCase('ß'));
                                                    ^
Main.java:45: error: not a statement
        System.out.println(Character.toUpperCase('ß'));
                                                   ^
Main.java:46: error: unclosed character literal
        System.out.println('ß');
                           ^
Main.java:46: error: unclosed character literal
        System.out.println('ß');
                              ^
Main.java:46: error: not a statement
        System.out.println('ß');
                             ^

Why is it like this? I'm using Java 16 and Gradle 7.0. And how to workaround it? I tried to achieve a way, that toUppercase() of ß returns ẞ.

I just figured out something:

public static void main(String[] args) {
    System.out.println("aß".toUpperCase(Locale.ROOT));
    System.out.println("ẞ");
    System.out.println("ẞ".equals("ß".toUpperCase()));
//  System.out.println(Character.toUpperCase('ß'));
//  System.out.println('ß');
    System.out.println("ß".toCharArray());
    System.out.println("ẞ".toCharArray());
    System.out.println("ß".toCharArray()[1]);
    System.out.println("ẞ".toCharArray()[0]);
}

This actually compiles:

Aß
ẞ
false
ß
ẞ
�
�

Even though IntelliJ warns me, that"ß".toCharArray()[1] will definitely throw an ArrayIndexOutOfBoundsException...

Its kinda strange, that "ß" and "ẞ" are each stored as two characters internal apparently. Is this intended? And if it is, why is it like this? Same problem with 'ä' 'ö' and 'ü' for example. The toCharArray()-Method returns a 2-Char-array for each letter. But according to the comments, this works on other PCs with the char literal. Am i missing something? Maybe System.out uses UTF-8 and the letters need 2 bytes to display?

I figured out something new. Since System.getProperty("file.encoding") returns windows-1252, I started thinking it's maybe that that causes the problem. So I added in the build.gradle this:

compileJava.options.encoding = "UTF-8"
compileTestJava.options.encoding = "UTF-8"

Then I changed the Main:

    System.out.println(System.getProperty("file.encoding"));
    System.setOut(new PrintStream(System.out, true, StandardCharsets.UTF_8));
    System.out.println("aß".toUpperCase(Locale.ROOT));
    System.out.println("ẞ");
    System.out.println("ẞ".equals("ß".toUpperCase()));
    System.out.println(Character.toUpperCase('ß'));
    System.out.println('ß');
    System.out.println("ß".toCharArray());
    System.out.println("ẞ".toCharArray());
    System.out.println("ß".toCharArray()[1]);
    System.out.println("ẞ".toCharArray()[0]);

Output is:

windows-1252
ASS
ẞ
false
ß
ß
ß
ẞ

So apparently that works at compiletime (after that output I get an AIOOB), however that didn't change the file.encoding. I would need to add the JVM.Arg every time I start. That doesn't sound how it should work. Without the Arg I need the second line, else the output is still trash. So if I add in the build.gradle the 2 compile encodings and the JVM-Arg, it compiles at least like it should.

But the original problem was, I wanted a method to change ß to ẞ without my own method, but I think that won't work.

So it's just a Windows-1252 problem?

0 Answers
Related