Fork me on GitHub
#shadow-cljs
<
2024-07-05
>
Stefan08:07:20

Hi! I think I'm having a dependency conflict, but I always find this very confusing. I think the problem is with protobuf-java. I just updated MySQL connector/j from 8.4.0 to 9.0.0, and they bumped their protobuf version from 3.x to 4.x. Given this deps.edn:

{:deps {thheller/shadow-cljs {:mvn/version "2.28.10"}
        com.mysql/mysql-connector-j {:mvn/version "9.0.0"}}}
When trying to jack-in using Calva deps.edn+shadow-cljs, I get:
Syntax error compiling at (shadow/cljs/devtools/server/nrepl.clj:1:1).
namespace 'cider.piggieback' not found
When I exclude protobuf:
{:deps {thheller/shadow-cljs {:mvn/version "2.28.10"}
        com.mysql/mysql-connector-j {:mvn/version "9.0.0"
                                     :exclusions [com.google.protobuf/protobuf-java]}}}
the repl starts normally. Assuming that there is an incompatibility in protobuf, this doesn't feel like a safe solution. Looking at the deps tree, this new version of protobuf overrides the one pulled in by com.google.javascript/closure-compiler-unshaded. So what does this mean and how can I solve it? Does this require an update of the google closure compiler to make it compatible with protobuf 4? Thanks for you thoughts...

thheller08:07:04

I assume you are running shadow-cljs embedded in your CLJ server? otherwise there is no reason to ever have mysql java connector as a dependencny with shadow-cljs?

thheller08:07:44

we are not using any protobuf related things from the closure compiler as far as I know, so shouldn't be a problem to just switch it to whatever

Stefan08:07:14

Yes your assumption is correct.

Stefan08:07:46

I'll exclude the protobuf dep then in shadow-cljs and see if that works. Thanks!

Stefan08:07:43

Excluding it from shadow-cljs doesn't change anything. namespace 'cider.piggieback' not found. I'll think about moving away from using the embedded server I guess.

thheller08:07:01

please check the actual exception you get with the full trace

thheller08:07:30

namespace 'cider.piggieback' not found could have a million reasons, should at least verify what the actual cause is

thheller08:07:24

where is the cause?

thheller08:07:38

just run clj and then (require 'cider.piggieback)

Stefan08:07:43

Yeah sorry

Stefan08:07:55

Clojure 1.11.1
user=> (require 'cider.piggieback)
Unexpected error (ClassNotFoundException) macroexpanding if-ns at (cider/piggieback.clj:22:1).
com.google.protobuf.GeneratedMessageV3
user=> *e
#error {
 :cause "com.google.protobuf.GeneratedMessageV3"
 :via
 [{:type clojure.lang.Compiler$CompilerException
   :message "Unexpected error macroexpanding if-ns at (cider/piggieback.clj:22:1)."
   :data #:clojure.error{:phase :macroexpansion, :line 22, :column 1, :source "cider/piggieback.clj", :symbol if-ns}
   :at [clojure.lang.Compiler macroexpand1 "Compiler.java" 7036]}
  {:type java.lang.NoClassDefFoundError
   :message "com/google/protobuf/GeneratedMessageV3"
   :at [java.lang.ClassLoader defineClass1 "ClassLoader.java" -2]}
  {:type java.lang.ClassNotFoundException
   :message "com.google.protobuf.GeneratedMessageV3"
   :at [jdk.internal.loader.BuiltinClassLoader loadClass "BuiltinClassLoader.java" 641]}]
 :trace
 [[jdk.internal.loader.BuiltinClassLoader loadClass "BuiltinClassLoader.java" 641]
  [jdk.internal.loader.ClassLoaders$AppClassLoader loadClass "ClassLoaders.java" 188]
  [java.lang.ClassLoader loadClass "ClassLoader.java" 526]
  [java.lang.ClassLoader defineClass1 "ClassLoader.java" -2]
  [java.lang.ClassLoader defineClass "ClassLoader.java" 1027]
  [java.security.SecureClassLoader defineClass "SecureClassLoader.java" 150]
  [jdk.internal.loader.BuiltinClassLoader defineClass "BuiltinClassLoader.java" 862]
  [jdk.internal.loader.BuiltinClassLoader findClassOnClassPathOrNull "BuiltinClassLoader.java" 760]
  [jdk.internal.loader.BuiltinClassLoader loadClassOrNull "BuiltinClassLoader.java" 681]
  [jdk.internal.loader.BuiltinClassLoader loadClass "BuiltinClassLoader.java" 639]
  [jdk.internal.loader.ClassLoaders$AppClassLoader loadClass "ClassLoaders.java" 188]
  [java.lang.ClassLoader loadClass "ClassLoader.java" 526]
  [com.google.javascript.jscomp.resources.ResourceLoader loadGlobalConformance "ResourceLoader.java" 53]
  [com.google.javascript.jscomp.CompilerOptions <clinit> "CompilerOptions.java" 1130]
  [java.lang.Class forName0 "Class.java" -2]
  [java.lang.Class forName "Class.java" 534]
  [java.lang.Class forName "Class.java" 513]
  [clojure.lang.RT classForName "RT.java" 2209]
  [clojure.lang.RT classForName "RT.java" 2218]
  [cljs.closure__init __init2 nil -1]
  [cljs.closure__init <clinit> nil -1]
  [java.lang.Class forName0 "Class.java" -2]
  [java.lang.Class forName "Class.java" 534]
  [java.lang.Class forName "Class.java" 513]
  [clojure.lang.RT classForName "RT.java" 2209]
  [clojure.lang.RT classForName "RT.java" 2218]
  [clojure.lang.RT loadClassForName "RT.java" 2237]
  [clojure.lang.RT load "RT.java" 449]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6908 invoke "core.clj" 6161]
  [clojure.core$load invokeStatic "core.clj" 6160]
  [clojure.core$load doInvoke "core.clj" 6144]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5933]
  [clojure.core$load_one invoke "core.clj" 5928]
  [clojure.core$load_lib$fn__6850 invoke "core.clj" 5975]
  [clojure.core$load_lib invokeStatic "core.clj" 5974]
  [clojure.core$load_lib doInvoke "core.clj" 5953]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 6016]
  [clojure.core$load_libs doInvoke "core.clj" 6000]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 6038]
  [clojure.core$require doInvoke "core.clj" 6038]
  [clojure.lang.RestFn invoke "RestFn.java" 2088]
  [cljs.repl$loading__6706__auto____7501 invoke "repl.cljc" 9]
  [cljs.repl__init load nil 9]
  [cljs.repl__init <clinit> nil -1]
  [java.lang.Class forName0 "Class.java" -2]
  [java.lang.Class forName "Class.java" 534]
  [java.lang.Class forName "Class.java" 513]
  [clojure.lang.RT classForName "RT.java" 2209]
  [clojure.lang.RT classForName "RT.java" 2218]
  [clojure.lang.RT loadClassForName "RT.java" 2237]
  [clojure.lang.RT load "RT.java" 449]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6908 invoke "core.clj" 6161]
  [clojure.core$load invokeStatic "core.clj" 6160]
  [clojure.core$load doInvoke "core.clj" 6144]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5933]
  [clojure.core$load_one invoke "core.clj" 5928]
  [clojure.core$load_lib$fn__6850 invoke "core.clj" 5975]
  [clojure.core$load_lib invokeStatic "core.clj" 5974]
  [clojure.core$load_lib doInvoke "core.clj" 5953]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 6016]
  [clojure.core$load_libs doInvoke "core.clj" 6000]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 6038]
  [clojure.core$require doInvoke "core.clj" 6038]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [cider.piggieback$if_ns$fn__1033 invoke "piggieback.clj" 13]
  [cider.piggieback$if_ns invokeStatic "piggieback.clj" 12]
  [cider.piggieback$if_ns invoke "piggieback.clj" 9]
  [clojure.lang.AFn applyToHelper "AFn.java" 171]
  [clojure.lang.AFn applyTo "AFn.java" 144]
  [clojure.lang.Var applyTo "Var.java" 705]
  [clojure.lang.Compiler macroexpand1 "Compiler.java" 7010]
  [clojure.lang.Compiler macroexpand "Compiler.java" 7092]
  [clojure.lang.Compiler eval "Compiler.java" 7178]
  [clojure.lang.Compiler load "Compiler.java" 7653]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6908 invoke "core.clj" 6161]
  [clojure.core$load invokeStatic "core.clj" 6160]
  [clojure.core$load doInvoke "core.clj" 6144]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5933]
  [clojure.core$load_one invoke "core.clj" 5928]
  [clojure.core$load_lib$fn__6850 invoke "core.clj" 5975]
  [clojure.core$load_lib invokeStatic "core.clj" 5974]
  [clojure.core$load_lib doInvoke "core.clj" 5953]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 6016]
  [clojure.core$load_libs doInvoke "core.clj" 6000]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 6038]
  [clojure.core$require doInvoke "core.clj" 6038]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [user$eval1 invokeStatic "NO_SOURCE_FILE" 1]
  [user$eval1 invoke "NO_SOURCE_FILE" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7194]
  [clojure.lang.Compiler eval "Compiler.java" 7149]
  [clojure.core$eval invokeStatic "core.clj" 3215]
  [clojure.core$eval invoke "core.clj" 3211]
  [clojure.main$repl$read_eval_print__9206$fn__9209 invoke "main.clj" 437]
  [clojure.main$repl$read_eval_print__9206 invoke "main.clj" 437]
  [clojure.main$repl$fn__9215 invoke "main.clj" 458]
  [clojure.main$repl invokeStatic "main.clj" 458]
  [clojure.main$repl_opt invokeStatic "main.clj" 522]
  [clojure.main$main invokeStatic "main.clj" 667]
  [clojure.main$main doInvoke "main.clj" 616]
  [clojure.lang.RestFn invoke "RestFn.java" 397]
  [clojure.lang.AFn applyToHelper "AFn.java" 152]
  [clojure.lang.RestFn applyTo "RestFn.java" 132]
  [clojure.lang.Var applyTo "Var.java" 705]
  [clojure.main main "main.java" 40]]}

thheller09:07:14

hmm ok yeah I guess that class doesn't exist then anymore

thheller09:07:39

seems the closure compiler can't do without it

Stefan09:07:38

Wonderful thing, backward compatibility 😞

thheller09:07:54

yeah google is absolutely terrible in that department

Stefan09:07:59

Anyway, no more embedded shadow then. Thanks for looking into it Thomas!

phill09:07:30

Can you exclude protobuf from the reference to the mysql library in deps.edn? (That is: is it possible that your actual use of MySQL does not make the mysql-connector actually use protobuf?)

Stefan09:07:26

Maybe but that sounds quite scary (mission critical, database, you know...)

Stefan10:07:42

I think MySQL connector only uses protobuf for "x dev-api", not sure what that is but good chance that we're not using that (datomic). Maybe I can indeed safely exclude it.

âž• 1