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

8298266: "java.home property not set" error in Graal when sun.awt.fontconfig java property is set on Windows #11559

Closed

Conversation

AlexanderScherbatiy
Copy link

@AlexanderScherbatiy AlexanderScherbatiy commented Dec 7, 2022

Environment:
GraalVM 22.3.0 with jdk 19, Windows OS.

Description:
Create a native image of Swing application using GraalVM and run it with -Dsun.awt.fontconfig=fontconfig.properties.src java property.
java.lang.Error: java.home property not set error is thrown.

For more details see oracle/graal#4875.

Solution:
The error is thrown by the code from FontConfiguration.findFontConfigFile() method.
GraalVM does not set java.home property, that is why the java.lang.Error: java.home property not set is thrown.
FontConfiguration.findFontConfigFile() method compares java.home property to null before checking user provided sun.awt.fontconfig java property.

The proposed fix swaps the order of java.home and sun.awt.fontconfig properties checking to avoid using java.home property in case sun.awt.fontconfig is set.

Steps to reproduce:

graalvm-ce-java19-22.3.0\bin\gu.cmd install native-image
  • Create and compile SwingSample.java sample
import java.awt.*;
import javax.swing.*;

public class SwingSample {
    public static void main(String[] args) throws Exception {
        SwingUtilities.invokeAndWait(() -> {

            JFrame frame = new JFrame("Hello World");

            JButton button = new JButton("Hello");
            button.addActionListener(e -> {
                System.out.printf("Hello, World!%n");
            });

            JPanel panel = new JPanel(new FlowLayout());
            panel.add(button);

            frame.add(panel);
            frame.setSize(400, 300);
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        });
    }
}
  • Run native-image-agent to generate configuration files
graalvm-ce-java19-22.3.0\bin\java.cmd -agentlib:native-image-agent=config-output-dir=conf-dir SwingSample
  • Copy graalvm-ce-java19-22.3.0\lib\fontconfig.properties.src file to the sample dir
  • Generate native image with configuration files and -Djava.awt.headless=false , -Dsun.awt.fontconfig=fontconfig.properties.src java properties
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64"
graalvm-ce-java19-22.3.0\bin\native-image.cmd --no-fallback -Djava.awt.headless=false -Dsun.awt.fontconfig=fontconfig.properties.src -H:ResourceConfigurationFiles=conf-dir/resource-config.json -H:SerializationConfigurationFiles=conf-dir/serialization-config.json -H:ReflectionConfigurationFiles=conf-dir/reflect-config.json -H:JNIConfigurationFiles=conf-dir/jni-config.json SwingSample
  • Run the native image with -Dsun.awt.fontconfig=fontconfig.properties.src java property.
swingsample.exe  -Dsun.awt.fontconfig=fontconfig.properties.src

Exception in thread "main" java.lang.reflect.InvocationTargetException
        at java.desktop@19.0.1/java.awt.EventQueue.invokeAndWait(EventQueue.java:1371)
        at java.desktop@19.0.1/java.awt.EventQueue.invokeAndWait(EventQueue.java:1346)
        at java.desktop@19.0.1/javax.swing.SwingUtilities.invokeAndWait(SwingUtilities.java:1480)
        at SwingSample.main(SwingSample.java:7)
Caused by: java.lang.Error: java.home property not set
        at java.desktop@19.0.1/sun.awt.FontConfiguration.findFontConfigFile(FontConfiguration.java:180)
        at java.desktop@19.0.1/sun.awt.FontConfiguration.<init>(FontConfiguration.java:97)
        at java.desktop@19.0.1/sun.awt.windows.WFontConfiguration.<init>(WFontConfiguration.java:41)

Progress

  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue
  • Change must be properly reviewed (2 reviews required, with at least 1 Reviewer, 1 Author)

Issue

  • JDK-8298266: "java.home property not set" error in Graal when sun.awt.fontconfig java property is set on Windows

Reviewers

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jdk pull/11559/head:pull/11559
$ git checkout pull/11559

Update a local copy of the PR:
$ git checkout pull/11559
$ git pull https://git.openjdk.org/jdk pull/11559/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 11559

View PR using the GUI difftool:
$ git pr show -t 11559

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jdk/pull/11559.diff

@bridgekeeper
Copy link

bridgekeeper bot commented Dec 7, 2022

👋 Welcome back alexsch! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk openjdk bot added the rfr Pull request is ready for review label Dec 7, 2022
@AlexanderScherbatiy AlexanderScherbatiy changed the title 8298266: 'java.home property not set' error in Graal when sun.awt.fontconfig java property is set on Windows 8298266: "java.home property not set" error in Graal when sun.awt.fontconfig java property is set on Windows Dec 7, 2022
@openjdk
Copy link

openjdk bot commented Dec 7, 2022

@AlexanderScherbatiy The following label will be automatically applied to this pull request:

  • client

When this pull request is ready to be reviewed, an "RFR" email will be sent to the corresponding mailing list. If you would like to change these labels, use the /label pull request command.

@openjdk openjdk bot added the client client-libs-dev@openjdk.org label Dec 7, 2022
@mlbridge
Copy link

mlbridge bot commented Dec 7, 2022

Webrevs

@mrserb
Copy link
Member

mrserb commented Dec 19, 2022

