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

2.14.0 Regression: GraalVM Native Image fails #1751

Closed
axelfontaine opened this issue Oct 29, 2022 · 11 comments
Closed

2.14.0 Regression: GraalVM Native Image fails #1751

axelfontaine opened this issue Oct 29, 2022 · 11 comments
Labels
api: storage Issues related to the googleapis/java-storage API. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.

Comments

@axelfontaine
Copy link

axelfontaine commented Oct 29, 2022

On the same project as in googleapis/gax-java#1781

Building a native image with GraalVM 22.3.0, Java 17, google-cloud-storage 2.13.1 and google-cloud-compute 1.13.0 works great.

 Version info: 'GraalVM 22.3.0 Java 17 CE'
 Java version info: '17.0.5+8-jvmci-22.3-b08'
 C compiler: cl.exe (microsoft, x64, 19.33.31630)
 Garbage collector: Serial GC
 5 user-specific feature(s)
 - com.google.api.gax.grpc.nativeimage.GrpcNettyFeature
 - com.google.api.gax.grpc.nativeimage.ProtobufMessageFeature
 - com.google.api.gax.nativeimage.GoogleJsonClientFeature
 - com.google.api.gax.nativeimage.OpenCensusFeature
 - com.oracle.svm.thirdparty.gson.GsonFeature

Bumping google-cloud-storage to 2.14.0 (no other changes) causes the native image build to fail with:

3 fatal errors detected:

1:

Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing io.grpc.netty.shaded.io.netty.channel.nio.AbstractNioChannel.<init>(io.grpc.netty.shaded.io.netty.channel.Channel, java.nio.channels.SelectableChannel, int) 
        at io.grpc.netty.shaded.io.netty.channel.nio.AbstractNioChannel.<init>(AbstractNioChannel.java:80)
        at io.grpc.netty.shaded.io.netty.channel.nio.AbstractNioByteChannel.<init>(AbstractNioByteChannel.java:66)
        at io.grpc.netty.shaded.io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:112)
        at io.grpc.netty.shaded.io.netty.channel.socket.nio.NioSocketChannel.<init>(NioSocketChannel.java:102)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:153)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:104)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureFlowsGraphCreated(MethodTypeFlow.java:83)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.getOrCreateMethodFlowsGraph(MethodTypeFlow.java:65)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.typestate.DefaultSpecialInvokeTypeFlow.onObservedUpdate(DefaultSpecialInvokeTypeFlow.java:61)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:562)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis$1.run(PointsToAnalysis.java:488)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:193)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:177)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.slf4j.jul.JDK14LoggerAdapter are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=org.slf4j.jul.JDK14LoggerAdapter.
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.checkImageHeapInstance(ClassInitializationFeature.java:132)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisUniverse.replaceObject(AnalysisUniverse.java:595)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.replaceObject(AnalysisConstantReflectionProvider.java:177)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.interceptValue(AnalysisConstantReflectionProvider.java:148)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readValue(AnalysisConstantReflectionProvider.java:100)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readFieldValue(AnalysisConstantReflectionProvider.java:79)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil$1.readValue(ConstantFoldUtil.java:55)
	at jdk.internal.vm.compiler/org.graalvm.compiler.core.common.spi.JavaConstantFieldProvider.readConstantField(JavaConstantFieldProvider.java:78)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantFieldProvider.readConstantField(AnalysisConstantFieldProvider.java:72)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil.tryConstantFold(ConstantFoldUtil.java:51)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.asConstant(LoadFieldNode.java:178)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:144)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:135)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:72)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.spi.Canonicalizable$Unary.canonical(Canonicalizable.java:101)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.canonicalizeFixedNode(SimplifyingGraphDecoder.java:214)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.canonicalizeFixedNode(PEGraphDecoder.java:1572)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.canonicalizeFixedNode(InlineBeforeAnalysis.java:192)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.handleFixedNode(SimplifyingGraphDecoder.java:193)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:821)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.processNextNode(InlineBeforeAnalysis.java:240)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:548)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:833)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysis.decodeGraph(InlineBeforeAnalysis.java:98)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:179)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:349)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:93)
	... 13 more

