oracle / graal

GraalVM compiles Java applications into native executables that start instantly, scale fast, and use fewer compute resources πŸš€
https://www.graalvm.org
Other
20.44k stars 1.64k forks source link

[GR-60169][Native Image] AWT component `MenuItem` shows wrong characters. #9816

Open hyranno opened 1 month ago

hyranno commented 1 month ago

Describe the Issue

Running built native image on Windows, AWT component MenuItem shows wrong characters. MenuItem on SystemTray PopupMenu shows characters with inverted byte order. Other OSs or AWT components are unverified.

Using the latest version of GraalVM can resolve many issues.

GraalVM Version

OpenJDK Runtime Environment GraalVM CE 21.0.2+13.1 (build 21.0.2+13-jvmci-23.1-b30)

Operating System and Version

Windows 22H2 (19045.4894)

Diagnostic Flag Confirmation

Run Command

javac -d ./java ./Reproduce.java
java -agentlib:native-image-agent=config-output-dir=./java/META-INF/native-image -cp ./java ./Reproduce.java
cp ./native-image.properties ./java/META-INF/native-image
cd ./java
jar -c -f ./Reproduce.jar -e Reproduce -C ./ .
cd ..
mkdir native
native-image -jar ./java/Reproduce.jar ./native/Reproduce
cp -r ./java_home ./native
./native/Reproduce.exe

Expected Behavior

AWT MenuItem on SystemTray PopupMenu shows "Reproduce"

Actual Behavior

AWT MenuItem on SystemTray PopupMenu shows "εˆ€ζ”€η€€ηˆ€ζΌ€ζ€η”€ζŒ€ζ”€". Each character has inverted byte order of UTF-16 "Reproduce". actuall

Steps to Reproduce

Put files in current directory :

Reproduce.java
native-image.properties
java_home/conf/fonts/fontconfig.properties

Reproduce.java

import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.nio.file.Path;

public class Reproduce extends Frame {
  public static void main(String [] args) {
    new Reproduce();
  }
  Reproduce() {
    super("Reproduce");
    setJavaHome();
    setSize(400, 100);
    addWindowListener(new SimpleWindowAdapter());
    setVisible(true);
    addTray();
  }

  private void addTray() {
    SystemTray tray = SystemTray.getSystemTray();
    PopupMenu popup = new PopupMenu();
    Image image = new BufferedImage(36, 36, BufferedImage.TYPE_INT_RGB);
    TrayIcon icon = new TrayIcon(image, "Reproduce", popup);
    icon.setImageAutoSize(true);

    MenuItem item1 = new MenuItem("Reproduce");
    item1.addActionListener(new ActionListener(){
      @Override
      public void actionPerformed(ActionEvent e) {
      System.out.println("Reproduce");
      }
    });
    popup.add(item1);

    try {
      tray.add(icon);
    } catch (AWTException e) {
      e.printStackTrace();
    }
  }

  private void setJavaHome() {
    String original = System.getProperty("java.home");
    boolean exists = !(original == null || !new File(original).exists());
    if (!exists) {
      Path exePath = (new File(getClass().getProtectionDomain().getCodeSource().getLocation().getPath())).toPath();
      Path home = exePath.getParent().resolve("java_home");
      System.setProperty("java.home", home.toString());
      System.out.println("java.home override : " + home);
    }
  }

}

class SimpleWindowAdapter extends WindowAdapter {
    public void windowClosing(WindowEvent e) {
       System.exit(0);
    }
}

native-image.properties

Args = \
    --no-fallback \
    -H:+UnlockExperimentalVMOptions \
    -H:+AddAllCharsets \
    -H:ReflectionConfigurationResources=${.}/reflect-config.json \
    -H:ResourceConfigurationResources=${.}/resource-config.json \
    -H:SerializationConfigurationResources=${.}/serialization-config.json \
    -H:JNIConfigurationResources=${.}/jni-config.json \
    -H:DynamicProxyConfigurationResources=${.}/proxy-config.json

fontconfig.properties is the copy of %JAVA_HOME%/lib/fontconfig.properties.src

Then run the following commands (described above) with several mouse inputs.

javac -d ./java ./Reproduce.java
java -agentlib:native-image-agent=config-output-dir=./java/META-INF/native-image -cp ./java ./Reproduce.java

You might need to right-click the tray icon and close the window of this program to collect metadata.

cp ./native-image.properties ./java/META-INF/native-image
cd ./java
jar -c -f ./Reproduce.jar -e Reproduce -C ./ .
cd ..
mkdir native
native-image -jar ./java/Reproduce.jar ./native/Reproduce
cp -r ./java_home ./native
./native/Reproduce.exe

Then right-click the tray icon and check if the MenuItem in popup menu shows right characters.

Additional Context

Without java_home/conf/fonts/fontconfig.properties, MenuItem does not show any characters. Setting system property java.home for it runtime.

Run-Time Log Output and Error Messages

No response

oubidar-Abderrahim commented 2 weeks ago

I could not reproduce this issue, please verify If this issue is still occurring with the latest GraalVM version, also it might be useful to add "-J-Dfile.encoding=UTF-8" to your build command

hyranno commented 2 weeks ago

Thank you for the response. I tried with latest (23.0.1+11.1 (build 23.0.1+11-jvmci-b01)) but still having this issue. I updated native-image.properties as output of agent has changed :

Args = \
    --no-fallback \
    -J-Dfile.encoding=UTF-8

Adding "-encoding utf8" to javac command and "-J-Dfile.encoding=UTF-8" to native-image.properties does not help.

I forgot to write detail for the run command. At line 2, you might need to right-click tray icon and close the window of this program to collect metadata.

hyranno commented 2 weeks ago

expected With Java, it works as expected. actuall Running native, it shows wrong characters. Other UIs or strings seems like working fine.