I can reproduce the bug and assume that this change will fix that exception. But after this change, we will skip initialization of the "javaLib" if the user config was passed, and as a result, we will skip initialization of the fallback fonts by the getInstalledFallbackFonts. I do not know should if fallback fonts are used if the user explicitly set config or not.

@AlexanderScherbatiy
Copy link
Author

Could you review the updated fix? The javaLib variable is initialized even userConfigFile is not null.

@openjdk
Copy link

openjdk bot commented Dec 23, 2022

@AlexanderScherbatiy This change is no longer ready for integration - check the PR body for details.

@openjdk openjdk bot added the ready Pull request is ready to be integrated label Dec 23, 2022
@prrace
Copy link
Contributor

prrace commented Dec 23, 2022

/reviewers 2

@prrace
Copy link
Contributor

prrace commented Dec 23, 2022

Why is it not set ? That seems wrong.

@openjdk
Copy link

openjdk bot commented Dec 23, 2022

@prrace
The total number of required reviews for this PR (including the jcheck configuration and the last /reviewers command) is now set to 2 (with at least 1 Reviewer, 1 Author).

@openjdk openjdk bot removed the ready Pull request is ready to be integrated label Dec 23, 2022
@AlexanderScherbatiy
Copy link
Author

There is the Java system properties are inconsistent between traditional JDK and native image issue in Graal: oracle/graal#2835

With comment: oracle/graal#2835 (comment)

We are still not setting the java.home system property at image run time by default, and do not plan to change that. Because there is just no "JDK home directory" around at image run time, so setting java.home to, for example, the directory where the native image is located in is misleading - files that might be expected to be in that directory are not there.

@prrace
Copy link
Contributor

prrace commented Dec 23, 2022

There is the Java system properties are inconsistent between traditional JDK and native image issue in Graal: oracle/graal#2835

With comment: oracle/graal#2835 (comment)

We are still not setting the java.home system property at image run time by default, and do not plan to change that. Because there is just no "JDK home directory" around at image run time, so setting java.home to, for example, the directory where the native image is located in is misleading - files that might be expected to be in that directory are not there.

Surely that's graal's problem to solve.
This is a standard system property, it is an error if it is not set correctly.
Also sun.awt.config is not a supported documented property. It was put there for debugging.
If user code is relying on that (I'm not sure if that is being implied) then it is on shaky ground.
We could remove that at any time without notice.

@AlanBateman
Copy link
Contributor

The table in System.getProperties() lists the standard system properties. java.home is not optional. It's not hard to find code that reads the value of this property and it would be a major compatibility issue to change java.home to be optional.

@AlexanderScherbatiy
Copy link
Author

Graal uses a substitutor which replaces FontConfiguration.findFontConfigFile() method to empty on Linux.
This does not work on Windows because it requires to read logical fonts from fontconfig.properties file.

The idea of the fix was to allow to use sun.awt.fontconfig property in Graal.
If sun.awt.fontconfig property is not a supported documented property then may be it is better to put the fontconfig.properties file as a resource during a native image generation and read it when the application is executed.

@prrace
Copy link
Contributor

prrace commented Jan 3, 2023

FYI here's an almost 9 year old bug report where I make clear the unsupported nature of that property. https://bugs.openjdk.org/browse/JDK-8038987

Seems this PR should be withdrawn and the bug report closed as external or not an issue.

@mrserb
Copy link
Member

mrserb commented Jan 6, 2023

If this property is not optional why do we have a null check for it? Can that check be removed as a part of refactoring?

@prrace
Copy link
Contributor

prrace commented Jan 6, 2023

If this property is not optional why do we have a null check for it? Can that check be removed as a part of refactoring?

It is much better to have an error thrown which explains the problem rather than a random NPE or similar right afterwards.
This behaviour has been there since at least JDK 1.3 (2000) when the file was first created as sun/awt/FontProperties.java. It may even have existed in some other location before then, but I can't tell that from SCCS per-file history.

@mrserb
Copy link
Member

mrserb commented Jan 6, 2023

It is much better to have an error thrown which explains the problem rather than a random NPE or similar right afterwards.

But I assume we should have a test somewhere that validates that this option is not null = "is not optional"?
I make a quick search of code where we read the conf files, and it seems:
https://github.com/search?q=%22java.home%22+repo%3Aopenjdk%2Fjdk+path%3Asrc%2Fjava.desktop%2F+language%3AJava+language%3AJava&type=Code&ref=advsearch&l=Java&l=Java

  • The Sound - throw an exception in one place, but ignores the null in another place
  • The Fontconfig - throw an exception in FcFontConfiguration.java, but fallback to the empty code in SunFontManager.java
  • The Swing ignores the null property
  • The metal pipeline fallback to the empty path
  • The a11y code just read it as is.
  • The printers code in PSPrinterJob ignores the null

We have an opportunity to clean up all that code.

@prrace
Copy link
Contributor

prrace commented Jan 17, 2023

But I assume we should have a test somewhere that validates that this option is not null = "is not optional"?

Maybe core libs could add such a test.

The link doesn't work for me but I expect I'd need to look at each of those cases to understand what they are doing.

It doesn't change that the reason for this proposed change isn't valid.
We probably should remove that debugging property to make it clear.

@AlanBateman
Copy link
Contributor

Maybe core libs could add such a test.

It is tested by conformance tests but a test could be added to the OpenJDK jtreg tests if needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
client client-libs-dev@openjdk.org rfr Pull request is ready for review
4 participants