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

Get ready for strict image heap #3122

Merged
merged 12 commits into from
Nov 8, 2024
Merged

Conversation

sdelamo
Copy link
Contributor

@sdelamo sdelamo commented Sep 12, 2024

In Micronaut Core, we are running already the server tck with --strict-image-heap which will be the default. This pull request runs with --strict-image-heap for GraalVM 21 and it adds some extra --initialize-at-build-time to make the tests pass.

Comment on lines 20 to 21
--initialize-at-build-time=io.micronaut.data.model.JsonDataType \
--initialize-at-build-time=io.micronaut.data.intercept.annotation.DataMethod$OperationType
Copy link
Contributor Author

Choose a reason for hiding this comment

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

I had to add these two build time initializations in a pet project

questionnaire-training/questionnaire-training@ad5ef17

--initialize-at-build-time=io.micronaut.data.model.DataType \
--initialize-at-build-time=io.micronaut.data.annotation.Join$Type \
--initialize-at-build-time=io.micronaut.data.model.JsonDataType \
--initialize-at-build-time=io.micronaut.data.intercept.annotation.DataMethod$OperationType
Copy link
Contributor

Choose a reason for hiding this comment

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

these flags shouldn't be needed if the project upgrades to Micronaut core 4.6.5

Copy link
Contributor

Choose a reason for hiding this comment

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

@sdelamo Can you try it with the latest Core?

Copy link
Contributor

Choose a reason for hiding this comment

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

With latest core and platform, looks like these are not needed for graalvm 21 (still failing for graalvm 17).

# limitations under the License.
#

Args = --initialize-at-build-time=org.bson.internal.ProvidersCodecRegistry \
Copy link
Contributor

Choose a reason for hiding this comment

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

we need to find out what is initialising these types and not include these flags if we don't have to

Copy link
Contributor

Choose a reason for hiding this comment

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

@radovanradic Can you please take a look at why we need this?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes, looks like it is needed because of this:

package org.bson.conversions;

public interface Bson {
    /**
     * This registry includes the following providers:
     * <ul>
     *     <li>{@link ValueCodecProvider}</li>
     *     <li>{@link BsonValueCodecProvider}</li>
     *     <li>{@link DocumentCodecProvider}</li>
     *     <li>{@link CollectionCodecProvider}</li>
     *     <li>{@link IterableCodecProvider}</li>
     *     <li>{@link MapCodecProvider}</li>
     *     <li>{@link Jsr310CodecProvider}</li>
     *     <li>{@link JsonObjectCodecProvider}</li>
     *     <li>{@link BsonCodecProvider}</li>
     *     <li>{@link EnumCodecProvider}</li>
     * </ul>
     * <p>
     * Additional providers may be added in a future release.
     * </p>
     *
     * @since 4.2
     */
    CodecRegistry DEFAULT_CODEC_REGISTRY =
            fromProviders(asList(
                    new ValueCodecProvider(),
                    new BsonValueCodecProvider(),
                    new DocumentCodecProvider(),
                    new CollectionCodecProvider(),
                    new IterableCodecProvider(),
                    new MapCodecProvider(),
                    new Jsr310CodecProvider(),
                    new JsonObjectCodecProvider(),
                    new BsonCodecProvider(),
                    new EnumCodecProvider()));

bunch of these if referred here. When trying to --initialize-at-run-time=org.bson.conversions.Bson then get the exception

[1/8] Initializing...                                                                                    (0.0s @ 0.17GB)
Error: Incompatible change of initialization policy for org.bson.conversions.Bson: trying to change RUN_TIME from 'META-INF/native-image/io.micronaut.data/micronaut-data-mongodb/native-image.properties' in 'file:///dev/projects/micronaut-data/data-mongodb/build/libs/micronaut-data-mongodb-4.10.0-SNAPSHOT.jar' with 'org.bson.conversions.Bson' to BUILD_TIME interface of org.bson.BsonDocument

so looks like we need to have all of these initializations that @sdelamo added.

# limitations under the License.
#

Args = --initialize-at-build-time=io.micronaut.data.model.query.builder.sql.Dialect,io.micronaut.data.model.DataType,io.micronaut.data.annotation.Join$Type
Copy link
Contributor

Choose a reason for hiding this comment

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

With graalvm 21 this is not needed, but is failing without it in graalvm 17 (which is used currently in github).

Copy link
Contributor

Choose a reason for hiding this comment

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

We shouldn't generate enums in metadata anymore. Where does it see them?

Copy link
Contributor

@radovanradic radovanradic Oct 10, 2024

Choose a reason for hiding this comment

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

In graalvm 17 it is failing and suggesting to trace --trace-class-initialization=io.micronaut.data.annotation.Join$Type which tells that Dialect is referring Join.Type here

public enum Dialect {
    /**
     * H2 database.
     */
    H2(true, false,
        EnumSet.of(
            DEFAULT,
            LEFT,
            LEFT_FETCH,
            RIGHT,
            RIGHT_FETCH,
            FETCH,
            INNER
        )),

in graalvm 21 this is not needed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Where does it see the dialect?

Copy link
Contributor

Choose a reason for hiding this comment

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

It is showing long stack trace

Error: Classes that should be initialized at run time got initialized during image building:
 io.micronaut.data.model.query.builder.sql.Dialect was unintentionally initialized at build time. io.micronaut.data.model.query.builder.sql.Dialect caused initialization of this class with the following trace: 
	at io.micronaut.data.model.query.builder.sql.Dialect.<clinit>(Dialect.java:43)
Error: Classes that should be initialized at run time got initialized during image building:

	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Unknown Source)
	at jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
	at jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:568)
	at java.lang.Class.getEnumConstantsShared(Class.java:3837)
	at java.lang.Class.enumConstantDirectory(Class.java:3859)
	at java.lang.Enum.valueOf(Enum.java:267)
	at sun.reflect.annotation.AnnotationParser.parseEnumValue(AnnotationParser.java:479)
	at sun.reflect.annotation.AnnotationParser.parseMemberValue(AnnotationParser.java:344)
	at sun.reflect.annotation.AnnotationParser.parseAnnotation2(AnnotationParser.java:282)
	at sun.reflect.annotation.AnnotationParser.parseAnnotations2(AnnotationParser.java:121)
	at sun.reflect.annotation.AnnotationParser.parseAnnotations(AnnotationParser.java:73)
	at java.lang.Class.createAnnotationData(Class.java:4068)
	at java.lang.Class.annotationData(Class.java:4057)
	at java.lang.Class.createAnnotationData(Class.java:4073)
	at java.lang.Class.annotationData(Class.java:4057)
	at java.lang.Class.getAnnotation(Class.java:3940)
