I am attempting to use the gcloud library.
(ns firengine.state (:import [com.google.cloud AuthCredentials] [com.google.cloud.datastore DatastoreOptions])) (-> (DatastoreOptions/builder) (.projectId "<project_id>") (.authCredentials (AuthCredentials/createForJson (clojure.java.io/input-stream service-account-path))) .build) The above clojure code is translated from the following code snippet (ellided, click on "Run elsewhere").
import com.google.cloud.AuthCredentials; import com.google.cloud.datastore.DatastoreOptions; DatastoreOptions options = DatastoreOptions.builder() .projectId(PROJECT_ID) .authCredentials(AuthCredentials.createForJson( new FileInputStream(PATH_TO_JSON_KEY))).build(); When I call this code from the Clojure REPL, I get the following error.
Unhandled java.lang.IllegalArgumentException Can't call public method of non-public class: public com.google.cloud.ServiceOptions$Builder com.google.cloud.ServiceOptions$Builder.projectId(java.lang.String) Reflector.java: 88 clojure.lang.Reflector/invokeMatchingMethod Reflector.java: 28 clojure.lang.Reflector/invokeInstanceMethod boot.user4590132375374459695.clj: 168 firengine.state/eval17529 boot.user4590132375374459695.clj: 167 firengine.state/eval17529 Compiler.java: 6927 clojure.lang.Compiler/eval ... elided ... The com.google.cloud.datastore.DatastoreOptions code can be found here.
Updated June 29, 2016: Pursuant to Schlomi's advice below, I thought that maybe if I AOT compiled my own wrapper around DatastoreOptions that it would work.
(ns firengine.datastore (:import [com.google.cloud AuthCredentials] [com.google.cloud.datastore Datastore DatastoreOptions Entity Key KeyFactory]) (:gen-class :state state :init init :constructors {[String String] []})) (defn -init [^String project-id ^String service-account-path] (let [service-account (clojure.java.io/input-stream service-account-path) credentials (AuthCredentials/createForJson service-account) dsoptions (-> (DatastoreOptions/builder) (.projectId project-id) (.authCredentials credentials) .build)] [[] {:project-id project-id :service-account-path service-account-path :datastore-options dsoptions}])) I modified my boot development task to include the following:
(deftask development "Launch Immediate Feedback Development Environment" [] (comp (aot :namespace '#{firengine.datastore}) (repl :port 6800) (reload) (watch) (cljs) (target :dir #{"target"}))) And I attempted to construct the object like so:
(def service-account-path (System/getenv "FIRENGINE_SERVICE_ACCOUNT_PATH")) (def project-id (System/getenv "PROJECT_ID")) (def datastore-options (firengine.datastore. project-id service-account-path)) Unfortunately, I still get the same error?
clojure.lang.Compiler$CompilerException: java.lang.reflect.InvocationTargetException, compiling:(state.clj:15:1) java.lang.reflect.InvocationTargetException: java.lang.IllegalArgumentException: Can't call public method of non-public class: public com.google.cloud.ServiceOptions$Builder com.google.cloud.ServiceOptions$Builder.projectId(java.lang.String) Am I not really aot compiling firengine.datastore?