2

I have created a luminus project with the following

lein new luminus chess +auth +swagger +cljs

I am trying to use the google datastore api but ran into this problem

Can't call public method of non-public class: public (Google gcloud library)

when trying to call the api from clojure. So I am trying to wrap my use of the api in my own Java code that I then call from my Clojure code.

My code that which imports my java code is simply the following and it doesn't even call code from the gcloud import yet.

(ns chess.routes.home
  (:require [chess.layout :as layout]
            [compojure.core :refer [defroutes GET]]
            [ring.util.http-response :as response]
            [clojure.java.io :as io])
  (:import [gcloud GCloud]))

(defn home-page []

  (layout/render "home.html"))

(defroutes home-routes
  (GET "/" []
       (home-page))
  (GET "/docs" []
       (-> (response/ok (-> "docs/docs.md" io/resource slurp))
       (response/header "Content-Type" "text/plain; charset=utf-8"))))

And my java code is just

package gcloud;

public class GCloud {
    public static void put() {
        System.out.println("sdfsd");

    }

}

Yet when I do lein javac it fails as follows. If I remove the gcloud import from the clojure code then lein javac successfully outputs a class file for my java code in the target directory. But why is lein javac even looking at clojure code at all and not dealing with purely java?

$ lein javac
Exception in thread "main" java.lang.ExceptionInInitializerError
    at clojure.main.<clinit>(main.java:20)
Caused by: java.lang.ClassNotFoundException: gcloud.GCloud, compiling:(chess/routes/home.clj:1:1)
    at clojure.lang.Compiler.load(Compiler.java:7391)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:363)
    at clojure.lang.RT.load(RT.java:453)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    at clojure.core$load.invokeStatic(core.clj:5892)
    at clojure.core$load.doInvoke(core.clj:5876)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5697)
    at clojure.core$load_one.invoke(core.clj:5692)
    at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
    at clojure.core$load_lib.invokeStatic(core.clj:5736)
    at clojure.core$load_lib.doInvoke(core.clj:5717)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$load_libs.invokeStatic(core.clj:5774)
    at clojure.core$load_libs.doInvoke(core.clj:5758)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$require.invokeStatic(core.clj:5796)
    at clojure.core$require.doInvoke(core.clj:5796)
    at clojure.lang.RestFn.invoke(RestFn.java:619)
    at chess.handler$eval25329$loading__5569__auto____25330.invoke(handler.clj:1)
    at chess.handler$eval25329.invokeStatic(handler.clj:1)
    at chess.handler$eval25329.invoke(handler.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6916)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:363)
    at clojure.lang.RT.load(RT.java:453)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    at clojure.core$load.invokeStatic(core.clj:5892)
    at clojure.core$load.doInvoke(core.clj:5876)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5697)
    at clojure.core$load_one.invoke(core.clj:5692)
    at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
    at clojure.core$load_lib.invokeStatic(core.clj:5736)
    at clojure.core$load_lib.doInvoke(core.clj:5717)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$load_libs.invokeStatic(core.clj:5774)
    at clojure.core$load_libs.doInvoke(core.clj:5758)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$require.invokeStatic(core.clj:5796)
    at clojure.core$require.doInvoke(core.clj:5796)
    at clojure.lang.RestFn.invoke(RestFn.java:551)
    at chess.core$eval25323$loading__5569__auto____25324.invoke(core.clj:1)
    at chess.core$eval25323.invokeStatic(core.clj:1)
    at chess.core$eval25323.invoke(core.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6916)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:363)
    at clojure.lang.RT.load(RT.java:453)
    at clojure.lang.RT.load(RT.java:419)
    at clojure.core$load$fn__5677.invoke(core.clj:5893)
    at clojure.core$load.invokeStatic(core.clj:5892)
    at clojure.core$load.doInvoke(core.clj:5876)
    at clojure.lang.RestFn.invoke(RestFn.java:408)
    at clojure.core$load_one.invokeStatic(core.clj:5697)
    at clojure.core$load_one.invoke(core.clj:5692)
    at clojure.core$load_lib$fn__5626.invoke(core.clj:5737)
    at clojure.core$load_lib.invokeStatic(core.clj:5736)
    at clojure.core$load_lib.doInvoke(core.clj:5717)
    at clojure.lang.RestFn.applyTo(RestFn.java:142)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$load_libs.invokeStatic(core.clj:5774)
    at clojure.core$load_libs.doInvoke(core.clj:5758)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invokeStatic(core.clj:648)
    at clojure.core$require.invokeStatic(core.clj:5796)
    at clojure.core$require.doInvoke(core.clj:5796)
    at clojure.lang.RestFn.invoke(RestFn.java:436)
    at user$eval3$loading__5569__auto____4.invoke(user.clj:1)
    at user$eval3.invokeStatic(user.clj:1)
    at user$eval3.invoke(user.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6916)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    at clojure.lang.RT.loadResourceScript(RT.java:372)
    at clojure.lang.RT.loadResourceScript(RT.java:359)
    at clojure.lang.RT.maybeLoadResourceScript(RT.java:355)
    at clojure.lang.RT.doInit(RT.java:475)
    at clojure.lang.RT.<clinit>(RT.java:331)
    ... 1 more
Caused by: java.lang.ClassNotFoundException: gcloud.GCloud
    at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
    at clojure.lang.DynamicClassLoader.findClass(DynamicClassLoader.java:69)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
    at clojure.lang.DynamicClassLoader.loadClass(DynamicClassLoader.java:77)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at clojure.lang.RT.classForName(RT.java:2168)
    at clojure.lang.RT.classForNameNonLoading(RT.java:2181)
    at chess.routes.home$eval30242$loading__5569__auto____30243.invoke(home.clj:1)
    at chess.routes.home$eval30242.invokeStatic(home.clj:1)
    at chess.routes.home$eval30242.invoke(home.clj:1)
    at clojure.lang.Compiler.eval(Compiler.java:6927)
    at clojure.lang.Compiler.eval(Compiler.java:6916)
    at clojure.lang.Compiler.load(Compiler.java:7379)
    ... 90 more

My projects file

(defproject chess "0.1.0-SNAPSHOT"

  :description "FIXME: write description"
  :url "http://example.com/FIXME"

  :dependencies [[bouncer "1.0.0"]
                 [buddy "1.1.0"]
                 [compojure "1.5.1"]
                 [com.google.cloud/google-cloud-datastore "0.7.0"]
                 [cprop "0.1.9"]
                 [luminus-immutant "0.2.2"]
                 [luminus-nrepl "0.1.4"]
                 [markdown-clj "0.9.90"]
                 [metosin/compojure-api "1.1.9"]
                 [metosin/ring-http-response "0.8.0"]
                 [mount "0.1.10"]
                 [org.clojure/clojure "1.8.0"]
                 [org.clojure/clojurescript "1.9.293" :scope "provided"]
                 [org.clojure/tools.cli "0.3.5"]
                 [org.clojure/tools.logging "0.3.1"]
                 [org.webjars.bower/tether "1.3.7"]
                 [org.webjars/bootstrap "4.0.0-alpha.5"]
                 [org.webjars/font-awesome "4.6.3"]
                 [org.webjars/webjars-locator-jboss-vfs "0.1.0"]
                 [reagent "0.5.1"]
                 [ring-middleware-format "0.7.0"]
                 [ring-webjars "0.1.1"]
                 [ring/ring-defaults "0.2.1"]
                 [selmer "1.10.0"]]

  :min-lein-version "2.0.0"

  :jvm-opts ["-server" "-Dconf=.lein-env"]
  :source-paths ["src/clj" "src/cljc"]
  :java-source-paths ["src/java"]
  :resource-paths ["resources" "target/cljsbuild"]
  :target-path "target/%s/"
  :main chess.core

  :plugins [[lein-cprop "1.0.1"]
            [lein-cljsbuild "1.1.4"]
            [lein-immutant "2.1.0"]]
  :clean-targets ^{:protect false}
  [:target-path [:cljsbuild :builds :app :compiler :output-dir] [:cljsbuild :builds :app :compiler :output-to]]
  :figwheel
  {:http-server-root "public"
   :nrepl-port 7002
   :css-dirs ["resources/public/css"]
   :nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}


  :profiles
  {:uberjar {:omit-source true
             :prep-tasks ["compile" ["cljsbuild" "once" "min"]]
             :cljsbuild
             {:builds
              {:min
               {:source-paths ["src/cljc" "src/cljs" "env/prod/cljs"]
                :compiler
                {:output-to "target/cljsbuild/public/js/app.js"
                 :externs ["react/externs/react.js"]
                 :optimizations :advanced
                 :pretty-print false
                 :closure-warnings
                 {:externs-validation :off :non-standard-jsdoc :off}}}}}


             :aot :all
             :uberjar-name "chess.jar"
             :source-paths ["env/prod/clj"]
             :resource-paths ["env/prod/resources"]}

   :dev           [:project/dev :profiles/dev]
   :test          [:project/dev :project/test :profiles/test]

   :project/dev  {:dependencies [[prone "1.1.2"]
                                 [ring/ring-mock "0.3.0"]
                                 [ring/ring-devel "1.5.0"]
                                 [pjstadig/humane-test-output "0.8.1"]
                                 [binaryage/devtools "0.8.2"]
                                 [com.cemerick/piggieback "0.2.2-SNAPSHOT"]
                                 [doo "0.1.7"]
                                 [figwheel-sidecar "0.5.8"]]
                  :plugins      [[com.jakemccrary/lein-test-refresh "0.14.0"]
                                 [lein-doo "0.1.7"]
                                 [lein-figwheel "0.5.8"]
                                 [org.clojure/clojurescript "1.9.293"]]
                  :cljsbuild
                  {:builds
                   {:app
                    {:source-paths ["src/cljs" "src/cljc" "env/dev/cljs"]
                     :compiler
                     {:main "chess.app"
                      :asset-path "/js/out"
                      :output-to "target/cljsbuild/public/js/app.js"
                      :output-dir "target/cljsbuild/public/js/out"
                      :source-map true
                      :optimizations :none
                      :pretty-print true}}}}



                  :doo {:build "test"}
                  :source-paths ["env/dev/clj" "test/clj"]
                  :resource-paths ["env/dev/resources"]
                  :repl-options {:init-ns user}
                  :injections [(require 'pjstadig.humane-test-output)
                               (pjstadig.humane-test-output/activate!)]}
   :project/test {:resource-paths ["env/test/resources"]
                  :cljsbuild
                  {:builds
                   {:test
                    {:source-paths ["src/cljc" "src/cljs" "test/cljs"]
                     :compiler
                     {:output-to "target/test.js"
                      :main "chess.doo-runner"
                      :optimizations :whitespace
                      :pretty-print true}}}}

                  }
   :profiles/dev {}
   :profiles/test {}})
Community
  • 1
  • 1
user782220
  • 10,677
  • 21
  • 72
  • 135
  • Please share your 'project.clj' file. Make sure you got `:java-source-paths` set up properly. – Shlomi Nov 27 '16 at 00:43
  • Well, thats a nice sized `project.clj` :) I would try to pinpoint the problem by having an empty `project clj`, with only `:java-source-paths`, your java class and a clojure file that calls it. It seems that there's some problem finding your class which is usually a problem with the project configuration or the file-system layout. – Shlomi Nov 27 '16 at 01:09
  • @Shlomi If I delete the :profiles key and its value (which is all of the bottom) then curiously lein javac works. So somehow something in the value there causes the clojure code to be compiled??? – user782220 Nov 27 '16 at 02:20
  • What is the exact lein commad you use? Try to add the default profile to your command, like `lein with-profile default javac` and see if that helps, I also had this trouble some time ago but cant remember exactly what I did. – Shlomi Nov 27 '16 at 03:00

1 Answers1

1

Because :dev profile is enabled by default.

You can compile without :dev profile:

lein with-profile -dev javac
Kimi Ma
  • 11
  • 2