2:

Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing io.grpc.netty.shaded.io.netty.util.ReferenceCountUtil.safeRelease(java.lang.Object) 
Parsing context: <no parsing context available> 
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:153)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:104)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureFlowsGraphCreated(MethodTypeFlow.java:83)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.getOrCreateMethodFlowsGraph(MethodTypeFlow.java:65)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.typestate.DefaultAnalysisPolicy.staticRootMethodGraph(DefaultAnalysisPolicy.java:182)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis.lambda$addRootMethod$0(PointsToAnalysis.java:320)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis$2.run(PointsToAnalysis.java:507)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:193)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:177)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.slf4j.jul.JDK14LoggerAdapter are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=org.slf4j.jul.JDK14LoggerAdapter.
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.checkImageHeapInstance(ClassInitializationFeature.java:132)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisUniverse.replaceObject(AnalysisUniverse.java:595)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.replaceObject(AnalysisConstantReflectionProvider.java:177)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.interceptValue(AnalysisConstantReflectionProvider.java:148)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readValue(AnalysisConstantReflectionProvider.java:100)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readFieldValue(AnalysisConstantReflectionProvider.java:79)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil$1.readValue(ConstantFoldUtil.java:55)
	at jdk.internal.vm.compiler/org.graalvm.compiler.core.common.spi.JavaConstantFieldProvider.readConstantField(JavaConstantFieldProvider.java:78)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantFieldProvider.readConstantField(AnalysisConstantFieldProvider.java:72)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil.tryConstantFold(ConstantFoldUtil.java:51)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.asConstant(LoadFieldNode.java:178)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:144)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:135)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:72)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.spi.Canonicalizable$Unary.canonical(Canonicalizable.java:101)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.canonicalizeFixedNode(SimplifyingGraphDecoder.java:214)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.canonicalizeFixedNode(PEGraphDecoder.java:1572)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.canonicalizeFixedNode(InlineBeforeAnalysis.java:192)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.handleFixedNode(SimplifyingGraphDecoder.java:193)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:821)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.processNextNode(InlineBeforeAnalysis.java:240)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:548)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:833)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysis.decodeGraph(InlineBeforeAnalysis.java:98)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:179)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:349)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:93)
	... 13 more

3:

Fatal error: com.oracle.graal.pointsto.util.AnalysisError$ParsingError: Error encountered while parsing io.grpc.netty.shaded.io.netty.util.ReferenceCountUtil.safeRelease(java.lang.Object, int) 
------------------------------------------------------------------------------------------------------------------------
Parsing context: <no parsing context available> 
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.AnalysisError.parsingError(AnalysisError.java:153)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:104)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureFlowsGraphCreated(MethodTypeFlow.java:83)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.getOrCreateMethodFlowsGraph(MethodTypeFlow.java:65)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.typestate.DefaultAnalysisPolicy.staticRootMethodGraph(DefaultAnalysisPolicy.java:182)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis.lambda$addRootMethod$0(PointsToAnalysis.java:320)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.PointsToAnalysis$2.run(PointsToAnalysis.java:507)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:193)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:177)
	at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: com.oracle.graal.pointsto.constraints.UnsupportedFeatureException: No instances of org.slf4j.jul.JDK14LoggerAdapter are allowed in the image heap as this class should be initialized at image runtime. To see how this object got instantiated use --trace-object-instantiation=org.slf4j.jul.JDK14LoggerAdapter.
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationFeature.checkImageHeapInstance(ClassInitializationFeature.java:132)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.meta.AnalysisUniverse.replaceObject(AnalysisUniverse.java:595)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.replaceObject(AnalysisConstantReflectionProvider.java:177)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.interceptValue(AnalysisConstantReflectionProvider.java:148)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readValue(AnalysisConstantReflectionProvider.java:100)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantReflectionProvider.readFieldValue(AnalysisConstantReflectionProvider.java:79)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil$1.readValue(ConstantFoldUtil.java:55)
	at jdk.internal.vm.compiler/org.graalvm.compiler.core.common.spi.JavaConstantFieldProvider.readConstantField(JavaConstantFieldProvider.java:78)
	at org.graalvm.nativeimage.builder/com.oracle.svm.hosted.ameta.AnalysisConstantFieldProvider.readConstantField(AnalysisConstantFieldProvider.java:72)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.util.ConstantFoldUtil.tryConstantFold(ConstantFoldUtil.java:51)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.asConstant(LoadFieldNode.java:178)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:144)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:135)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.java.LoadFieldNode.canonical(LoadFieldNode.java:72)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.spi.Canonicalizable$Unary.canonical(Canonicalizable.java:101)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.canonicalizeFixedNode(SimplifyingGraphDecoder.java:214)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.canonicalizeFixedNode(PEGraphDecoder.java:1572)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.canonicalizeFixedNode(InlineBeforeAnalysis.java:192)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.SimplifyingGraphDecoder.handleFixedNode(SimplifyingGraphDecoder.java:193)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:821)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.processNextNode(InlineBeforeAnalysis.java:240)
	at jdk.internal.vm.compiler/org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:548)
	at jdk.internal.vm.compiler/org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:833)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.phases.InlineBeforeAnalysis.decodeGraph(InlineBeforeAnalysis.java:98)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:179)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:349)
	at org.graalvm.nativeimage.pointsto/com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:93)
	... 13 more
