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

allow java.home config files to be included in the build output #7109

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

kkriske
Copy link
Contributor

@kkriske kkriske commented Aug 2, 2023

set up basic support for copying files from the java.home directory to the build output

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Aug 2, 2023
@kkriske kkriske force-pushed the java_home_config_files branch from e4296bc to 1b24a1d Compare August 2, 2023 22:08
@kkriske kkriske force-pushed the java_home_config_files branch from 1b24a1d to 67f7cc7 Compare August 3, 2023 21:40
@@ -47,6 +47,8 @@ enum ArtifactType {
JDK_LIBRARY("jdk_libraries"),
/* For all library shims for the JDK needed at run-time. */
JDK_LIBRARY_SHIM(JDK_LIBRARY.getJsonKey()), // distinction should not be important to users.
/* For all configuration files from java.home needed at run-time */
JDK_CONFIG_FILE("jdk_config"),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you extend this enum, you'll also have to extend this JSON schema. Since v0.9.0 is already release, you'll have to copy it and call it v0.9.1. Also, search for references to the file name and update the help text of the corresponding option. We should probably add a note about this to the enum's javadoc.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

example build artifacts file:

{
  "executables": [
    "native-tests.exe.exe"
  ],
  "jdk_config": [
    "lib\\fontconfig.bfc"
  ],
  "jdk_libraries": [
    "awt.dll",
    "fontmanager.dll",
    "freetype.dll",
    "javaaccessbridge.dll",
    "javajpeg.dll",
    "jawt.dll",
    "lcms.dll",
    "java.dll",
    "jvm.dll"
  ]
}

I'm assuming the double backslash may have to be normalized?

Comment on lines 55 to 59
if (configFile.startsWith("/")) {
configFiles.add(configFile.substring(1));
} else {
configFiles.add(configFile);
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about this?

Suggested change
if (configFile.startsWith("/")) {
configFiles.add(configFile.substring(1));
} else {
configFiles.add(configFile);
}
configFiles.add(configFile.startsWith("/") ? configFile.substring(1) : configFile);

Also, shouldn't we use File.separator instead of "/" here?

Copy link
Contributor Author

@kkriske kkriske Aug 4, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The thing that's validated here is user input (as in GraalVM dev/contributer, as it's not exposes to end users), so it all depends on how JDKConfigFiles.singleton().register("") is called.
In theory, removing the leading slash isn't required either if nobody passes one in.. So depends on how much input sanitisation you want to do.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, how about changing this to something like register(String... configPathParts), which can then be used like register("lib", "bar", "my.file");. Parts are not allowed to be .. or to start with / or \. register() then joins the parts using the correct File.separator and validates that the joined path exists in java.home. If any of this is not the case, fail with an error.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could even just use Paths.get() in register().

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A vararg does make more sense indeed. I've modified it and changed the validation accordingly.


@Override
public void afterImageWrite(AfterImageWriteAccess access) {
Path jdkHomeDir = Path.of(System.getProperty("java.home")).normalize();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

java.home cannot be null, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think it can be. What are you hinting at?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just checking. As you know, java.home isn't always set in SVM 😉

Path jdkHomeDir = Path.of(System.getProperty("java.home")).normalize();
for (String configFile : new TreeSet<>(JDKConfigFiles.singleton().configFiles)) {
Path jdkConfigPath = jdkHomeDir.resolve(configFile).normalize();
VMError.guarantee(jdkConfigPath.startsWith(jdkHomeDir));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't resolve().normalize() take care of this? If you want to keep the guarantee, please add a descriptive message.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to validate this, but the idea was to protect against passing in ../../../someSystemFile, which after .normalize() would no longer contain the .. directories, but would point to a fille outside of the java.home dir. That is unless I'm missing something.
Since it's not actually exposes to end user (will it ever be?) this validation is maybe a bit overly cautious.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree that we probably don't need to be too cautious here as it's internal API. However, the validation again happens late in the process, I'd prefer if we validate such things as early as possible (in the register() hook in this case).

Files.copy(jdkConfigPath, imageConfigPath, REPLACE_EXISTING);
BuildArtifacts.singleton().add(BuildArtifacts.ArtifactType.JDK_CONFIG_FILE, imageConfigPath);
} catch (IOException e) {
VMError.shouldNotReachHere(e);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a descriptive reason such as

Suggested change
VMError.shouldNotReachHere(e);
VMError.shouldNotReachHere("Failed to copy JDK configuration files", e);

final class JDKConfigFilesFeature implements InternalFeature {
@Override
public void afterRegistration(AfterRegistrationAccess access) {
ImageSingletons.add(JDKConfigFiles.class, new JDKConfigFiles());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could annotate JDKConfigFiles with AutomaticallyRegisteredImageSingleton and drop this manual registration if you like, but it can also stay as is.

}

public void register(String configFile) {
if (configFile.startsWith("/")) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder whether it would make sense to check the existence of the configFile here, so that we can fail when an incorrect file is registered, rather than later before the image is being created.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, I moved the validation to the register call.

@kkriske kkriske force-pushed the java_home_config_files branch 2 times, most recently from 3e92a8a to 6e8c7da Compare August 4, 2023 19:45
- make input validation more readable
@kkriske kkriske force-pushed the java_home_config_files branch from 6e8c7da to 84fed02 Compare August 4, 2023 19:55
- include lib/fontconfig.bfc
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
native-image OCA Verified All contributors have signed the Oracle Contributor Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants