Add native-image metadata for the different ChannelHandler implementations#12738
Conversation
|
cc @violetagg and thank you for helping with testing and cleaning up of the generated metadata :) |
|
@gradinac its really "sad" that we need to always manually update these whenever we add more stuff :( Is there no other way to make this work ? |
|
I agree completely, manual metadata maintenance = bad Right now, we don't have anything on the native-image/native-image-agent side that would help with this particular issue :/ I can push a python script to automate generating these from the collected metadata (and convert the existing bash script that collects metadata into a python script) If the above is okay, I can create a follow up PR with the above python script |
|
It would be good to have a python script. We need to have a build step that checks if this metadata is up to date, so breakage can't sneak in. |
|
I did not have time to fully dive into all the details, but if this may help, in Reactor-Netty, we have a Junit test which scans all handlers using reflection, and the test will fail the build in case one handler is missing from the reflect-config.json. See reactor/reactor-netty#2432 More specifically, see the junit test which performs the checking. |
|
@pderop using the Reflections library in a JUnit test to find all implementations of the |
I think that |
There was a problem hiding this comment.
Also one thing I was wonder was if we should really put this in common ? Shouldn't we have the config with the right entries in each artefact that has such a handler ?
There was a problem hiding this comment.
That's a good point - the reason why I put them under the common directory is because these would be available to every project, so we would only have to maintain it in one place. During the image build, only handlers that are reachable (both available on the classpath and used in the application) would be included
I'm looking into the reflections approach for automatically generating this metadata now - if this approach ends up working, I could split the generated metadata on a per-project basis
fe4a00c to
6b3af75
Compare
|
I've tried the The benefits of this approach is that it would run as a standard unit test every time there's a change and point the exact different in metadata (if any), as well as that it would generate metadata on a per-module basis, rather than storing it as a monolithic file inside The downsides are that we have to add a bit of boilerplate code to each project (3 Would this approach be okay? If yes, I can add the necessary bits to the rest of the Netty modules and polish up the PR |
There was a problem hiding this comment.
Maybe we could automatically update the metadata file here, rather than printing a message and letting the users do it
There was a problem hiding this comment.
This one bugged my mind a bit - is there a smarter way to find out if a class originates from the test sources? It would be nice to have all of the test classes filtered automatically, and this seems to work, but it also seems a bit ugly
There was a problem hiding this comment.
Maven seems to always set the current directory to the module it's currently building/testing - this lets us look up the reflect-config.json file directly from the module sources by using a relative path here
There was a problem hiding this comment.
Ideally we don't want to re-write the metadata generation for every test, but we also don't want to bloat up the non-test sources with test specific code. This creates a test-only dependency to the test-jar of netty5-transport where the metadata-generation logic lives
|
It seems like the "is this class a test class" test is failing on Windows - most likely because I messed up the path checking logic. I'll look into it |
|
You'll also need to rebase to avoid the build failing on some certificate validation. Some test certificates expired and have been replaced. |
6b3af75 to
847b681
Compare
|
@chrisvest Thank you for the heads up! :) I've also added the logic for automatic metadata generation to remaining Netty modules that needed it |
|
@gradinac I am correct to assume we would also need this for 4.1 ? |
|
|
||
| System.err.println("Expected metadata file contents:\n"); | ||
| System.err.println(getMetadataJsonString(handlerMetadata)); | ||
| Assertions.fail(); |
There was a problem hiding this comment.
Why not add what you pass to System.err.println() to the fail method ?
There was a problem hiding this comment.
That's a good point, I'll move all System.err.println messages to the fail method instead
| "This metadata was not found under " + existingMetadataPath); | ||
| System.err.println("Please create this file with the following content: "); | ||
| System.err.println(getMetadataJsonString(handlerMetadata)); | ||
| Assertions.fail(); |
There was a problem hiding this comment.
Why not add what you pass to System.err.println() to the fail method ?
| return gson.toJson(metadataList, HANDLER_METADATA_LIST_TYPE); | ||
| } | ||
|
|
||
| private static class Condition { |
There was a problem hiding this comment.
| private static class Condition { | |
| private static final class Condition { |
| this.typeReachable = typeReachable; | ||
| } | ||
|
|
||
| String typeReachable; |
There was a problem hiding this comment.
| String typeReachable; | |
| final String typeReachable; |
| } | ||
|
|
||
| private static class HandlerMetadata { | ||
| String name; |
There was a problem hiding this comment.
| String name; | |
| final String name; |
| private static class HandlerMetadata { | ||
| String name; | ||
|
|
||
| Condition condition; |
There was a problem hiding this comment.
| Condition condition; | |
| final Condition condition; |
|
|
||
| Condition condition; | ||
|
|
||
| boolean queryAllPublicMethods; |
There was a problem hiding this comment.
| boolean queryAllPublicMethods; | |
| final boolean queryAllPublicMethods; |
This is correct - I didn't want to create a Netty 4.1 PR yet though as I wasn't sure if I had taken the right approach for generating this metadata |
de9921e to
07ddd74
Compare
|
I've pushed the changes that should address the review - in the meantime, I've also prepared a Netty 4 PR and gathered the required metadata. Once that metadata is tested, I'll create a Netty 4 PR as well |
|
Thanks a lot! Great work |
|
Thank you very much for looking into this! :) I'll have a PR for Netty 4.1 ready soon with the same approach |
Motivation: Enhance the native image reflect-config.json with conditions This is based on netty/netty#12738 Modification: - Enhance the native image reflect-config.json with conditions - Add test for collecting and comparing the configuration Result: Enhance the native image reflect-config.json with conditions
Motivation: Enhance the native image reflect-config.json with conditions This is based on netty/netty#12738 Modification: - Enhance the native image reflect-config.json with conditions - Add test for collecting and comparing the configuration Result: Enhance the native image reflect-config.json with conditions
Motivation: Enhance the native image reflect-config.json with conditions This is based on netty/netty#12738 Modification: - Enhance the native image reflect-config.json with conditions - Add test for collecting and comparing the configuration Result: Enhance the native image reflect-config.json with conditions
Motivation: Enhance the native image reflect-config.json with conditions This is based on netty/netty#12738 Modification: - Enhance the native image reflect-config.json with conditions - Add test for collecting and comparing the configuration Result: Enhance the native image reflect-config.json with conditions
…#12786) Motivation: #12738 introduced automatic metadata generation for handlers. However, @violetagg rightly noticed that this metadata was not under META-INF. This means it wouldn't automatically be picked up by the native-image builder. This slipped through testing as I was manually merging the metadata before sending it over for tests with an existing Netty version. Modification: Move all generated `reflect-config.json` files from `src/main/resources/native-image/...` to `src/main/resources/META-INF/native-image/` Result: Native-image will properly pick up the generated handler metadata
…andler implementations. (#12794) Motivation: Analogous to #12738, this PR introduces automatic conditional native-image metadata generation for different ChannelHandler implementations Modification: This PR is basically the same as #12738, but adapted to conform to the Java language level 6. This PR also adds the metadata generation to more subprojects that contain ChannelHandler implementations. Result: Fixes #12725
Motivation:
Due to a specific reflection usage pattern in
io.netty5.channel.ChannelHandlerMask#mask0, the agent cannot automatically infer the necessary conditional metadata. Therefor, we must manually add such metadata for subclasses of theChannelHandler.See also #12725 (comment)
Modification:
This PR adds the necessary metadata for handlers used in the Netty 5 testsuite.
Result:
Should fix #12725
Note that for user-defined
ChannelHandlerimplementations, users will still need to supply necessary metadata, either manually or by using the tracing agent