@product-auto-label product-auto-label bot added the api: storage Issues related to the googleapis/java-storage API. label Oct 29, 2022
@BenWhitehead BenWhitehead added priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns. labels Oct 31, 2022
@BenWhitehead
Copy link
Collaborator

Thank you for bringing this to my attention. I spent some time today investigating what we can do to improve the situation.

Unfortunately, we can't use the same solution here as was implemented for compute in googleapis/java-compute#721. In our case, as of 2.14.0 java-storage does need many of the grpc modules in it's dependencies, so we can't exclude them.

Searching around the web it seems like this type of error isn't all that uncommon, and unfortunately is not always one size fits all to address given the complexities of logging frameworks in the Java ecosystem.

We do have CI setup to test compatibility with native-image -- both for jdk 11 and jdk 17 -- however, we do not have any logging frameworks -- in particular Slf4J -- in use in any of our code, so we are unable to trigger this specific failure. In fact nothing in our entire dependency chain declares a dependency on Slf4J, this happens do to Netty's logging compatibility trying to use the logger it discovers on the class path.

Your means of fixing this error, are to define a native-image.properties resource which explicitly signals the to Graal where these classes should be initialized. I've created a stub project which depends on storage along with slf4j and have found the following to result in a successful build.

src/main/resources/META-INF/native-image/native-image.properties

Args=\
  --initialize-at-build-time=\
    org.slf4j.jul.JDK14LoggerAdapter,\
    org.slf4j.LoggerFactory

@BenWhitehead BenWhitehead added priority: p2 Moderately-important priority. Fix may not be included in next release. and removed priority: p1 Important issue which blocks shipping the next release. Will be fixed prior to next release. labels Oct 31, 2022
@axelfontaine
Copy link
Author

axelfontaine commented Nov 1, 2022

Thank you for the workaround. I can confirm it works.

However for a minor version upgrade it doesn't feel right to be forced to adjust my own config due to transitive dependency issues on your end. I suspect I won't be the only one facing this over time and this will create a steady support load for you.

Is there a way to opt-out of GRPC completely and use REST instead? And if so, which transitive dependencies can then be safely excluded?

@BenWhitehead
Copy link
Collaborator

You're correct it's not ideal, after talking with some folks on the broader java libraries team, unfortunately this issues is not unique to storage and compute. I've asked them to look into a better long term solution for this scenario.

I'll have to do some deeper investigation as to how difficult it would be to remove gRPC dependencies. In general I'm a bit surprised this is happening when using the existing JSON based implementation as we shouldn't be initializing gRPC specific classes unless necessary.

Would it be at all possible for you to share with me how you're initializing your StorageOptions and Storage instances so I might be able to try and trace down how things are being triggered?

Apologies for this causing havoc for you on the minor release.

@axelfontaine
Copy link
Author

It's actually about as trivial as it gets:

val storage: Storage = StorageOptions.newBuilder().setCredentials(credentials).setProjectId(projectId).build().service

To ensure the transport selection without incurring unnecessary dependencies, I see two ways that could work:

  1. Excludes
google-cloud-storage
|- google-cloud-storage-http
|    |- <http dependencies>
|- google-cloud-storage-grpc
     |- <grpc dependencies>

This would make it trivial to exclude google-cloud-storage-grpc and all it's transitive dependencies in one go.

  1. Transitive includes
google-cloud-storage-http
|- google-cloud-storage
|- <http dependencies>

google-cloud-storage-grpc
|- google-cloud-storage
|- <grpc dependencies>

In this case the user would choose which artifact to include.

