NoSuchMethodError when AOT'ing with Clojure 1.10

107 views
Skip to first unread message

Matthew Phillips

unread,
Jan 16, 2019, 12:54:14 AM1/16/19
to Clojure
Hi all,

I have an inexplicable runtime error with a leiningen-generated AOT uberjar that happens when using Clojure 1.10 that doesn't happen with 1.9 (I'm on Java 8 for both compilation and deployment).

The code in question looks like:

(defn make-apns-message [payload]
 
(let [buffer (ByteBuffer/allocate 3072)]
   
(doto buffer
     
(.put (byte 2))
     
(.position (int 5))  ;; this fails
     
(.put (byte 1))                  

     
;;<more .put's etc>

      (.flip))
    (Unpooled/wrappedBuffer buffer)))

When compiled with Clojure 1.10, the call to .position triggers this at runtime:

java.lang.NoSuchMethodError: java.nio.ByteBuffer.position(I)Ljava/nio/ByteBuffer;
        at basis
.apns$make_apns_message.invokeStatic(apns.clj:255)
        at basis
.apns$make_apns_message.invoke(apns.clj:249)
        at basis
.apns$send_queued_apns_messages.invokeStatic(apns.clj:162)
        at basis
.apns$send_queued_apns_messages.invoke(apns.clj:157)
        at basis
.apns$schedule_open_apns$fn__11654$fn__11655.invoke(apns.clj:109)
        at clojure
.core$binding_conveyor_fn$fn__5739.invoke(core.clj:2033)
        at clojure
.lang.AFn.applyToHelper(AFn.java:154)
        at clojure
.lang.RestFn.applyTo(RestFn.java:132)
        at clojure
.lang.Agent$Action.doRun(Agent.java:114)
        at clojure
.lang.Agent$Action.run(Agent.java:163)
        at java
.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
        at java
.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
        at java
.lang.Thread.run(Thread.java:748)


It's very strange because there is only one variant of position in a ByteBuffer that takes a parameter (and I'm compiling with *warn-on-reflection* set to catch this sort of thing). 

Any ideas?

Cheers,

Matt.

Alex Miller

unread,
Jan 16, 2019, 8:07:00 AM1/16/19
to Clojure
Are you absolutely sure you’re not compiling on Java 9? I think Java 9 added a position on ByteBuffer with covariant return (other versions have it on the Buffer super class).

From the error it looks like AOT compilation found the method and compiled it into the byte code, but then that method is not found at runtime. I think from eyeballing things (didn’t try it) that compiling with Java 9 and running on Java 8 could result in this.

Matthew Phillips

unread,
Jan 16, 2019, 6:10:48 PM1/16/19
to Clojure
I am pretty sure I'm using Java 8. I do have both Java 8 and Java 11 installed, but the environment it's built with:

$ java -version
java version "1.8.0_162"
Java(TM) SE Runtime Environment (build 1.8.0_162-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.162-b12, mixed mode)

$ echo $JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_162.jdk/Contents/Home

Same environment, just changing Clojure versions. I assume there's a change between Clojure 1.9 and 1.10 Java interop that explains the difference in behaviour?

But AOT'ing using the wrong version of Java and deploying backwards certainly seems like it fits the problem perfectly, given the change in ByteBuffer between 8 and 9. Will further investigate.

Cheers. And thanks, Alex.

Matthew Phillips

unread,
Jan 16, 2019, 6:46:58 PM1/16/19
to Clojure
I've been able to reproduce this by deliberately building with Java 11/Clojure 1.10, then running on Java 8. Doing the same thing but built with Java 8 is fine.

So, somehow some classes built with Java 11 must have gotten into the build. Time to check my build cleanliness...

Thanks again, and sorry for taking up your time on a silly build error!

Matt.

Alex Miller

unread,
Jan 16, 2019, 6:48:15 PM1/16/19
to clo...@googlegroups.com
Off the top of my head, I think the only stuff in this area is the big bump in the asm bytecode version, which could theoretically come into play here. There were changes in reflection but I don’t think you’re doing reflection. I am going to poke at this some more so it would probably be good to file a CLJ jira to track it, if that’s possible.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to clo...@googlegroups.com
Note that posts from new members are moderated - please be patient with your first post.
To unsubscribe from this group, send email to
clojure+u...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
---
You received this message because you are subscribed to a topic in the Google Groups "Clojure" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/clojure/n6wpzSGj-Z0/unsubscribe.
To unsubscribe from this group and all its topics, send an email to clojure+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Alex Miller

unread,
Jan 16, 2019, 6:49:20 PM1/16/19
to clo...@googlegroups.com
Oh, well disregard my last message then! 
Reply all
Reply to author
Forward
0 new messages