Cannot build GraalVM native image due to timeout thread starting during image creation

Description

When attempting to build a native image of a Clojure core.async program that uses `timeout` using GraalVM's `native-image` functionality, GraalVM throws, with the following trace:

```
clark$> boot build-native-image
Compiling 1/2 timeout.core...
Compiling 2/2 timeout.core-test...
Writing pom.xml and pom.properties...
Adding uberjar entries...
Writing target dir(s)...
Building native image
Build on Server(pid: 2056, port: 26681)
classlist: 1,600.78 ms
(cap): 793.28 ms
setup: 1,029.93 ms
analysis: 3,805.72 ms

error: Must not have a started Thread in the image heap.
Detailed message:
Error: Must not have a started Thread in the image heap.
Trace: object java.util.concurrent.locks.AbstractQueuedSynchronizer$Node
object java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject
object java.util.concurrent.DelayQueue
object clojure.lang.Var
method clojure.core.async.impl.timers$timeout.invokeStatic(long)
Call path from entry point to clojure.core.async.impl.timers$timeout.invokeStatic(long):
at clojure.core.async.impl.timers$timeout.invokeStatic(timers.clj:43)
at clojure.core.async.impl.timers$timeout.invoke(timers.clj:43)
at clojure.tools.reader.default_data_readers.proxy$java.lang.ThreadLocal$ff19274a.toString(Unknown Source)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at com.oracle.svm.core.amd64.AMD64CPUFeatureAccess.verifyHostSupportsArchitecture(AMD64CPUFeatureAccess.java:163)
at com.oracle.svm.core.JavaMainWrapper.run(JavaMainWrapper.java:180)
at Lcom/oracle/svm/core/code/CEntryPointCallStubs;.com_002eoracle_002esvm_002ecore_002eJavaMainWrapper_002erun_0028int_002corg_002egraalvm_002enativeimage_002ec_002etype_002
eCCharPointerPointer_0029(generated:0)

Error: Processing image build request failed

```

The actual `native-image` invocation (called as part of that boot task) looks like this:
`native-image -H:+ReportUnsupportedElementsAtRuntime -H:Name=timeout -cp .:target timeout.core`.

The code in the project is this namespace:

```
(ns timeout.core
(:require [clojure.core.async :refer [go timeout <!]])
(:gen-class))

(defn do-timeout-print [m]
(go (while true
(<! (timeout m))
(println "printed"))))

(defn -main
"I don't do a whole lot ... yet."
[& args]
(println "Hello, World!")
(do-timeout-print 1000)
(future (+ 1 1)))
```

I will attach a patch in a bit.

Thanks Alex for encouraging me to file an issue and for the hint that a delay will fix: https://twitter.com/puredanger/status/995079983633780736

Environment

  • OSX 10.13.3

  • Clojure 1.9.0

  • core.async 0.4.474

  • Boot 2.7.2

  • ```
    clark$> java -version
    java version "1.8.0_161"
    Java(TM) SE Runtime Environment (build 1.8.0_161-b12)
    GraalVM 1.0.0-rc1 (build 25.71-b01-internal-jvmci-0.42, mixed mode)
    ```

Activity

Show:
Clark Kampfe
May 12, 2018, 10:48 PM

Alex, let me know if there is an alternate approach to delay that is closer to what you had in mind. Thanks.

Alex Miller
November 19, 2018, 5:39 PM

Committed

Alex Miller
November 19, 2018, 9:25 PM

Added in 0.4.490

Completed

Assignee

Unassigned

Reporter

Clark Kampfe

Labels

None

Approval

None

Patch

None

Priority

Major