Currently, CDS prints fewer warnings in -Xshare:auto mode when we fail to use an archive.
For example, we cannot load the archive if the classpath has an non-empty directory
$ java -cp HelloWorld.jar -Xshare:off -XX:DumpLoadedClassList=hw.classlist HelloWorld
$ rm -rf foo
$ mkdir foo
$ java -cp foo:HelloWorld.jar -Xshare:dump -XX:SharedArchiveFile=hw.jsa -XX:SharedClassListFile=hw.classlist
$ touch foo
-Xshare:on shows more detail info
$ java -cp foo:HelloWorld.jar -Xshare:on -XX:SharedArchiveFile=hw.jsa [0.005s][warning][cds] directory is not empty: foo
[0.006s][error ][cds] An error has occurred while processing the shared archive file.
[0.006s][error ][cds] Unable to map shared spaces
Error occurred during initialization of VM
Unable to use shared archive.
However, -Xshare:auto, which is the default mode, doesn't tell you that the CDS archive is not being mapped:
$ java -cp foo:HelloWorld.jar -Xshare:auto -XX:SharedArchiveFile=hw.jsa
[0.005s][warning][cds] directory is not empty: foo
Hello World
************************
Historical note: beforeJDK-8231610, it was very common for the CDS archive to fail to map due to ASLR. Therefore, we avoided printing warning messages, or else on Windows, half of time time you would see a warning that the CDS archive could not be mapped. Such message would be useless as there's nothing that the user could do address the problem.
However, sinceJDK-8231610, the CDS archive will be relocated as necessary to work with ASLR. Therefore, if the CDS archive fails to map, it's (almost?) always due to user error. E.g., incorrect command-line flags. We should probably change most of the failure messages to the warning level.
======================
Suggested fix:
We should look at all the log_info() related to CDS mapping failure and convert them into one of the following
[1] If the error is caused by version mismatch, file corruption, (or other serious reasons that the user must be aware of), change the call to log_warning().
[2] Otherwise, change the call from
log_info(cds)("CDS is disabled because early JVMTI ClassFileLoadHook is in use.");
log_info(cds)("Unable to use shared archive: %s", message);
to
MetaspaceShared::report_loading_error("CDS is disabled because early JVMTI ClassFileLoadHook is in use.");
MetaspaceShared::report_loading_error("Unable to use shared archive: %s", message);
MetaspaceShared::report_loading_error() should look like this:
if (using default cds archive) {
// It's quite easy to come here when using the default CDS archive, so we should keep using the "info" level
// to avoid excessive warnings (as the user may not even want to use the default CDS archive).
log_info(cds)(....);
} else {
// When we are using a custom CDS archive, the user will be more interested in knowing if/why the CDS archive cannot
// be mapped. So "warning" level is better.
log_warning(cds)(....);
}
For example, we cannot load the archive if the classpath has an non-empty directory
$ java -cp HelloWorld.jar -Xshare:off -XX:DumpLoadedClassList=hw.classlist HelloWorld
$ rm -rf foo
$ mkdir foo
$ java -cp foo:HelloWorld.jar -Xshare:dump -XX:SharedArchiveFile=hw.jsa -XX:SharedClassListFile=hw.classlist
$ touch foo
-Xshare:on shows more detail info
$ java -cp foo:HelloWorld.jar -Xshare:on -XX:SharedArchiveFile=hw.jsa [0.005s][warning][cds] directory is not empty: foo
[0.006s][error ][cds] An error has occurred while processing the shared archive file.
[0.006s][error ][cds] Unable to map shared spaces
Error occurred during initialization of VM
Unable to use shared archive.
However, -Xshare:auto, which is the default mode, doesn't tell you that the CDS archive is not being mapped:
$ java -cp foo:HelloWorld.jar -Xshare:auto -XX:SharedArchiveFile=hw.jsa
[0.005s][warning][cds] directory is not empty: foo
Hello World
************************
Historical note: before
However, since
======================
Suggested fix:
We should look at all the log_info() related to CDS mapping failure and convert them into one of the following
[1] If the error is caused by version mismatch, file corruption, (or other serious reasons that the user must be aware of), change the call to log_warning().
[2] Otherwise, change the call from
log_info(cds)("CDS is disabled because early JVMTI ClassFileLoadHook is in use.");
log_info(cds)("Unable to use shared archive: %s", message);
to
MetaspaceShared::report_loading_error("CDS is disabled because early JVMTI ClassFileLoadHook is in use.");
MetaspaceShared::report_loading_error("Unable to use shared archive: %s", message);
MetaspaceShared::report_loading_error() should look like this:
if (using default cds archive) {
// It's quite easy to come here when using the default CDS archive, so we should keep using the "info" level
// to avoid excessive warnings (as the user may not even want to use the default CDS archive).
log_info(cds)(....);
} else {
// When we are using a custom CDS archive, the user will be more interested in knowing if/why the CDS archive cannot
// be mapped. So "warning" level is better.
log_warning(cds)(....);
}
- links to
-
Review(master) openjdk/jdk/24889