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

[native-image] Netty with native EPoll support #442

Open
Jotschi opened this Issue May 31, 2018 · 6 comments

Comments

3 participants
@Jotschi

Jotschi commented May 31, 2018

I'm trying to build a native image for netty / Vert.x which makes use of the native EPoll library (netty-transport-native-epoll).

The image generation is however failing with error:

Error: Must not have a started Thread in the image heap.

Full Log:
https://gist.github.com/Jotschi/c9ba9e54fed1a7bdb6d1acf4c1f1aaa4

I think this is similar to the error in this issue:
#365

A very basic reproducer can be found in the netty-native-epoll branch:
https://github.com/Jotschi/vertx-graalvm-native-image-test/tree/netty-native-epoll

Native Libs are for linux-amd64 only.

I'm not sure how the JNIConfigurationFiles should actually be used. I added the native classes and all native methods. Let me know whether this is actually needed.

@cstancu cstancu added the substrate label May 31, 2018

@kontrafiktion

This comment has been minimized.

kontrafiktion commented Jun 5, 2018

Would it help to call the static block in ThreadDeathWatcher from the main function?

    static {
        String poolName = "threadDeathWatcher";
        String serviceThreadPrefix = SystemPropertyUtil.get("io.netty.serviceThreadPrefix");
        if (!StringUtil.isNullOrEmpty(serviceThreadPrefix)) {
            poolName = serviceThreadPrefix + poolName;
        }
        // because the ThreadDeathWatcher is a singleton, tasks submitted to it can come from arbitrary threads and
        // this can trigger the creation of a thread from arbitrary thread groups; for this reason, the thread factory
        // must not be sticky about its thread group
        threadFactory = new DefaultThreadFactory(poolName, true, Thread.MIN_PRIORITY, null);
    }

see #424

@Jotschi

This comment has been minimized.

Jotschi commented Jun 5, 2018

@kontrafiktion Thanks. I patched a few more classes and handled the static constructor calls in the main. That solved the issue. I'm now down to two errors.

fatal error: java.lang.NoClassDefFoundError: Could not initialize class io.netty.channel.unix.FileDescriptor
        at sun.misc.Unsafe.ensureClassInitialized(Native Method)
        at jdk.vm.ci.hotspot.HotSpotResolvedObjectTypeImpl.initialize(HotSpotResolvedObjectTypeImpl.java:381)
        at com.oracle.graal.pointsto.meta.AnalysisUniverse.createType(AnalysisUniverse.java:211)
        at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookupAllowUnresolved(AnalysisUniverse.java:191)
        at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookup(AnalysisUniverse.java:168)
        at com.oracle.graal.pointsto.meta.AnalysisField.<init>(AnalysisField.java:102)
        at com.oracle.graal.pointsto.meta.AnalysisUniverse.createField(AnalysisUniverse.java:355)
        at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookupAllowUnresolved(AnalysisUniverse.java:343)
        at com.oracle.graal.pointsto.meta.AnalysisUniverse.lookup(AnalysisUniverse.java:310)
        at com.oracle.graal.pointsto.meta.AnalysisType.convertFields(AnalysisType.java:845)
        at com.oracle.graal.pointsto.meta.AnalysisType.convertInstanceFields(AnalysisType.java:838)
        at com.oracle.graal.pointsto.meta.AnalysisType.getInstanceFields(AnalysisType.java:829)
        at com.oracle.graal.pointsto.flow.context.object.AnalysisObject.getInstanceFieldTypeStore(AnalysisObject.java:207)
        at com.oracle.graal.pointsto.flow.context.object.AnalysisObject.getInstanceFieldFlow(AnalysisObject.java:197)
        at com.oracle.graal.pointsto.flow.StoreFieldTypeFlow$StoreInstanceFieldTypeFlow.onObservedUpdate(StoreFieldTypeFlow.java:158)
        at com.oracle.graal.pointsto.flow.TypeFlow.notifyObservers(TypeFlow.java:345)
        at com.oracle.graal.pointsto.flow.TypeFlow.update(TypeFlow.java:387)
        at com.oracle.graal.pointsto.BigBang$2.run(BigBang.java:498)
        at com.oracle.graal.pointsto.util.CompletionExecutor.lambda$execute$0(CompletionExecutor.java:172)
        at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1402)
        at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:289)
        at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1056)
        at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1692)
        at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:157)
@kontrafiktion

This comment has been minimized.

kontrafiktion commented Jun 6, 2018

Is that the full stack trace? No “caused by ...”?

@Jotschi

This comment has been minimized.

Jotschi commented Jun 6, 2018

@kontrafiktion Yes. That is the full stacktrace.

@kontrafiktion

This comment has been minimized.

kontrafiktion commented Jun 6, 2018

Your article (https://vertx.io/blog/eclipse-vert-x-goes-native/) does not mention how you handle JNI

https://github.com/oracle/graal/blob/master/substratevm/JNI.md

Especially I do not see

-H:+JNI

in your command line.

(But I am admittedly very far out of my depth)

@Jotschi

This comment has been minimized.

Jotschi commented Jun 6, 2018

@kontrafiktion I'm actually using the netty-native-epoll branch to test this and the build.sh script uses the mentioned flag. I'm a bit clueless why the FileDescriptor class can't be initialized. It has some native methods but those should afaik be provided by the netty-transport-native-epoll native lib.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment