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

Backport reachability-metadata.json parser #23

Merged
merged 3 commits into from
Nov 7, 2024

Conversation

loicottet
Copy link
Member

@loicottet loicottet commented Sep 13, 2024

Partial backport of oracle/graal#9048 and related PRs:

The goal of this PR is to enable the 23.1 version of GraalVM to correctly parse reachability metadata files emitted by GraalVM 24.1 and future releases. These files are parsed and matched to the existing capabilities of GraalVM 23.1 on a best effort basis, meaning that existing workflows won't be disrupted, but features introduced in subsequent versions will be ignored. For example, GraalVM 24.1 can register members (methods, fields and constructors) of proxy classes for reflection, which was not possible before, and does it via the reflection metadata instead of a separate proxy metadata file. When encountering such metadata, the 23.1 parser will now correctly register the proxy class for runtime instantiation, but won't enable reflective access to the specified members.
The PR is split in two commits to facilitate reviewing. The first one is a simple copy-paste of the parser from master (most of the contents of the com.oracle.svm.core.configure package) and the second contains the modifications required to make the parser fit with the features of 23.1.

@oracle-contributor-agreement oracle-contributor-agreement bot added the OCA Verified All contributors have signed the Oracle Contributor Agreement. label Sep 13, 2024
@jerboaa
Copy link
Contributor

jerboaa commented Sep 13, 2024

@loicottet Thanks! There are some CI failures. Could you please look into those?

@zakkak
Copy link
Contributor

zakkak commented Sep 24, 2024

Hi @loicottet, is there any progress on this? Thanks

@loicottet loicottet force-pushed the lottet/backport-metadata-21 branch from 237120c to 11f3306 Compare September 24, 2024 12:08
@zakkak
Copy link
Contributor

zakkak commented Sep 24, 2024

Thanks for fixing the conflicts @loicottet. I will have a look later today or tomorrow.