------------------------------------------------------------------------------------------------------------------------	at java.lang.reflect.AnnotatedElement.isAnnotationPresent(AnnotatedElement.java:292)
	at java.lang.Class.isAnnotationPresent(Class.java:3950)
	at com.oracle.svm.hosted.heap.PodFeature.isPodClass(PodSupport.java:270)
	at com.oracle.svm.hosted.SVMHost.computeHubType(SVMHost.java:506)
	at com.oracle.svm.hosted.SVMHost.createHub(SVMHost.java:421)

	at com.oracle.svm.hosted.SVMHost.registerType(SVMHost.java:268)
	at com.oracle.graal.pointsto.meta.AnalysisUniverse.createType(AnalysisUniverse.java:310)
	at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookupAllowUnresolved(AnalysisUniverse.java:220)
	at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookup(AnalysisUniverse.java:197)
	at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookup(AnalysisUniverse.java:78)
	at com.oracle.graal.pointsto.infrastructure.WrappedConstantPool.lookupConstant(WrappedConstantPool.java:178)
	at org.graalvm.compiler.java.BytecodeParser.lookupConstant(BytecodeParser.java:4287)
	at org.graalvm.compiler.java.BytecodeParser.genLoadConstant(BytecodeParser.java:3960)
	at org.graalvm.compiler.java.BytecodeParser.processBytecode(BytecodeParser.java:5167)
	at org.graalvm.compiler.java.BytecodeParser.iterateBytecodesForBlock(BytecodeParser.java:3406)
	at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.iterateBytecodesForBlock(SharedGraphBuilderPhase.java:712)
	at org.graalvm.compiler.java.BytecodeParser.handleBytecodeBlock(BytecodeParser.java:3366)
	at org.graalvm.compiler.java.BytecodeParser.processBlock(BytecodeParser.java:3208)
	at org.graalvm.compiler.java.BytecodeParser.build(BytecodeParser.java:1134)
	at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase$SharedBytecodeParser.build(SharedGraphBuilderPhase.java:152)
	at org.graalvm.compiler.java.BytecodeParser.buildRootMethod(BytecodeParser.java:1026)
	at org.graalvm.compiler.java.GraphBuilderPhase$Instance.run(GraphBuilderPhase.java:97)
	at com.oracle.svm.hosted.phases.SharedGraphBuilderPhase.run(SharedGraphBuilderPhase.java:114)
	at org.graalvm.compiler.phases.Phase.run(Phase.java:49)
	at org.graalvm.compiler.phases.BasePhase.apply(BasePhase.java:434)
	at org.graalvm.compiler.phases.Phase.apply(Phase.java:42)
	at org.graalvm.compiler.phases.Phase.apply(Phase.java:38)
	at com.oracle.graal.pointsto.flow.AnalysisParsedGraph.parseBytecode(AnalysisParsedGraph.java:146)
	at com.oracle.graal.pointsto.meta.AnalysisMethod.parseGraph(AnalysisMethod.java:819)
	at com.oracle.graal.pointsto.meta.AnalysisMethod.ensureGraphParsedHelper(AnalysisMethod.java:784)
	at com.oracle.graal.pointsto.meta.AnalysisMethod.ensureGraphParsed(AnalysisMethod.java:767)
	at com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.lookupEncodedGraph(InlineBeforeAnalysisGraphDecoder.java:120)
	at org.graalvm.compiler.replacements.PEGraphDecoder.doInline(PEGraphDecoder.java:1190)
	at org.graalvm.compiler.replacements.PEGraphDecoder.tryInline(PEGraphDecoder.java:1173)
	at org.graalvm.compiler.replacements.PEGraphDecoder.trySimplifyInvoke(PEGraphDecoder.java:1028)
	at org.graalvm.compiler.replacements.PEGraphDecoder.handleInvoke(PEGraphDecoder.java:982)
	at org.graalvm.compiler.nodes.GraphDecoder.processNextNode(GraphDecoder.java:871)
	at com.oracle.graal.pointsto.phases.InlineBeforeAnalysisGraphDecoder.processNextNode(InlineBeforeAnalysisGraphDecoder.java:186)
	at org.graalvm.compiler.nodes.GraphDecoder.decode(GraphDecoder.java:600)
	at org.graalvm.compiler.replacements.PEGraphDecoder.decode(PEGraphDecoder.java:854)
	at com.oracle.graal.pointsto.phases.InlineBeforeAnalysis.decodeGraph(InlineBeforeAnalysis.java:77)
	at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.parse(MethodTypeFlowBuilder.java:193)
	at com.oracle.graal.pointsto.flow.MethodTypeFlowBuilder.apply(MethodTypeFlowBuilder.java:583)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.createFlowsGraph(MethodTypeFlow.java:165)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.ensureFlowsGraphCreated(MethodTypeFlow.java:152)
	at com.oracle.graal.pointsto.flow.MethodTypeFlow.getOrCreateMethodFlowsGraphInfo(MethodTypeFlow.java:110)
	at com.oracle.graal.pointsto.typestate.DefaultAnalysisPolicy.staticRootMethodGraph(DefaultAnalysisPolicy.java:199)
	at com.oracle.graal.pointsto.PointsToAnalysis.lambda$addRootMethod$0(PointsToAnalysis.java:315)
	at com.oracle.graal.pointsto.PointsToAnalysis$$Lambda$540/0x0000000401a133c0.run(Unknown Source)
	at com.oracle.graal.pointsto.PointsToAnalysis$2.run(PointsToAnalysis.java:493)
	at com.oracle.graal.pointsto.util.CompletionExecutor.executeCommand(CompletionExecutor.java:187)
	at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$executeService$0(CompletionExecutor.java:171)
	at com.oracle.graal.pointsto.util.CompletionExecutor$$Lambda$1065/0x0000000401a873e8.run(Unknown Source)
	at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
	at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
	at java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
	at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
	at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
	at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)

