0

I have a Clojure library that has two gen-class directives. When I run lein run, there are no issues. However, when I run lein uberjar, I get errors:

$ lein uberjar
Compiling 6 source files to /Users/frank/src/user/target/uberjar/classes
Compiling user.common
Compiling user.core
java.lang.ClassNotFoundException: user.server.UserAuthenticationServer, compiling:(user/core.clj:15:30)
Exception in thread "main" java.lang.ClassNotFoundException: user.server.UserAuthenticationServer, compiling:(user/core.clj:15:30)
  at clojure.lang.Compiler.analyzeSeq(Compiler.java:6926)
.....
  at clojure.lang.Compiler.analyze(Compiler.java:6701)
Caused by: java.lang.ClassNotFoundException: user.server.UserAuthenticationServer
  at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
...
  at clojure.lang.Compiler.analyzeSeq(Compiler.java:6919)
  ... 86 more

In addition to the generated java files, there is the project.clj, server.clj, and core.clj.

project.clj

(defproject user "0.1.0-SNAPSHOT"
  :dependencies [[org.clojure/clojure                        "1.9.0-alpha14"]
                 [io.grpc/grpc-core                          "1.7.0"]
                 [io.grpc/grpc-netty                         "1.7.0"
                  :exclusions [io.grpc/grpc-core]]
                 [io.grpc/grpc-protobuf                      "1.7.0"]
                 [io.grpc/grpc-stub                          "1.7.0"]]
  :main ^:skip-aot user.core
  :aot [user.server]
  :target-path "target/%s"
  :source-paths ["src/clj"]
  :java-source-paths ["src/generated/proto"
                      "src/generated/grpc"]
  :profiles {:uberjar {:aot :all}})

core.clj

(ns user.core
  (:import [io.grpc Server ServerBuilder])
  (:gen-class))

(defonce start-server-atom   (atom nil))
(def port                    8080)

(defn start-server []
  (when-not @start-server-atom
    (reset! start-server-atom
            (-> (ServerBuilder/forPort port)
                (.addService (new user.server.UserAuthenticationServer))
                .build
                .start
                .awaitTermination))))

(defn -main
  [& args]
  (start-server))

server.clj

(ns user.server
  (:gen-class
   :main false
   :name user.server.UserAuthenticationServer
   :extends xyz.skroo.user.UserAuthenticationGrpc$UserAuthenticationImplBase))

(defn -startUserAuthentication [this req res]
  (.onNext res req)
  (.onCompleted res))

It's weird because this was working and I think the compile-time order changed and now I cannot generate a standalone jar.

1 Answer 1

3

:profiles {:uberjar {:aot :all}} means that when you run uberjar it will try to compile all Namespaces. When you do lein run it only compiles the namespace in the :aot key.

Try to update the uberjar profile to only aot the server namespace and see if that works.

Sign up to request clarification or add additional context in comments.

1 Comment

That worked! I added both user.core and user.server to the uberjar aot vector.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.