Comment on lines +48 to +54
if (typeDescriptor instanceof NamedConfigurationTypeDescriptor namedDescriptor) {
String typeName = namedDescriptor.name();
ConfigurationType type = configuration.get(condition, typeName);
ConfigurationType result = type != null ? type : new ConfigurationType(condition, typeName);
return TypeResult.forType(typeName, result);
} else {
return TypeResult.forException(typeDescriptor.toString(), null);
Copy link
Contributor

Choose a reason for hiding this comment

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

I am not able to find this kind of handling in any point in time on master. I assume this was done to prevent applying https://github.com/oracle/graal/pull/8822/files#diff-f6d5768c08225b6ce33958e46c13befe50cbb6d84d9508c52db893a374f65bbf (which IMO is OK to backport in order to avoid deviations in code logic)

Copy link
Member Author

Choose a reason for hiding this comment

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

That's correct. My logic on the backport is to keep the changes confined to the parser code as much as possible. We do not want to backport new builder functionality to previous versions, but only allow previous versions to correctly parse newer reachability-metadata.json files.

Comment on lines +53 to +77
private void parseTopLevelObject(EconomicMap<String, Object> obj) {
Object resourcesObject = null;
Object bundlesObject = null;
Object globsObject = null;
MapCursor<String, Object> cursor = obj.getEntries();
while (cursor.advance()) {
if (RESOURCES_KEY.equals(cursor.getKey())) {
resourcesObject = cursor.getValue();
} else if (BUNDLES_KEY.equals(cursor.getKey())) {
bundlesObject = cursor.getValue();
} else if (GLOBS_KEY.equals(cursor.getKey())) {
globsObject = cursor.getValue();
}
}

if (resourcesObject != null) {
parseResourcesObject(resourcesObject);
}
if (bundlesObject != null) {
parseBundlesObject(bundlesObject);
}
if (globsObject != null) {
parseGlobsObject(globsObject);
}
}
Copy link
Contributor

@zakkak zakkak Sep 25, 2024

Choose a reason for hiding this comment

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

If I get this right, you need to partially backport globs support for reachability-metadata, but do we really want to backport globs support to resource-config as well?

If we do, shouldn't the oracle/graal@17fc7f0 implementation be preferred?

Copy link
Member Author

Choose a reason for hiding this comment

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

Globs can be present in a resource-config.json file in the case where both globs and resource patterns are registered in the same ResourceConfiguration (for example when merging both combined and legacy metadata files). In that case JSON printing falls back to emitting a standalone legacy file instead of integrating resources in reachability-metadata.json (where we want to avoid resource patterns moving forwards), which means we need to be able to emit globs in this legacy file.

If we do, the oracle/graal@17fc7f0 implementation be preferred?

This change applies to JSON emission to ensure that converting legacy resource-config.json files to reachability-metadata.json succeeds most of the time instead of having to fallback to resource-config.json because it contains resource patterns. Since the Java 21 version of Graal doesn't emit reachability-metadata.json files, this optimization is not necessary.

Copy link
Contributor

Choose a reason for hiding this comment

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

Globs can be present in a resource-config.json file

Not in JDK 21 (GraalVM 23.1), that feature was added in JDK 23 (GraalVM 24.1.0). So what I am worried about is backporting the globs support without actually intending to do so.

As you say in #23 (comment):

We do not want to backport new builder functionality to previous versions, but only allow previous versions to correctly parse newer reachability-metadata.json files.

Regarding:

Since the Java 21 version of Graal doesn't emit reachability-metadata.json files, this optimization is not necessary.

I see, what I worry about though is making future backports harder due to deviating from the actual upstream code (which we already do by not fully backporting oracle/graal#8250)

Copy link
Member Author

Choose a reason for hiding this comment

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

Not in JDK 21 (GraalVM 23.1), that feature was added in JDK 23 (GraalVM 24.1.0).

But metadata files created on GraalVM 24.1 can be passed to GraalVM 23.1 and are expected to be understood.

So what I am worried about is backporting the globs support without actually intending to do so.

Since globs are meant as a replacement for resource patterns and as such are not purely a new capability of the builder, backporting glob parsing is necessary, otherwise resource handling through reachability-metadata.json would become impossible on 23.1. ResourceConfigurationParser.globToRegex and the Wildcard backport achieve this goal without having to backport the complete glob support (RuntimeResourceSupport.addGlob and the whole logic behind it).

I see, what I worry about though is making future backports harder due to deviating from the actual upstream code (which we already do by not fully backporting oracle/graal#8250)

That's a fair point, keeping parser code as close to master as possible should indeed be a goal. I will start the backporting process for this change and either include it in this PR or open a new one once it's done.

Copy link
Contributor

Choose a reason for hiding this comment

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

But metadata files created on GraalVM 24.1 can be passed to GraalVM 23.1 and are expected to be understood.

That would be in the reachability-metadata.json format though, not in the legacy resource-config.json format, right?

If we want to be able to consume "legacy" config files generated by newer GraalVM versions then we need to also support type in reflect-config.json and proxies in serialization-config.json

Since globs are meant as a replacement for resource patterns and as such are not purely a new capability of the builder, backporting glob parsing is necessary, otherwise resource handling through reachability-metadata.json would become impossible on 23.1.

I agree, my only concern is about bringing support for globs in resource-config.json in addition to reachability-metadata.json.

That's a fair point, keeping parser code as close to master as possible should indeed be a goal. I will start the backporting process for this change and either include it in this PR or open a new one once it's done.

Thank you

Copy link
Contributor

Choose a reason for hiding this comment

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

@loicottet can you please have a look in the above comments and provide some more details? It's still not clear to me at what level we need to support "globs support".

Copy link
Member Author

Choose a reason for hiding this comment

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

But metadata files created on GraalVM 24.1 can be passed to GraalVM 23.1 and are expected to be understood.

That would be in the reachability-metadata.json format though, not in the legacy resource-config.json format, right?

That's correct.

If we want to be able to consume "legacy" config files generated by newer GraalVM versions then we need to also support type in reflect-config.json and proxies in serialization-config.json

type is never emitted into reflect-config.json, we corrected it to be always name. proxies is understood by the backported parser, this should not be a problem.

Since globs are meant as a replacement for resource patterns and as such are not purely a new capability of the builder, backporting glob parsing is necessary, otherwise resource handling through reachability-metadata.json would become impossible on 23.1.

I agree, my only concern is about bringing support for globs in resource-config.json in addition to reachability-metadata.json.

This is necessary for merging resource configuration from both a resource-config.json file with non-trivial resource patterns, and a reachability-metadata.json with globs. In that case, we can't emit a reachability-metadata.json file since we don't want it to contain resource patterns. The only solution is to emit a resource-config.json, which then needs to be able to hold globs as well.

Comment on lines +111 to +196
public static String globToRegex(String module, String glob) {
return (module == null || module.isEmpty() ? "" : module + ":") + globToRegex(glob);
}

private static String globToRegex(String glob) {
/* this char will trigger last wildcard dump if the glob ends with the wildcard */
String tmpGlob = glob + '#';
StringBuilder sb = new StringBuilder();

int quoteStartIndex = 0;
Wildcard previousWildcard = Wildcard.START;
for (int i = 0; i < tmpGlob.length(); i++) {
char c = tmpGlob.charAt(i);
Wildcard currentWildcard = previousWildcard.next(c);

boolean wildcardStart = previousWildcard == Wildcard.START && currentWildcard != Wildcard.START;
if (wildcardStart && quoteStartIndex != i) {
/* start of the new wildcard => quote previous content */
sb.append(Pattern.quote(tmpGlob.substring(quoteStartIndex, i)));
}

boolean consecutiveWildcards = previousWildcard == Wildcard.DOUBLE_STAR_SLASH && currentWildcard != Wildcard.START;
boolean wildcardEnd = previousWildcard != Wildcard.START && currentWildcard == Wildcard.START;
if (wildcardEnd || consecutiveWildcards) {
/* end of the wildcard => append regex and move start of next quote after it */
sb.append(previousWildcard.regex);
quoteStartIndex = i;
}
previousWildcard = currentWildcard;
}
/* remove the last char we added artificially */
tmpGlob = tmpGlob.substring(0, tmpGlob.length() - 1);
if (quoteStartIndex < tmpGlob.length()) {
sb.append(Pattern.quote(tmpGlob.substring(quoteStartIndex)));
}
return sb.toString();
}

/**
* This enum acts like a state machine that helps to identify glob wildcards.
*/
private enum Wildcard {
START("") {
@Override
public Wildcard next(char c) {
return c == '*' ? STAR : START;
}
},
STAR("[^/]*") {
@Override
public Wildcard next(char c) {
return c == '*' ? DOUBLE_STAR : START;
}
},
DOUBLE_STAR(".*") {
@Override
public Wildcard next(char c) {
return c == '/' ? DOUBLE_STAR_SLASH : START;
}
},
DOUBLE_STAR_SLASH("([^/]*(/|$))*") {
@Override
public Wildcard next(char c) {
return c == '*' ? STAR : START;
}
};

final String regex;

Wildcard(String val) {
regex = val;
}

public abstract Wildcard next(char c);
}

protected void parseGlobsObject(Object globsObject) {
List<Object> globs = asList(globsObject, "Attribute 'globs' must be a list of glob patterns");
for (Object object : globs) {
parseGlobEntry(object, (condition, module, resource) -> registry.addResources(condition, globToRegex(module, resource)));
}
}

private interface GlobPatternConsumer<T> {
void accept(T a, String b, String c);
}
Copy link
Contributor

@zakkak zakkak Sep 25, 2024

Choose a reason for hiding this comment

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

This code is new (instead of backporting more code from oracle/graal#8715) in order to reduce the touched classes. Although having less code touched is preferred, this feels quite risky to me as it will only be "tested" in the LTS branches (and probably not to a great extend).

@graalvm/community-maintainers @simonis WDYT? How do you handle similar cases in OpenJDK backports?

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think such a feature would ever be downported in the OpenJDK in the first place :)

In the end it is always a judgement call between the ease of a downport (this one is already quite big) and long term maintainability. I currently can't oversee which existing functionality in the upstream version this new code is replacing and how many additional changes would need to be downorted in oder to make this code look more like the upstream version. If you could detail the alternative (i.e. the additional changes that would need to be downported), that would be helpful.

In general, I have problems to understand the reason behind this downport (see my general comment below). For me, the only justification to accept such a downport would be to maintain compatibility with the corresponding Oracle GraalVM verision 23.1. But in that case we wouldn't have a big choice anyway and should probably accept the exact change that was downported to Oracle GraalVM 23.1 (although we can't see it).

Copy link
Member Author

Choose a reason for hiding this comment

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

See #23 (comment) for the reasoning

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think such a feature would ever be downported in the OpenJDK in the first place :)

I see :)

If you could detail the alternative (i.e. the additional changes that would need to be downported), that would be helpful.

For the sake of simplicity (and ease of maintenance), let's say that we would need to backport oracle/graal#8715 as a whole (this would also address my concern in #23 (comment))

In general, I have problems to understand the reason behind this downport (see my general comment below).

Let's keep this discussion in the general comment.

@Delete //
static ConcurrentHashMap<Target_java_lang_invoke_MemberName, MethodHandle> LOOKASIDE_TABLE;
// Checkstyle: resume

Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be accidentally brought in from oracle/graal#8122. Could you please elaborate on why it's needed?

Copy link
Member Author

Choose a reason for hiding this comment

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

Same here, this is a bug that appeared during testing the metadata repository with converted metadata (from *-config.json to reachability-metadata.json). The likely cause is that "type" in reachability-metadata.json brings in the whole class reflection metadata for registered types instead of the more targeted registrations from the legacy files. In this case the bug was already discovered and fixed in oracle/graal#8122, so I included the fix in the backport.

@@ -53,7 +53,9 @@ protected void registerConditionalConfiguration(ConfigurationCondition condition
public void flushConditionalConfiguration(Feature.BeforeAnalysisAccess b) {
for (Map.Entry<String, Collection<Runnable>> reachabilityEntry : pendingReachabilityHandlers.entrySet()) {
TypeResult<Class<?>> typeResult = ((FeatureImpl.BeforeAnalysisAccessImpl) b).getImageClassLoader().findClass(reachabilityEntry.getKey());
b.registerReachabilityHandler(access -> reachabilityEntry.getValue().forEach(Runnable::run), typeResult.get());
if (typeResult.isPresent()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Could you please explain why this check is now necessary?

Copy link
Member Author

Choose a reason for hiding this comment

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

Testing this PR brought forward the fact that if a class throwing a linkage error when resolved is added to the list of reachability handlers, the build fails since typeResult.get() returns null.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, thank you for the clarification. I wonder if it's worth printing a warning to notify the user that some reachability handlers got ignored (ideally with some info about the LinkafeError, but that won't be trivial I guess).

FTR in the main repo this is fixed by oracle/graal@fff140b

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, I can add a warning here in the follow-up PR which will add the warning for ignored proxy registrations. The LinkageError should be part of the TypeResult, so it should be possible to add it to the warning.

Copy link
Contributor

@zakkak zakkak left a comment

Choose a reason for hiding this comment

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

Thank you for the backport @loicottet.

It looks good except for the schema version updates and 1-2 more changes plus some concerns I have regarding the tradeoff between touching less classes and introducing new code. Let's discuss these and proceed accordingly.

@simonis
Copy link
Contributor

simonis commented Sep 25, 2024

@loicottet, @zakkak, I have difficulties in understanding the reason for this quite significant downport. Why is it important that GraalVM 23.1 will partially understand reachability metadata files emitted by GraalVM 24.1 and future releases? Do you expect that popular frameworks/libraries will only emit the new formt in the future?

You write "These files are parsed and matched to the existing capabilities of GraalVM 23.1 on a best effort basis, meaning that existing workflows won't be disrupted, but features introduced in subsequent versions will be ignored." What do you mean by "existing workflows won't be disrupted"? From my understanding the reachability metadata is crucial in order for a native application to work correctly. What sense does it make to be able to successfully create a native image with GraalVM 23.1 and metadata in the new format, if the native application in the end won't work correctly (because some features of the metadate were ignored)? In such a case, wouldn't it be preferable that GraalVM 23.1 bails out immediately on the new format, thus forcing dependencies to maintain reachability metadata files in the old format as well, if they want to support GraalVM 23.1? Please let me know if I'm misunderstanding this completely?

Also, has this feature been downported to Oracle's GraalVM version 23.1 as well and if yes in which form? I.e. is this downport something we need in the community edition of GraalVM 23.1 in order to maintain compatibility with Oracle GraalVM 23.1? If so, it would be very helpful to know what exact variant of support for the new reachability metadata format landed in OracleVM 23.1 because downporting it in a different way for the community version will probably just cause more confusion than help.

@jerboaa
Copy link
Contributor

jerboaa commented Sep 25, 2024

I haven't looked at the patch in detail, yet. That's on my TODO for tomorrow.

When talking to @vjovanov at the GraalVM Summit last week he mentioned that there is a set of tests that were run on the Oracle parts. It would be good to include those tests in this downport or as a follow-up. Without it, we'd get even more divergence on what the various metadata parsers would support. Even if there is no observable divergence currently, we need to ensure this doesn't break with later backports so we need a test harness ensuring compatibility.

@zakkak
Copy link
Contributor

zakkak commented Sep 25, 2024

@loicottet, @zakkak, I have difficulties in understanding the reason for this quite significant downport. Why is it important that GraalVM 23.1 will partially understand reachability metadata files emitted by GraalVM 24.1 and future releases? Do you expect that popular frameworks/libraries will only emit the new formt in the future?

Yes that's possible. For frameworks it's quite difficult (and I guess impossible for libraries) to detect the GraalVM version that will eventually be used to build the project, e.g. in Quarkus we support packaging everything in one container and building the native image in another container (in which case the actual GraalVM version can only be obtained after we have done all the config generation).

So in order to allow the frameworks and libraries to use the new configuration capabilities without breaking backwards compatibility this backport was proposed. The other alternative, that is already supported is to have frameworks and libraries generate both the new config and the old ones, in this case GraalVM for JDK 21 would ignore the new config, but newer GraalVM versions would parse both configurations and combine them, which seems scary to me. Why not ignore the old configs if a newer one is present? I guess it's to allow for combinations of libraries each using their own configuration scheme, but I will let @loicottet comment on that.

You write "These files are parsed and matched to the existing capabilities of GraalVM 23.1 on a best effort basis, meaning that existing workflows won't be disrupted, but features introduced in subsequent versions will be ignored." What do you mean by "existing workflows won't be disrupted"? From my understanding the reachability metadata is crucial in order for a native application to work correctly. What sense does it make to be able to successfully create a native image with GraalVM 23.1 and metadata in the new format, if the native application in the end won't work correctly (because some features of the metadate were ignored)?

Good point, note that the native image won't work only in very specific cases though, where the configuration is using something without an equivalent in GraalVM 23.1 (e.g. the proxy members registration from oracle/graal#8822). @loicottet I believe that in such cases the compilation should fail, as the application might end up trying to reflectively access these members at run-time.

In such a case, wouldn't it be preferable that GraalVM 23.1 bails out immediately on the new format, thus forcing dependencies to maintain reachability metadata files in the old format as well, if they want to support GraalVM 23.1? Please let me know if I'm misunderstanding this completely?

Yes, that would be an option, but it would most probably result in frameworks and/or libraries not moving to the new configuration to avoid the burden of maintaining both configurations. Which would result in missing out on some new features for users building with newer GraalVM versions and also a much slower adoption of the new configuration scheme, meaning the legacy support would need to be maintained for a longer time.

Also, has this feature been downported to Oracle's GraalVM version 23.1 as well and if yes in which form? I.e. is this downport something we need in the community edition of GraalVM 23.1 in order to maintain compatibility with Oracle GraalVM 23.1?

Yes, that was the ask.

If so, it would be very helpful to know what exact variant of support for the new reachability metadata format landed in OracleVM 23.1 because downporting it in a different way for the community version will probably just cause more confusion than help.

👍

@jerboaa
Copy link
Contributor

jerboaa commented Sep 25, 2024

oracle/graal#7487 mentions that the reachability metadata repository will move to the new format immediately. Hence, the older GraalVM versions need to accept glob patterns as well.

@zakkak
Copy link
Contributor

zakkak commented Sep 25, 2024

oracle/graal#7487 mentions that the reachability metadata repository will move to the new format immediately. Hence, the older GraalVM versions need to accept glob patterns as well.

Thanks for the reference @jerboaa.

Note that in the "Backward Compatibility" sections it mentions that:

The previous versions of GraalVM must be modified to accept the new format as well.

So it looks like we might need to do some additional backporting. @vjovanov @loicottet can you please confirm? Is glob support in resource-config.json backported to Oracle GraalVM for JDK 21?

The current format for resources will be supported until the majority of the ecosystem adopts the new format.

So the new format support in resource-config.json is not a requirement, unless requested by the GraalVM team for compatibility with Oracle GraalVM. We can require people to either use resource-config.json v1.0.0 , or the new reachability-metadata.json if they want backwards compatibility, although it seems to complicate things...

@loicottet
Copy link
Member Author

So it looks like we might need to do some additional backporting. @vjovanov @loicottet can you please confirm? Is glob support in resource-config.json backported to Oracle GraalVM for JDK 21?

Yes, this backport is the same that was backported to Oracle GraalVM 23.1, including glob parsing support.

So in order to allow the frameworks and libraries to use the new configuration capabilities without breaking backwards compatibility this backport was proposed. The other alternative, that is already supported is to have frameworks and libraries generate both the new config and the old ones, in this case GraalVM for JDK 21 would ignore the new config, but newer GraalVM versions would parse both configurations and combine them, which seems scary to me. Why not ignore the old configs if a newer one is present? I guess it's to allow for combinations of libraries each using their own configuration scheme, but I will let @loicottet comment on that.

We want to avoid having to ship two parallel metadata formats alongside each other, as this would be confusing, and keeping the versions in sync would also be a burden on library owners. Our idea is to introduce reachability-metadata.json as the new standard, and progressively retire the old *-config.json files from circulation. The newer GraalVM versions already only emit the new file. Potential differences in the required metadata can be addressed through the use of conditions.

The differences between the old and new formats are usually solved in a straightforward manner:

  • queriedMethods, queryAllDeclaredMethods and the like in reflect-config.json are implied by "type" in reachability-metadata.json. The same is true for allRecordComponents, allPermittedSubclasses, etc.;
  • Proxy registration as part of the "reflection" field of reachability-metadata.json is equivalent to registration in proxy-config.json. Any method or field registrations on such a type are ignored since the 23.1 builder doesn't support them;
  • Resource patterns in resource-config.json are equivalent to globs in reachability-metadata.json. Crucially, any glob can be expressed as a regex, which enables previous versions to fully understand newer metadata files (see also my answer here);
  • Resource exclude lists and the resource bundle "classNames" field are not allowed in reachability-metadata.json. This only reduces functionality and doesn't cause backwards compatibility problems;
  • typeReached conditions are transformed into typeReachable conditions, which are less constraining. This can cause missing registration errors to not fire when using --exact-reachability-metadata, but no new failures in existing working code;
  • Lambda serialization is not supported in reachability-metadata.json yet and is currently emitted in a serialization-config.json even on the latest GraalVM version. This file can already be read by the 23.1 parser.

What do you mean by "existing workflows won't be disrupted"?

If a program was successfully running on GraalVM 23.1 with legacy configuration files, transforming these files into a reachability-metadata.json file won't cause the program to stop working.

@loicottet loicottet force-pushed the lottet/backport-metadata-21 branch from 11f3306 to 595cd90 Compare September 26, 2024 11:53
@vjovanov
Copy link
Member

vjovanov commented Sep 26, 2024

@jerboaa I have changed the sentence mentioning the immediate porting of the metadata repo to say that we will wait for the community to adjust to the new changes.

When talking to @vjovanov at the GraalVM Summit last week he mentioned that there is a set of tests that were run on the Oracle parts.

We are completing the test suite now (will take some more time). After that, we will start the discussion about opening this suite. Until then we will run the suite on top of the backport repositories.

@jerboaa
Copy link
Contributor

jerboaa commented Sep 26, 2024

@jerboaa I have changed the sentence mentioning the immediate porting of the metadata repo to say that we will wait for the community to adjust to the new changes.

Thanks.

When talking to @vjovanov at the GraalVM Summit last week he mentioned that there is a set of tests that were run on the Oracle parts.

We are completing the test suite now (will take some more time). After that, we will start the discussion about opening this suite. Until then we will run the suite on top of the backport repositories.

OK. If that suite could be moved to community it would be ideal. Thanks for considering it!

@zakkak
Copy link
Contributor

zakkak commented Sep 27, 2024

Yes, this backport is the same that was backported to Oracle GraalVM 23.1, including glob parsing support.

@loicottet by "including glob parsing support" do I understand correctly that Oracle GraalVM 23.1 includes a backport of oracle/graal#8715 (which is not part of this PR)?

Proxy registration as part of the "reflection" field of reachability-metadata.json is equivalent to registration in proxy-config.json. Any method or field registrations on such a type are ignored since the 23.1 builder doesn't support them;

Shouldn't GraalVM print warnings in such cases?

OK. If that suite could be moved to community it would be ideal. Thanks for considering it!

👍, right now there is no good way for us to test this (without creating a similar suite). Even if the suite is not compete it is still better than nothing :)

General comment: Please use git cherry-pick -x when backporting as it makes it easy to track things in the future. I understand that the biggest part of this PR was not done through cherry-pick (as that would be kind of impossible), but when you use it please include the -x parameter. Thanks

@simonis
Copy link
Contributor

simonis commented Sep 30, 2024

For the wider context and for those who didn't had a chance to attend the GraalVM Community Summit I attach @vjovanov great slides about "Native Image Developer Experience" which motivate and explain some of the changes in this PR.

@simonis
Copy link
Contributor

simonis commented Sep 30, 2024

  • Proxy registration as part of the "reflection" field of reachability-metadata.json is equivalent to registration in proxy-config.json. Any method or field registrations on such a type are ignored since the 23.1 builder doesn't support them;

But doesn't this mean that a project which migrates to the new reachability-metadata.json format and moves its proxy registration from proxy-config.json to the new "reflection" field wont work on 23.1 any more?

@simonis
Copy link
Contributor

simonis commented Sep 30, 2024

[GR-56101] JSON Metadata Versioning, Backwards Compatibility, and Evolution (i.e. oracle/graal#8534) describes the envisioned forward and backward compatibility requirements for the new metadata format. It mentions "type for proxy and lambda classes oracle/graal#7476, new conditions such as typeReached oracle/graal#7480, and the new resource-config.json format oracle/graal#7487" as the most important upcoming features which will have to be backported.

@zakkak
Copy link
Contributor

zakkak commented Oct 3, 2024

But doesn't this mean that a project which migrates to the new reachability-metadata.json format and moves its proxy registration from proxy-config.json to the new "reflection" field wont work on 23.1 any more?

Only if the application tries to reflectively access methods or fields of the proxy class, which is supported in the latest GraalVM versions but not in GraalVM 23.1 for JDK 21. So migrating an existing configuration of a 23.1-compatible application shouldn't break anything, the proxy classes will be registered as expected.

The problem is for applications developed with a newer GraalVM that might be reflectively accessing members of proxy classes. Such applications are expected to fail at runtime since with the current state of the PR the user doesn't get a warning or error at build time about their configuration partially being ignored.

@loicottet
Copy link
Member Author

loicottet commented Oct 22, 2024

@loicottet by "including glob parsing support" do I understand correctly that Oracle GraalVM 23.1 includes a backport of oracle/graal#8715 (which is not part of this PR)?

This is a partial backport, containing only the code required for the parser to understand globs, and pass them to the resources feature as patterns.

Proxy registration as part of the "reflection" field of reachability-metadata.json is equivalent to registration in proxy-config.json. Any method or field registrations on such a type are ignored since the 23.1 builder doesn't support them;

Shouldn't GraalVM print warnings in such cases?

Yes, that's a good idea.

@zakkak
Copy link
Contributor

zakkak commented Oct 23, 2024

@loicottet by "including glob parsing support" do I understand correctly that Oracle GraalVM 23.1 includes a backport of oracle/graal#8715 (which is not part of this PR)?

This is a partial backport, containing only the code required for the parser to understand globs, and pass them to the resources feature as patterns.

ACK, the question still holds though. Does Oracle GraalVM 23.1 include complete globs support, including in the "legacy" config file resource-config.json?

Proxy registration as part of the "reflection" field of reachability-metadata.json is equivalent to registration in proxy-config.json. Any method or field registrations on such a type are ignored since the 23.1 builder doesn't support them;

Shouldn't GraalVM print warnings in such cases?

Yes, that's a good idea.

Do you intend to contribute this as part of this PR or should we add it as a follow up TODO?

Does Oracle GraalVM for JDK 21.0.5 include this backport? Is there any way I can see what has been backported or what is supported?

@loicottet
Copy link
Member Author

ACK, the question still holds though. Does Oracle GraalVM 23.1 include complete globs support, including in the "legacy" config file resource-config.json?

Oracle GraalVM 23.1 has the same glob support as this backport, only parsing on both resource-config.json and reachability-metadata.json, which are converted to resource patterns. See also my reply on the code comments for the rationale behind the inclusion of globs to resource-config.json.

Do you intend to contribute this as part of this PR or should we add it as a follow up TODO?

We will need to add this to Oracle GraalVM as well, so I would do this as a follow-up to keep both versions in sync.

Does Oracle GraalVM for JDK 21.0.5 include this backport? Is there any way I can see what has been backported or what is supported?

Yes, this backport is the same that will be included in Oracle GraalVM for JDK 21.0.5. The code is not available publicly, but this is an attempt to make this repo's configuration parsing behavior identical to Oracle GraalVM's.

@zakkak
Copy link
Contributor

zakkak commented Nov 1, 2024

Proxy registration as part of the "reflection" field of reachability-metadata.json is equivalent to registration in proxy-config.json. Any method or field registrations on such a type are ignored since the 23.1 builder doesn't support them;

Shouldn't GraalVM print warnings in such cases?

Yes, that's a good idea.

@loicottet are you planning to implement this in this PR?

Furthermore, what do you think about #23 (comment):

I see, thank you for the clarification. I wonder if it's worth printing a warning to notify the user that some reachability handlers got ignored (ideally with some info about the LinkafeError, but that won't be trivial I guess).

I think other than that you have addressed all comments/questions. Thank you!

@loicottet
Copy link
Member Author

@loicottet are you planning to implement this in this PR?

I answered this above, I will do it in a follow-up PR to keep the Oracle version in sync with this one.

Furthermore, what do you think about #23 (comment):

Answered the comment

Copy link
Contributor

@zakkak zakkak left a comment

Choose a reason for hiding this comment

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

Approved on the condition that a follow up will:

  1. Print a warning when method or field registrations of proxy types are ignored since the 23.1 builder doesn't support them.

  2. Print a warning when classes that would otherwise be added to the list of reachability handlers are ignored because they throw a linkage error when resolved

I plan to merge this PR next week if there are no objections from @graalvm/community-maintainers .

Thank you @loicottet

@jerboaa
Copy link
Contributor

jerboaa commented Nov 4, 2024

I plan to merge this PR next week if there are no objections from @graalvm/community-maintainers .

No objection. We should try to get it in early for the 23.1.6 dev cycle.

@zakkak zakkak merged commit 981e384 into graalvm:master Nov 7, 2024
12 checks passed
@zakkak
Copy link
Contributor

zakkak commented Nov 7, 2024

The "follow up conditions" are tracked in #29

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
OCA Verified All contributors have signed the Oracle Contributor Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants