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

operating with java method, the result string is garbled(encoding error) #718

Closed
RekaDowney opened this issue Apr 3, 2023 · 2 comments
Closed

Comments

@RekaDowney
Copy link

RekaDowney commented Apr 3, 2023

Graal Version

openjdk version "19.0.2" 2023-01-17
OpenJDK Runtime Environment GraalVM CE 22.3.1 (build 19.0.2+7-jvmci-22.3-b12)
OpenJDK 64-Bit Server VM GraalVM CE 22.3.1 (build 19.0.2+7-jvmci-22.3-b12, mixed mode, sharing)

image

Describe the issue

When evalling java method in js script, the result string encoding error.(UTF-8)
I'm sure all files are UTF8 charset encoded.

Code snippet

@Data
@NoArgsConstructor
@AllArgsConstructor
@Accessors(chain = true)
public class RegisterUserReq {

    private String name;
    private String password;

}

public class UserService {

    public static String register(RegisterUserReq req) {
        return """
                用户:%s
                密码:%s
                """.formatted(req.getName(), req.getPassword());
    }

}
public class TestGraal {

    final Predicate<String> hostClassLookup = className -> !className.startsWith("java.io")
            && !className.startsWith("java.nio")
            && !className.startsWith("java.net")
            && !System.class.getName().equals(className)
            && !Runtime.class.getName().equals(className);

    @Test
    public void testMethodObjectParam() throws Exception {
        try (Context ctx = Context.newBuilder("js")
                .allowHostAccess(HostAccess.ALL)
                .allowHostClassLookup(hostClassLookup)
                .allowIO(false)
                // even adding the following 2 lines has no effect.
                // .allowExperimentalOptions(true)
                // .option("js.charset", "UTF-8")
                .engine(Engine.newBuilder().build())
                .build()) {
            final String script = """
                    var UserService = Java.type('com.comp.UserService');
                    var RegisterUserReq = Java.type('com.comp.RegisterUserReq');
                    var req = new RegisterUserReq();
                    req.setName("Reka");
                    req.setPassword("123456");
                    UserService.register(req);
                    """;
            final Source source = Source.newBuilder("js", script, "InvokeJava")
                    .encoding(StandardCharsets.UTF_8)
                    .buildLiteral();
            final Value register = ctx.eval(source);
            System.out.println(register.asString());
        }
    }

}

Expected behavior

Expected:

用户:Reka
密码:123456

Actual:
image

@RekaDowney RekaDowney changed the title eval operating with java method, the result string is garbled(encoding error) Apr 3, 2023
@iamstolis
Copy link
Member

I am sorry, I am not able to reproduce this issue. I see the expected output. Have you tried to set name and password properties of RegisterUserReq (and print the output of UserService.register()) using pure Java (i.e. without the usage of JavaScript)? Does it print the expected output or is it garbled as well? I am curious if the issue is really caused by GraalVM or whether it is some issue of the tool that you use to display the test results.

@RekaDowney
Copy link
Author

RekaDowney commented Apr 4, 2023

@iamstolis Oh, thank you for reminding me, I quickly checked the breakpoint and found that the code was indeed correct during execution, but the output was garbled.
image

Then I looked at all the encoding configurations of IDEA and found that they were all UTF-8. I tried to add -Dfile.encoding=UTF-8 and -Dconsole.encoding=UTF-8 VM options for IDEA, but it was useless at all, whether restart IDEA or restart the computer.
image

Just when I was frustrated, I thought about whether System.out had changed, and found that charset had indeed changed (it did not use the charset specified by -Dfile.encoding, but followed the default charset of the operating system) . I then changed the charset via the System.setOut method and it finally worked.
image

Finally, I continued to search and found that this is a bug of JDK19. The official provides a new -Dstdout.encoding=UTF-8 property to control the charset of System.out. See here.

Thanks :)

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

No branches or pull requests

2 participants