2

I worked through Developing Clojure on App Engine. I was then attempting to replicate the same functionality using boot. However, I do not know how to include the Google App Engine (non Maven) code in a boot project. Any help getting me past this point is appreciated.

All of the following code is hosted here

Here is the currently working project.clj

(defproject clojure-gae "0.1.0-SNAPSHOT"
  :description "FIXME: write description"
  :url "http://example.com/FIXME"
  :license {:name "Eclipse Public License"
            :url "http://www.eclipse.org/legal/epl-v10.html"}
  :dependencies [[org.clojure/clojure "1.7.0"]
                 [ring "1.4.0-RC2"]
                 [compojure "1.3.4"]
                 [com.google.appengine/appengine-api-1.0-sdk "1.9.31"]]
  :plugins [[lein-ring "0.9.6" :exclusions [org.clojure/clojure]]]
  :ring {:handler clojure-gae.core/app}
  :profiles {:dev
             {:dependencies
              [[com.google.appengine/appengine-api-stubs "1.9.31"]
               [com.google.appengine/appengine-local-runtime "1.9.31"]
               [com.google.appengine/appengine-local-runtime-shared "1.9.31"]]}})

Here is the currently broken build.boot I am working on, based on the previous project.clj.

(set-env!
 :source-paths #{"src"}
 :resource-paths #{"assets"}
 :dependencies '[[compojure "1.3.4"]
                 [com.google.appengine/appengine-api-stubs "1.9.31"]
                 [com.google.appengine/appengine-local-runtime "1.9.31"]
                 [com.google.appengine/appengine-local-runtime-shared "1.9.31"]
                 [org.clojure/clojure "1.7.0"]
                 [pandeiro/boot-http "0.7.1-SNAPSHOT" :scope "test"]
                 [ring "1.4.0-RC2"]])

(require
 '[pandeiro.boot-http :refer :all])

(task-options!
 pom {:project "clojure-gae"
      :version "0.1"}
 jar {:main 'clojure_gae.core
      :manifest {"Description" "A Clojure Application on Google App Engine"}}
 repl {:init-ns 'clojure-gae.core}
 serve {:handler 'clojure-gae.core/app
        :reload true})

(def DEV_DEPENDENCIES '[])

(deftask dev
  "Profile for doing local development"
  []
  (set-env! :dependencies #(reduce conj % DEV_DEPENDENCIES))
  (comp
   (serve)))

It fails with

bash$ boot dev
2016-01-18 21:02:01.826:INFO::clojure-agent-send-off-pool-0: Logging initialized @5139ms
             clojure.lang.ExceptionInfo: java.lang.ClassNotFoundException: com.google.appengine.api.datastore.DatastoreServiceFactory, compiling:(clojure_gae/core.clj:1:1)
    data: {:file
           "/var/folders/f8/brrq5_n902jdb7m3bb8vsvsh0000gn/T/boot.user2792359634710984639.clj",
           :line 27}
java.util.concurrent.ExecutionException: java.lang.ClassNotFoundException: com.google.appengine.api.datastore.DatastoreServiceFactory, compiling:(clojure_gae/core.clj:1:1)
clojure.lang.Compiler$CompilerException: java.lang.ClassNotFoundException: com.google.appengine.api.datastore.DatastoreServiceFactory, compiling:(clojure_gae/core.clj:1:1)
       java.lang.ClassNotFoundException: com.google.appengine.api.datastore.DatastoreServiceFactory
                                      ...
clojure-gae.core/eval1150/loading--auto--       core.clj:    1
                clojure-gae.core/eval1150       core.clj:    1
                                      ...
                     clojure.core/load/fn       core.clj: 5866
                        clojure.core/load       core.clj: 5865
                                      ...
                    clojure.core/load-one       core.clj: 5671
                 clojure.core/load-lib/fn       core.clj: 5711
                    clojure.core/load-lib       core.clj: 5710
                                      ...
                       clojure.core/apply       core.clj:  632
                   clojure.core/load-libs       core.clj: 5749
                                      ...
                       clojure.core/apply       core.clj:  632
                     clojure.core/require       core.clj: 5832
                                      ...
      pandeiro.boot-http.util/resolve-sym       util.clj:    4
     pandeiro.boot-http.impl/ring-handler       impl.clj:   66
           pandeiro.boot-http.impl/server       impl.clj:  102
                                      ...
                        clojure.core/eval       core.clj: 3081
                        boot.pod/eval-in*        pod.clj:  369
                                      ...
                        boot.pod/eval-in*        pod.clj:  372
          pandeiro.boot-http/eval85/fn/fn  boot_http.clj:   51
                                      ...
                       clojure.core/deref       core.clj: 2206
       pandeiro.boot-http/eval85/fn/fn/fn  boot_http.clj:   83
                      boot.core/run-tasks       core.clj:  794
                        boot.core/boot/fn       core.clj:  804
      clojure.core/binding-conveyor-fn/fn       core.clj: 1916
                                      ...

Obviously, boot has no idea how to get the com.google.appengine code. In lein's world, there was the lein localrepo install ... steps I went through (in the article) concerning how to install non Maven projects into my local repository. It seems that the App Engine Jar's should still be in my local repository, but boot does not seem to see them. How do I make the appengine jars visible within my boot project?

Cocoatype
  • 2,572
  • 25
  • 42
Stephen Cagle
  • 14,124
  • 16
  • 55
  • 86
  • 1
    Um, you're missing the dependency `[com.google.appengine/appengine-api-1.0-sdk "1.9.31"]` from your project.clj? – schaueho Jan 19 '16 at 06:56
  • I don't appreciate you telling me I am dumb :] – Stephen Cagle Jan 19 '16 at 07:23
  • 1
    I don't -- I haven't used gae, so this was a (obvious) shot in the dark which is also why this is a comment, not an answer. If it fixes your problem, I'm happy to turn it into an answer. – schaueho Jan 19 '16 at 07:28
  • 1
    Oh dear. Just to be clear, I meant my last comment to be humorous. Apologies if you thought I was being confrontational. Secondly, yes. Your comment did move me forward in this process. Thank you. – Stephen Cagle Jan 19 '16 at 23:16

1 Answers1

2

The jar has to be visible from your classpath. This is similar to this question : leiningen - how to add dependencies for local jars?

But for boot, so adding the location to your line :resource-paths #{"assets"} should work.

For instance, if your jars are in "lib", the previous line should look like this : :resource-paths #{"assets" "lib"}

Note : in your case, installing these with lein localrepo should still work. But boot has a built-in install task https://github.com/boot-clj/boot/blob/master/boot/core/src/boot/task/built_in.clj#L679

To use from the command-line like that : boot install -f warp-0.1.0.jar -p tailrecursion/warp"

Community
  • 1
  • 1
nha
  • 17,623
  • 13
  • 87
  • 133
  • So I tried placing the jars in the `:resource-paths` as you mentioned, no dice. It does not seem to see them. I then tried using `boot install` for both `appengine-local-runtime` and `appengine-local-runtime-shared`. These both failed. Finally I just reverted to using the old `lein localrepo` on both of them. This succeeded. I have updated the github code linked at the top to reflect the current state of things. Any idea why `:resource-paths` is not working and I can't `boot install`? – Stephen Cagle Jan 19 '16 at 23:20
  • @StephenCagle can you try `boot pom add-src jar install` as in this article : http://www.martinklepsch.org/posts/why-boot-is-relevant-for-the-clojure-ecosystem.html ? – nha Jan 20 '16 at 08:09