-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
base: master
Are you sure you want to change the base?
Conversation
e4296bc
to
1b24a1d
Compare
…o the build output
1b24a1d
to
67f7cc7
Compare
@@ -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"), |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
if (configFile.startsWith("/")) { | ||
configFiles.add(configFile.substring(1)); | ||
} else { | ||
configFiles.add(configFile); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about this?
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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()
.
There was a problem hiding this comment.
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(); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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)); |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
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
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()); |
There was a problem hiding this comment.
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("/")) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
3e92a8a
to
6e8c7da
Compare
- make input validation more readable
6e8c7da
to
84fed02
Compare
- include lib/fontconfig.bfc
set up basic support for copying files from the java.home directory to the build output