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
Unable to create native image for GRPC project #8
Comments
so it is probably just missing the Graal metadata for the GRPC module. We will have to play with it and see if we can get it working. Thanks for the report |
This Netty change might be helpful: netty/netty@f1495e1#diff-5cbe3026d0fe94bd7b8480f692edfb17R15
|
It would be helpful if there weren't other breaking native image related changes in Netty. See micronaut-projects/micronaut-core#1802 |
Currently Micronaut uses Netty version 4.1.30.Final. The latest version (4.1.36.Final) contains --rerun-class-initialization-at-runtime=io.netty.handler.codec.http2.Http2CodecUtil
--initialize-at-run-time=io.netty.handler.codec.http2.DefaultHttp2FrameWriter Those lines are taken from the following Netty change: When those options are applied to the sample project (by adding them to native-image.properties) @Singleton
public class ExampleEndpoint extends ExampleServiceGrpc.ExampleServiceImplBase {
@Override
public void send(ExampleRequest request,
StreamObserver<ExampleReply> responseObserver) {
ExampleReply reply = ExampleReply.newBuilder()
.setMessage("Hi " + request.getName())
.build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
} With the service enabled the native compilation fails again with the following messages: $ ./mvnw clean package && ./docker-build.sh
...
Warning: RecomputeFieldValue.ArrayBaseOffset automatic substitution failed. The automatic substitution registration was attempted because a call to sun.misc.Unsafe.arrayBaseOffset(Class) was detected in the static initializer of com.google.protobuf.UnsafeUtil. Detailed failure reason(s): Could not determine the field where the value produced by the call to sun.misc.Unsafe.arrayBaseOffset(Class) for the array base offset computation is stored. The call is not directly followed by a field store or by a sign extend node followed directly by a field store.
...
Error: Class that is marked for delaying initialization to run time got initialized during image building: com.google.protobuf.ExtensionRegistry. Try marking this class for build-time initialization with --initialize-at-build-time=com.google.protobuf.ExtensionRegistry
Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception
Error: Image build request failed with exit status 1 It seems like com.google.protobuf.UnsafeUtil and com.google.protobuf.ExtensionRegistry needs some configuration in order to work with GraalVM. I've applied those changes to my sample repo: https://github.com/auke-/micronaut-grpc-graal |
@auke- One comment. Please keep in mind that Regarding the error, you can try the suggested fix: |
The last suggestion seems to work, i've added the following options:
This still generates two warnings, but the service seems to work:
I can't find a working alternative for --rerun-class-initialization-at-runtime. |
Nice. To fix those errors I think there need to be some re-computes defined similar to https://github.com/micronaut-projects/micronaut-core/blob/master/http-netty/src/main/java/io/micronaut/http/netty/graal/MicronautSubstitutions.java#L56 For the usages of Other than that the next step would be to include these flags directly in the metadata for the micronaut GRPC project, then each user would not need to do what you had to do. |
@auke- with these flags with GraalVM 19.1 and Micronaut master snapshot I get
I guess there are still issues with the flags being fed to native image |
I've updated the sample project. It works with Micronaut 1.1.3. I have also updated the GraalVM version from 19.0.0 to 19.0.2 and 19.1.0. All versions seem to work with the same options:
I haven't tried 1.1.4, but when I use Micronaut 1.2.0-RC2 the native image compilation fails with the same error you got:
When I remove the options for the Netty packages from the native-image.properties file (and leave the option for the protobuf package) the options look like this:
Now the compilation fails with the following error:
This is caused by the Graal options provided by Netty 4.1.37. When the option for Http2CodecUtil in It looks like option --initialize-at-run-time=io.netty.handler.codec.http2.Http2CodecUtil provided by Netty 4.1.37 doesn't work, or at least doesn't work for Micronaut and GRPC. |
Bummer, one of the problems of having these now embedded in the Netty JAR. I wonder why |
Motivation: The first final version of GraalVM was released which deprecated some flags. We should use the new ones. Modifications: Removes the use of deprecated GraalVM native-image flags Adds a flag to initialize netty at build time. Result: Do not use deprecated flags
I have asked why this flag was added netty/netty@3eff1db#r34249173 |
It was added in netty/netty#9118 in an attempt to remove deprecated flags. |
The error says what is the problem. You are trying to define two conflicting policies for the same class ( Also, |
@vjovanov ok great, but without that flag the following error occurs so it seems like a catch 22 situation:
If one specifies |
You need to put a breakpoint in I am working on a framework to do this for you, but ATM you need to go with the breakpoint. |
so would that involve attaching a debugger to the native image tool |
Yes, you use |
FWIW, I'm still seeing the same issue with a clean generated micronaut project:
|
Adding:
to the |
See micronaut-projects/micronaut-grpc#8: ``` Error: Class that is marked for delaying initialization to run time got initialized during image building: io.netty.handler.codec.http2.Http2CodecUtil. Try marking this class for build-time initialization with --initialize-at-build-time=io.netty.handler.codec.http2.Http2CodecUtil Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception Error: Image build request failed with exit status 1 ``` After debugging, it seems the culprit is `io.netty.handler.codec.http2.Http2ClientUpgradeCodec`, which also needs runtime initialisation.
Created a PR for netty: netty/netty#9593 |
@pete-woods Thanks for looking into it. We will see if we can get updated metadata published for this project |
Cool. I couldn’t figure out where the protobuf metatdata came from |
I have pushed a change that includes the non-Netty metadata in the grpc and protobuf modules (which are typically used separately). |
Motivation: Error: Class that is marked for delaying initialization to run time got initialized during image building: io.netty.handler.codec.http2.Http2CodecUtil. Try marking this class for build-time initialization with --initialize-at-build-time=io.netty.handler.codec.http2.Http2CodecUtil Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception Error: Image build request failed with exit status 1 Modification: After debugging, it seems the culprit is io.netty.handler.codec.http2.Http2ClientUpgradeCodec, which also needs runtime initialisation. Result: Fixes #micronaut-projects/micronaut-grpc#8
Motivation: Error: Class that is marked for delaying initialization to run time got initialized during image building: io.netty.handler.codec.http2.Http2CodecUtil. Try marking this class for build-time initialization with --initialize-at-build-time=io.netty.handler.codec.http2.Http2CodecUtil Error: Use -H:+ReportExceptionStackTraces to print stacktrace of underlying exception Error: Image build request failed with exit status 1 Modification: After debugging, it seems the culprit is io.netty.handler.codec.http2.Http2ClientUpgradeCodec, which also needs runtime initialisation. Result: Fixes #micronaut-projects/micronaut-grpc#8
There's another breakage in the newer Netty here that I've pushed a PR for: netty/netty#9621 |
The PR is merged since netty 4.1.43 it seems which is the netty dependency resolved as of micronaut 1.2.8 and at least for a small sample grpc app it works with graalvm-ce:19.3.0.2 native image. I assume this issue is therefore resolved. |
Thanks for verifying |
Building a native image for a Micronaut GRPC project fails due to the absence of SubstrateVM substitutions for Netty. When the Micronaut HTTP client dependency is added (which pulls in the substitutions) the building of the images fails due to the detection of a direct/mapped ByteBuffer in the image heap, which seems to be caused by the Netty GRPC shutdown handler.
The following steps reproduce the issue:
The project is created with the Micronaut 1.1.3 (but I've also tried 1.2.0 RC1) command line tool:
Building that project fails due to the absence of the SubstrateVM substitutes for Netty:
Micronaut supplies those substitutes with their Netty components, which are also needed when using the Micronaut rest client.
The micronaut-http-client dependency is added to the pom file:
This gives a different error when building the native image:
It seems like it tries to access a ByteBuffer when the shutdown handler is being invoked.
The GraalVM native image support in Micronaut works great for REST services, I would expect the same for GRPC services.
I've created a sample repo to reproduce the issue, see https://github.com/auke-/micronaut-grpc-graal.
The text was updated successfully, but these errors were encountered: