clj-python / libpython-clj

Python bindings for Clojure
Eclipse Public License 2.0
1.05k stars 68 forks source link

Newbie: Lein Clojure Windows Anaconda VSCode Cava REPL Returns (NoClassDefFoundError) #239

Closed israellandes closed 1 year ago

israellandes commented 1 year ago

I'm new to Clojure but have some familiarity with starting a REPL and evaluating statements. I'm trying to follow guides that show how to get a basic project going.

I have only gotten clj-python/libpython-clj "1.3" to work in VSCode Calva REPL, but I run into others errors as other have open Issues about.

Java version:

java 17.0.6 2023-01-17 LTS Java(TM) SE Runtime Environment (build 17.0.6+9-LTS-190) Java HotSpot(TM) 64-Bit Server VM (build 17.0.6+9-LTS-190, mixed mode, sharing)

Anaconda Base Env Python Version:

Python 3.8.12

I'm stuck with this error from output.calva-repl when evaluating line 1 required statement :

; Syntax error (NoClassDefFoundError) compiling at (libpython_clj2\codegen.clj:1:1). ; Could not initialize class libpython_clj2.python__init

Here is my core.clj :

(require '[libpython-clj2.codegen :as codegen])
(codegen/write-namespace!
 "builtins" {:symbol-name-remaps {"AssertionError" "PyAssertionError"
                                  "Exception" "PyException"}})
(require '[python.builtins :as python])
(require '[libpython-clj2.python
           :refer [as-python as-jvm
                   ->python ->jvm
                   get-attr call-attr call-attr-kw
                   get-item initialize!
                   run-simple-string
                   add-module module-dict
                   import-module
                   python-type
                   dir]
           :as py])
(initialize! ; Python executable
 :python-executable "C:\\Users\\Is-Rael\\anaconda3\\python.exe"
             ; Python Library
 :library-path "C:\\Users\\Is-Rael\\anaconda3\\python38.dll"
             ; Anacondas PATH environment to load native dlls of modules (numpy, etc.)
 :windows-anaconda-activate-bat "C:\\Users\\Is-Rael\\anaconda3\\Scripts\\activate.bat")
; To start new VScode REPL and Jack-In use:
; Ctrl + Alt + C & Ctrl + Alt + J
; Example using Normal Python Syntax
; print ("Hey")
; Write in Clojure like:
(defn -main
  "I don't do a whole lot ... yet."
  [& args]
  (println "Hello, World!"))

Here is my log when starting VSCode Calva REPL:

cmd.exe /d /c lein update-in :dependencies conj [nrepl,"1.0.0"] -- update-in :plugins conj [cider/cider-nrepl,"0.28.5"] -- update-in [:repl-options,:nrepl-middleware] conj '["cider.nrepl/cider-middleware"]' -- with-profile +uberjar repl :headless

error {

:cause clojure.core$seq5467 :via [{:type clojure.lang.Compiler$CompilerException :message Syntax error compiling at (libpython_clj2/codegen.clj:1:1). :data #:clojure.error{:phase :compile-syntax-check, :line 1, :column 1, :source libpython_clj2/codegen.clj} :at [clojure.lang.Compiler load Compiler.java 7652]} {:type java.lang.NoClassDefFoundError :message clojure/core$seq5467 :at [clojure.tools.logging.impl$jul_factory invokeStatic impl.clj 213]} {:type java.lang.ClassNotFoundException :message clojure.core$seq5467 :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 520] [clojure.tools.logging.impl$jul_factory invokeStatic impl.clj 213] [clojure.tools.logging.impl$find_factory invokeStatic impl.clj 244] [clojure.tools.logging.impl$find_factory invoke impl.clj 240] [clojure.tools.logginginit load nil 291] [clojure.tools.logginginit nil -1] [java.lang.Class forName0 Class.java -2] [java.lang.Class forName Class.java 467] [clojure.lang.RT classForName RT.java 2212] [clojure.lang.RT classForName RT.java 2221] [clojure.lang.RT loadClassForName RT.java 2240] [clojure.lang.RT load RT.java 449] [clojure.lang.RT load RT.java 424] [clojure.core$load$fn__6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [libpython_clj2.python.info$loading6789auto__175 invoke info.clj 1] [libpython_clj2.python.info__init load nil 1] [libpython_clj2.python.infoinit nil -1] [java.lang.Class forName0 Class.java -2] [java.lang.Class forName Class.java 467] [clojure.lang.RT classForName RT.java 2212] [clojure.lang.RT classForName RT.java 2221] [clojure.lang.RT loadClassForName RT.java 2240] [clojure.lang.RT load RT.java 449] [clojure.lang.RT load RT.java 424] [clojure.core$load$fn6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn__6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [libpython_clj2.python$loading6789auto__173 invoke python.clj 1] [libpython_clj2.pythoninit load nil 1] [libpython_clj2.pythoninit nil -1] [java.lang.Class forName0 Class.java -2] [java.lang.Class forName Class.java 467] [clojure.lang.RT classForName RT.java 2212] [clojure.lang.RT classForName RT.java 2221] [clojure.lang.RT loadClassForName RT.java 2240] [clojure.lang.RT load RT.java 449] [clojure.lang.RT load RT.java 424] [clojure.core$load$fn6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [libpython_clj2.codegen$eval153$loading6738auto__154 invoke codegen.clj 1] [libpython_clj2.codegen$eval153 invokeStatic codegen.clj 1] [libpython_clj2.codegen$eval153 invoke codegen.clj 1] [clojure.lang.Compiler eval Compiler.java 7181] [clojure.lang.Compiler eval Compiler.java 7170] [clojure.lang.Compiler load Compiler.java 7640] [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$fn6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [user$eval147 invokeStatic core.clj 1] [user$eval147 invoke core.clj 1] [clojure.lang.Compiler eval Compiler.java 7181] [clojure.lang.Compiler load Compiler.java 7640] [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$fn6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn__6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [user$eval5 invokeStatic form-init4549718856997273774.clj 1] [user$eval5 invoke form-init4549718856997273774.clj 1] [clojure.lang.Compiler eval Compiler.java 7181] [clojure.lang.Compiler eval Compiler.java 7170] [clojure.lang.Compiler eval Compiler.java 7170] [clojure.lang.Compiler load Compiler.java 7640] [clojure.lang.Compiler loadFile Compiler.java 7578] [clojure.main$load_script invokeStatic main.clj 475] [clojure.main$init_opt invokeStatic main.clj 477] [clojure.main$init_opt invoke main.clj 477] [clojure.main$initialize invokeStatic main.clj 508] [clojure.main$null_opt invokeStatic main.clj 542] [clojure.main$null_opt invoke main.clj 539] [clojure.main$main invokeStatic main.clj 664] [clojure.main$main doInvoke main.clj 616] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.lang.Var applyTo Var.java 705] [clojure.main main main.java 40]]} nREPL server started on port 49301 on host 127.0.0.1 - nrepl://127.0.0.1:49301

Here is my project.clj :

(defproject clojure-app "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
            :url "https://www.eclipse.org/legal/epl-2.0/"}
  :dependencies [[org.clojure/clojure "1.10.2"], [clj-python/libpython-clj "2.024"]]
  :jvm-opts ["--add-modules" "jdk.incubator.foreign"]
  :main ^:skip-aot clojure-app.core
  :target-path "target/%s"
  :profiles {:uberjar {:aot :all
                       :jvm-opts ["-Dclojure.compiler.direct-linking=true"]}})

Lastly, here is the output from my VSC Calva Jack-In:

cmd.exe /d /c lein update-in :dependencies conj [nrepl,"1.0.0"] -- update-in :plugins conj [cider/cider-nrepl,"0.28.5"] -- update-in [:repl-options,:nrepl-middleware] conj '["cider.nrepl/cider-middleware"]' -- with-profile +uberjar repl :headless

error {

:cause clojure.core$seq5467 :via [{:type clojure.lang.Compiler$CompilerException :message Syntax error compiling at (libpython_clj2/codegen.clj:1:1). :data #:clojure.error{:phase :compile-syntax-check, :line 1, :column 1, :source libpython_clj2/codegen.clj} :at [clojure.lang.Compiler load Compiler.java 7652]} {:type java.lang.NoClassDefFoundError :message clojure/core$seq5467 :at [clojure.tools.logging.impl$jul_factory invokeStatic impl.clj 213]} {:type java.lang.ClassNotFoundException :message clojure.core$seq5467 :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 520] [clojure.tools.logging.impl$jul_factory invokeStatic impl.clj 213] [clojure.tools.logging.impl$find_factory invokeStatic impl.clj 244] [clojure.tools.logging.impl$find_factory invoke impl.clj 240] [clojure.tools.logginginit load nil 291] [clojure.tools.logginginit nil -1] [java.lang.Class forName0 Class.java -2] [java.lang.Class forName Class.java 467] [clojure.lang.RT classForName RT.java 2212] [clojure.lang.RT classForName RT.java 2221] [clojure.lang.RT loadClassForName RT.java 2240] [clojure.lang.RT load RT.java 449] [clojure.lang.RT load RT.java 424] [clojure.core$load$fn__6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [libpython_clj2.python.info$loading6789auto__175 invoke info.clj 1] [libpython_clj2.python.info__init load nil 1] [libpython_clj2.python.infoinit nil -1] [java.lang.Class forName0 Class.java -2] [java.lang.Class forName Class.java 467] [clojure.lang.RT classForName RT.java 2212] [clojure.lang.RT classForName RT.java 2221] [clojure.lang.RT loadClassForName RT.java 2240] [clojure.lang.RT load RT.java 449] [clojure.lang.RT load RT.java 424] [clojure.core$load$fn6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn__6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [libpython_clj2.python$loading6789auto__173 invoke python.clj 1] [libpython_clj2.pythoninit load nil 1] [libpython_clj2.pythoninit nil -1] [java.lang.Class forName0 Class.java -2] [java.lang.Class forName Class.java 467] [clojure.lang.RT classForName RT.java 2212] [clojure.lang.RT classForName RT.java 2221] [clojure.lang.RT loadClassForName RT.java 2240] [clojure.lang.RT load RT.java 449] [clojure.lang.RT load RT.java 424] [clojure.core$load$fn6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [libpython_clj2.codegen$eval153$loading6738auto__154 invoke codegen.clj 1] [libpython_clj2.codegen$eval153 invokeStatic codegen.clj 1] [libpython_clj2.codegen$eval153 invoke codegen.clj 1] [clojure.lang.Compiler eval Compiler.java 7181] [clojure.lang.Compiler eval Compiler.java 7170] [clojure.lang.Compiler load Compiler.java 7640] [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$fn6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [user$eval147 invokeStatic core.clj 1] [user$eval147 invoke core.clj 1] [clojure.lang.Compiler eval Compiler.java 7181] [clojure.lang.Compiler load Compiler.java 7640] [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$fn6857 invoke core.clj 6115] [clojure.core$load invokeStatic core.clj 6114] [clojure.core$load doInvoke core.clj 6098] [clojure.lang.RestFn invoke RestFn.java 408] [clojure.core$load_one invokeStatic core.clj 5897] [clojure.core$load_one invoke core.clj 5892] [clojure.core$load_lib$fn__6797 invoke core.clj 5937] [clojure.core$load_lib invokeStatic core.clj 5936] [clojure.core$load_lib doInvoke core.clj 5917] [clojure.lang.RestFn applyTo RestFn.java 142] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$load_libs invokeStatic core.clj 5974] [clojure.core$load_libs doInvoke core.clj 5958] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.core$apply invokeStatic core.clj 669] [clojure.core$require invokeStatic core.clj 5996] [user$eval5 invokeStatic form-init4549718856997273774.clj 1] [user$eval5 invoke form-init4549718856997273774.clj 1] [clojure.lang.Compiler eval Compiler.java 7181] [clojure.lang.Compiler eval Compiler.java 7170] [clojure.lang.Compiler eval Compiler.java 7170] [clojure.lang.Compiler load Compiler.java 7640] [clojure.lang.Compiler loadFile Compiler.java 7578] [clojure.main$load_script invokeStatic main.clj 475] [clojure.main$init_opt invokeStatic main.clj 477] [clojure.main$init_opt invoke main.clj 477] [clojure.main$initialize invokeStatic main.clj 508] [clojure.main$null_opt invokeStatic main.clj 542] [clojure.main$null_opt invoke main.clj 539] [clojure.main$main invokeStatic main.clj 664] [clojure.main$main doInvoke main.clj 616] [clojure.lang.RestFn applyTo RestFn.java 137] [clojure.lang.Var applyTo Var.java 705] [clojure.main main main.java 40]]} nREPL server started on port 49301 on host 127.0.0.1 - nrepl://127.0.0.1:49301

Any help and suggestions are greatly appreciated, thanks!

cnuernber commented 1 year ago

Some of this is due to running the uberjar profile.

I imagine there is aot specified in the uberjar profile. This interacts negatively with the repl classloader and the missing class definition is due to an inner class of clojure.core being redefined as the repl is loading up.

I am curious - why are you running the uberjar profile for you lein repl session?

cnuernber commented 1 year ago

Additionally - the codegen system is meant to be used offline as a preprocess or one time build step - not every repl session. For every repl session you should be using require-python although this interacts negatively with uberjars.

israellandes commented 1 year ago

To answer your question I’m brand new to Clojure and especially Calva, so when I was setting up my REPL I was just always using the default settings. I’ll see if I can avoid use img uberjar, I’m sure I can.

If I’m understanding everything correctly,

  1. Don’t use uberjar
  2. No need for codegen
  3. You mention something about the “missing class definition is due to an inner class of clojure.core being redefined as the repl is loading up.”

Is there a solution I can implement for 3. ?

Im out right now but when I get home tomorrow I’m going to put these suggestions to use and let you know how it goes.

On Thu, Feb 23, 2023 at 7:39 AM Chris Nuernberger @.***> wrote:

Additionally - the codegen system is meant to be used offline as a preprocess or one time build step - not every repl session. For every repl session you should be using require-python although this interacts negatively with uberjars.

— Reply to this email directly, view it on GitHub https://github.com/clj-python/libpython-clj/issues/239#issuecomment-1441999140, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARXQO4WVWWNBJS5TQCSYELDWY6AEZANCNFSM6AAAAAAVFIH6IE . You are receiving this because you authored the thread.Message ID: @.***>

cnuernber commented 1 year ago

For 3., 1. will solve it :-). What I meant about codegen is to run it once and check the file in if you want to go that route. It is faster than require-python and it works with uberjars so it is a bit more general but it is a precompile step that will output a file based on your particular python version at the time so in that sense it is more fragile.

Probably for your use case right now require-python is the right approach. When (if) you build something you want to deploy then moving to codegen and fixing the python version is probably going to result in more stable deployments.

israellandes commented 1 year ago

You were absolutely correct, removing the uberjar checkmark in my Calva REPL loaded up just perfect and everything worked as expected. Thank you a ton, excited to try out this repo. Cheers!