Copy link
Contributor

Choose a reason for hiding this comment

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

And line 43. of Dialect is this again

H2(true, false,
        EnumSet.of(
            DEFAULT,
            LEFT,
            LEFT_FETCH,
            RIGHT,
            RIGHT_FETCH,
            FETCH,
            INNER
        )),

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe we just need Join$Type entry? Not both

Copy link
Contributor

Choose a reason for hiding this comment

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

Need both of these (for 17) Args = --initialize-at-build-time=io.micronaut.data.annotation.Join$Type \ --initialize-at-build-time=io.micronaut.data.model.query.builder.sql.Dialect or else fails again telling Dialect is initialized during build time

Error: Classes that should be initialized at run time got initialized during image building:
 io.micronaut.data.model.query.builder.sql.Dialect was unintentionally initialized at build time. To see why io.micronaut.data.model.query.builder.sql.Dialect got initialized use --trace-class-initialization=io.micronaut.data.model.query.builder.sql.Dialect
To see how the classes got initialized, use --trace-class-initialization=io.micronaut.data.model.query.builder.sql.Dialect

Copy link
Contributor

Choose a reason for hiding this comment

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

Ok, so let's merge it

Copy link
Contributor

Choose a reason for hiding this comment

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

Added back minimal changes to pass graalvm tests on graalvm 17 but we can delete them once we switch to 21.

Copy link

sonarcloud bot commented Nov 8, 2024

@sdelamo sdelamo merged commit fc401b5 into 4.10.x Nov 8, 2024
53 checks passed
@sdelamo sdelamo deleted the get-ready-for-strict-image-heap branch November 8, 2024 12:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants