taoensso / carmine

Redis client + message queue for Clojure
https://www.taoensso.com/carmine
Eclipse Public License 1.0
1.15k stars 131 forks source link

Fix NoClassDefFoundError when included in uberjar #131

Closed remvee closed 9 years ago

remvee commented 9 years ago

I am getting:

Exception in thread "main" java.lang.NoClassDefFoundError: taoensso/carmine/connections/IConnectionPool

when starting my application from an uberjar which is build with :aot :all. This change makes sure the protocol is compiled and included in the jar file. It probably has something to do with my code using the wcar macro.

Please note: the version of 1.24.1 does not yet exist. , I've submitted a pull request because 1.23.1 and the current 1.24.0 version it do not compile: https://github.com/ptaoussanis/encore/pull/14

ptaoussanis commented 9 years ago

Hi Remco,

Before cutting a new Carmine release - could you maybe confirm that encore v1.24.1 (now on Clojars) actually resolves this error for you? It's not clear to me why you're having problems with encore v1.23.1/v1.24.0 or why that'd produce the error you're describing - would just prefer to double check that we've got the right solution here.

Much appreciated, thanks! :-)

remvee commented 9 years ago

Yes, it does. Thanks.

ptaoussanis commented 9 years ago

Could you tell me what version of Clojure are you using that throws with a 1-arg partial? Am curious to investigate a little more. Thanks :-)

remvee commented 9 years ago

I just tried to reproduce the compilation failure but.. failed. I did so many lein install's to get camine to work from my uberjar I lost track on when I used what. To try and repoduce the compilation error I removed my .m2 but the problem dissappeared. It's some kind of "classpath hell" I guess..

I do have the compilation stacktrace:

Compiling taoensso.carmine.connections
Reflection warning, clojure/tools/reader/impl/commons.clj:112 - call to endsWith can't be resolved.
clojure.lang.ArityException: Wrong number of args (1) passed to: core$partial, compiling:(encore.clj:2134)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3387)
    at clojure.lang.Compiler$DefExpr.eval(Compiler.java:398)
    at clojure.lang.Compiler.compile1(Compiler.java:7035)
    at clojure.lang.Compiler.compile(Compiler.java:7097)
    at clojure.lang.RT.compile(RT.java:387)
    at clojure.lang.RT.load(RT.java:427)
    at clojure.lang.RT.load(RT.java:400)
    at clojure.core$load$fn__4890.invoke(core.clj:5415)
    at clojure.core$load.doInvoke(core.clj:5414)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5227)
    at clojure.core$load_lib.doInvoke(core.clj:5264)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$load_libs.doInvoke(core.clj:5298)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$require.doInvoke(core.clj:5381)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at taoensso.carmine.connections$loading__4784__auto__.invoke(connections.clj:1)
    at clojure.lang.AFn.applyToHelper(AFn.java:159)
    at clojure.lang.AFn.applyTo(AFn.java:151)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3382)
    at clojure.lang.Compiler.compile1(Compiler.java:7035)
    at clojure.lang.Compiler.compile1(Compiler.java:7025)
    at clojure.lang.Compiler.compile(Compiler.java:7097)
    at clojure.lang.RT.compile(RT.java:387)
    at clojure.lang.RT.load(RT.java:427)
    at clojure.lang.RT.load(RT.java:400)
    at clojure.core$load$fn__4890.invoke(core.clj:5415)
    at clojure.core$load.doInvoke(core.clj:5414)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5227)
    at clojure.core$compile$fn__4895.invoke(core.clj:5426)
    at clojure.core$compile.invoke(core.clj:5425)
    at user$eval13$fn__20.invoke(form-init7666833697558150816.clj:1)
    at user$eval13.invoke(form-init7666833697558150816.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6511)
    at clojure.lang.Compiler.eval(Compiler.java:6501)
    at clojure.lang.Compiler.load(Compiler.java:6952)
    at clojure.lang.Compiler.loadFile(Compiler.java:6912)
    at clojure.main$load_script.invoke(main.clj:283)
    at clojure.main$init_opt.invoke(main.clj:288)
    at clojure.main$initialize.invoke(main.clj:316)
    at clojure.main$null_opt.invoke(main.clj:349)
    at clojure.main$main.doInvoke(main.clj:427)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:419)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.main.main(main.java:37)
Caused by: clojure.lang.ArityException: Wrong number of args (1) passed to: core$partial
    at clojure.lang.AFn.throwArity(AFn.java:437)
    at clojure.lang.RestFn.invoke(RestFn.java:412)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.RestFn.applyTo(RestFn.java:132)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3382)
    ... 50 more
Exception in thread "main" clojure.lang.ArityException: Wrong number of args (1) passed to: core$partial, compiling:(encore.clj:2134)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3387)
    at clojure.lang.Compiler$DefExpr.eval(Compiler.java:398)
    at clojure.lang.Compiler.compile1(Compiler.java:7035)
    at clojure.lang.Compiler.compile(Compiler.java:7097)
    at clojure.lang.RT.compile(RT.java:387)
    at clojure.lang.RT.load(RT.java:427)
    at clojure.lang.RT.load(RT.java:400)
    at clojure.core$load$fn__4890.invoke(core.clj:5415)
    at clojure.core$load.doInvoke(core.clj:5414)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5227)
    at clojure.core$load_lib.doInvoke(core.clj:5264)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$load_libs.doInvoke(core.clj:5298)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:603)
    at clojure.core$require.doInvoke(core.clj:5381)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at taoensso.carmine.connections$loading__4784__auto__.invoke(connections.clj:1)
    at clojure.lang.AFn.applyToHelper(AFn.java:159)
    at clojure.lang.AFn.applyTo(AFn.java:151)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3382)
    at clojure.lang.Compiler.compile1(Compiler.java:7035)
    at clojure.lang.Compiler.compile1(Compiler.java:7025)
    at clojure.lang.Compiler.compile(Compiler.java:7097)
    at clojure.lang.RT.compile(RT.java:387)
    at clojure.lang.RT.load(RT.java:427)
    at clojure.lang.RT.load(RT.java:400)
    at clojure.core$load$fn__4890.invoke(core.clj:5415)
    at clojure.core$load.doInvoke(core.clj:5414)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invoke(core.clj:5227)
    at clojure.core$compile$fn__4895.invoke(core.clj:5426)
    at clojure.core$compile.invoke(core.clj:5425)
    at user$eval13$fn__20.invoke(form-init7666833697558150816.clj:1)
    at user$eval13.invoke(form-init7666833697558150816.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6511)
    at clojure.lang.Compiler.eval(Compiler.java:6501)
    at clojure.lang.Compiler.load(Compiler.java:6952)
    at clojure.lang.Compiler.loadFile(Compiler.java:6912)
    at clojure.main$load_script.invoke(main.clj:283)
    at clojure.main$init_opt.invoke(main.clj:288)
    at clojure.main$initialize.invoke(main.clj:316)
    at clojure.main$null_opt.invoke(main.clj:349)
    at clojure.main$main.doInvoke(main.clj:427)
    at clojure.lang.RestFn.invoke(RestFn.java:421)
    at clojure.lang.Var.invoke(Var.java:419)
    at clojure.lang.AFn.applyToHelper(AFn.java:163)
    at clojure.lang.Var.applyTo(Var.java:532)
    at clojure.main.main(main.java:37)
Caused by: clojure.lang.ArityException: Wrong number of args (1) passed to: core$partial
    at clojure.lang.AFn.throwArity(AFn.java:437)
    at clojure.lang.RestFn.invoke(RestFn.java:412)
    at clojure.lang.AFn.applyToHelper(AFn.java:161)
    at clojure.lang.RestFn.applyTo(RestFn.java:132)
    at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3382)
    ... 50 more
Compilation failed: Subprocess failed
ptaoussanis commented 9 years ago

Okay, thanks for trying. May have been some temporary/broken development artifact somewhere along the way. Closing this for now; please feel free to reopen if you run into any further trouble.

Cheers! :-)

remvee commented 9 years ago

It's not the compilation error in encore that's causing the uberjar problems, it's the absence of a pre-compiled IConnectionPool protocol. That's what led me to the, I agree rather strange, issue with partial in encore.

Can you reconsider this pull request? How do I reopen a pull request on gh?

ptaoussanis commented 9 years ago

Have you tried adding taoensso.carmine.connections to your own :aot entries? Have you tried lein clean? Do you have a minimal reproducible example that I could look at?

I never use AOT myself, but don't believe (?) it should be necessary for dependencies to manually do their own AOT compilation. Actually, I suspect that'd be likely to cause problems.

Quick Google turned up some discussions here and here which seem to suggest that :aot :all should be including necessary transitive dependencies for AOT?

How are you importing the IConnectionPool protocol?

remvee commented 9 years ago

I am closing this pull request because it's a leiningen related. I am sorry about the inconvenience.

For future reference: I had :source-paths ["src" "dev"] and :aot true in my profile.clj which, apparently, interact with each other. I am not sure if this is a leiningen bug or me not fully understanding the meaning of :source-paths.

EDIT: Nope, I pinned it down to having a user namespace which required leiningen.core.main to run figwheel from cider which clobbered the uberjar generation.

ptaoussanis commented 9 years ago

No problem, happy you found a resolution :-)