Currently 1. is more orthogonal to http client selection where one presently also needs to exclude unnecessary dependencies such as google-http-client-apache-v2. Either way a documentation page detailing how to select http clients and transports would probably be a good idea.

@BenWhitehead
Copy link
Collaborator

Thanks for sharing, I'll do some investigation and see what I can figure out.

Unfortunately, at this time we aren't able to restructure the modules as there are common middleware classes which are shared between http and grpc but are not public. Most likely it will end up taking the form of

google-cloud-storage
exclude:
  <grpc only dependencies>

In the case of "only want grpc" there is actually only 1 dependency that would be dropped, as the rest of the http middleware is used by the other identity and auth middleware.

@n12c
Copy link

n12c commented Nov 2, 2022

I was unsatisfied with my dependencies increasing by 30MB with 2.14.0 despite not needing or wanting gRPC, but I found that the situation can be brought under control by excluding:

  • com.google.cloud:google-cloud-core-grpc
  • com.google.api:gax-grpc
  • org.conscrypt:conscrypt-openjdk-uber
  • com.google.api.grpc:*
  • io.grpc:*

And then reincluding io.grpc:grpc-context, which the client no longer functions without. I too would like to see this improved; it should not be necessary to carry around an unused copy of gRPC and Netty.

On a more general note, it doesn't seem like the client should depend on a shaded copy of Netty. This will result in duplicate Netty classes in any application which already uses Netty, directly or transitively. It's easy enough to work around but still a bit of a landmine for the unwary.

@BenWhitehead
Copy link
Collaborator

I spent some time today trying to pair things down as close to 2.13.x and got the following exclusion list.

com.google.api.grpc:gapic-google-cloud-storage-v2
com.google.api.grpc:grpc-google-cloud-storage-v2
com.google.api.grpc:grpc-google-iam-v1
com.google.api.grpc:proto-google-cloud-storage-v2
com.google.api:gax-grpc
com.google.cloud:google-cloud-core-grpc
io.grpc:grpc-alts
io.grpc:grpc-api
io.grpc:grpc-auth
io.grpc:grpc-core
io.grpc:grpc-googleapis
io.grpc:grpc-grpclb
io.grpc:grpc-netty-shaded
io.grpc:grpc-protobuf-lite
io.grpc:grpc-protobuf
io.grpc:grpc-services
io.grpc:grpc-stub
io.grpc:grpc-xds
io.perfmark:perfmark-api
org.conscrypt:conscrypt-openjdk-uber

I was able to successfully run our full JSON integration tests suite with these exclusions.

io.grpc:grpc-context is a dependency of open census, and was present before 2.14.0.

The shaded version of Netty for gRPC was not a light decision made by them, but was done in order to ensure compatibility between the version of Netty used by gRPC. There are many places gRPC -- and Google Cloud Libraries -- is deployed which do not have the ability to change the version of Netty packaged in their platforms/frameworks.

@mpeddada1
Copy link
Contributor

And @axelfontaine a small note on this: we haven't adopted our configuration files for GraalVM 22.3 yet. This not fully related to the error you mentioned but just wanted to provide a heads up since you mentioned GraalVM 22.3.0 in the issue description.

@ddobrin
Copy link

ddobrin commented Nov 14, 2022

@BenWhitehead @axelfontaine - I have updated an app from GraalVm, 22.2 to 22.3 (and Spring Boot 3 which requires it) and the previous codebase does not build anymore.

Not using gRPC or Netty directly.
Updated the client libs BOM from 26.0.0 to 26.1.4 and both behave the same, including the listed above

@mpeddada1
Copy link
Contributor

A quick update on this folks, we're keeping this issue open as we continue to look into the slf4j compatibility issue. To close the loop on #1751 (comment), google-cloud-storage should be compatible with GraalVM 22.3 as of 2.16.0. For any issues related to specifically GraalVM 22.3, please create a new issue.

@mpeddada1
Copy link
Contributor

mpeddada1 commented Jan 20, 2023

Thanks again for reporting this issue! We've added a Common Issues section in our documentation page which now contains more information and suggested workarounds on the SLF4J compatibility issue. Please take a look at it if you are still blocked on this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api: storage Issues related to the googleapis/java-storage API. priority: p2 Moderately-important priority. Fix may not be included in next release. type: bug Error or flaw in code with unintended results or allowing sub-optimal usage patterns.
Projects
None yet
Development

No branches or pull requests

5 participants