This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-02-25
Channels
- # announcements (5)
- # beginners (74)
- # boot (5)
- # cider (57)
- # cljdoc (5)
- # cljs-dev (45)
- # clojure (37)
- # clojure-dev (6)
- # clojure-europe (4)
- # clojure-italy (17)
- # clojure-nl (11)
- # clojure-spec (48)
- # clojure-uk (96)
- # clojurescript (79)
- # cursive (17)
- # data-science (1)
- # datomic (27)
- # emacs (2)
- # fulcro (22)
- # immutant (1)
- # java (62)
- # juxt (4)
- # kaocha (4)
- # lein-figwheel (5)
- # leiningen (6)
- # midje (1)
- # mount (1)
- # music (3)
- # nrepl (6)
- # off-topic (49)
- # pathom (10)
- # pedestal (2)
- # re-frame (43)
- # reagent (2)
- # ring (2)
- # shadow-cljs (78)
- # spacemacs (6)
- # test-check (2)
- # tools-deps (4)
So it's (.create s blob-info (bytes b) (into-array BlogTargetOption []))
user=> (.create s blob-info (bytes b) (into-array Storage$BlobTargetOption []))
java.lang.IllegalArgumentException: No matching method create found taking 3 args for class com.google.cloud.storage.StorageImpl
user=>
i got access to BlobStorageOption
from user=> (import [com.google.cloud.storage Storage$BlobTargetOption])
@hoopes You may need to type hint blob-info
as well... It depends how many overloads create
has...
user=> (.create s [^BlobInfo blob-info] b (into-array Storage$BlobTargetOption []))
java.lang.IllegalArgumentException: No matching method create found taking 3 args for class com.google.cloud.storage.StorageImpl
Hmm, it has half a dozen overloads... no wonder it's tough to call 😞
(.create ^BlobInfo blob-info ...)
-- you passed a vector there
user=> (.create s ^BlobInfo blob-info b (into-array Storage$BlobTargetOption []))
java.lang.IllegalArgumentException: No matching method create found taking 3 args for class com.google.cloud.storage.StorageImpl
I've seen people struggle with Google libraries because of this sort of stuff... ¯\(ツ)/¯
haha, so obviously i don't want or expect you to sit here and fiddle with this with me, but it IS possible, right?
Sure. Definitely possible 🙂
I'm happy to try it locally if I know what library you're pulling in (lein/deps coords) and what the code around this looks like
user=> (set! *warn-on-reflection* true)
true
user=> (.create s ^BlobInfo blob-info (bytes b) ^Storage$BlobTargetOption (into-array Storage$BlobTargetOption []))
Reflection warning, /tmp/form-init4534991595574875173.clj:1:1 - call to method create can't be resolved (target class is unknown).
What are s
and b
?
(defn ->blob-info [bucket storage-key]
(let [content-type "text/plain"
blob-id (BlobId/of bucket storage-key)
blob-info (doto
(BlobInfo/newBuilder blob-id)
(.setContentType content-type)
(.build))]
blob-info))
the example i’m trying to follow is here: https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-examples/src/main/java/com/google/cloud/examples/storage/snippets/CreateBlob.java
Dinner time here. Will try the code in 10-15 mins
would greatly appreciate - i have a new baby, and must go attend, but i will check back
(ns my-lib.utils.gcp.storage
(:require [ :as io])
(:import [com.google.cloud.storage
StorageOptions
BlobId
BlobInfo
Storage$BlobTargetOption ]))
(defn get-storage []
(-> (StorageOptions/getDefaultInstance)
(.getService)))
(defn get-blob-info [bucket storage-key]
(let [content-type "text/plain"
blob-id (BlobId/of bucket storage-key)]
(doto
(BlobInfo/newBuilder blob-id)
(.setContentType content-type)
(.build))))
(defn upload-str [bucket storage-key str-to-store]
(let [storage (get-storage)
blob-info (get-blob-info bucket storage-key)
byte-arr (.getBytes str-to-store)]
(.create storage blob-info byte-arr (into-array Storage$BlobTargetOption []))))
user=> (require '[my-lib.utils.gcp.storage :as storage])
user=> (storage/upload-str "my-bucket" "some-new-file.txt" "whoa buddy")
java.lang.IllegalArgumentException: No matching method create found taking 3 args for class com.google.cloud.storage.StorageImpl
Based on that, you almost certainly need to type hint the get-storage
and get-blob-info
functions (add a type hint before the arglist).
(ns my-lib.utils.gcp.storage
(:require [ :as io])
(:import [com.google.cloud.storage
Storage
StorageOptions
BlobId
BlobInfo
Storage$BlobTargetOption ]))
(defn get-storage ^Storage []
(-> (StorageOptions/getDefaultInstance)
(.getService)))
(defn get-blob-info ^BlobInfo [bucket storage-key]
(let [content-type "text/plain"
blob-id (BlobId/of bucket storage-key)]
(doto
(BlobInfo/newBuilder blob-id)
(.setContentType content-type)
(.build))))
(defn upload-str [bucket storage-key str-to-store]
(let [storage (get-storage)
blob-info (get-blob-info bucket storage-key)
byte-arr (.getBytes str-to-store)]
(.create storage
blob-info
byte-arr
(into-array Storage$BlobTargetOption []))))
Try (bytes byte-arr)
(defn upload-str [bucket storage-key str-to-store]
(let [storage (get-storage)
blob-info (get-blob-info bucket storage-key)
byte-arr (.getBytes str-to-store)]
(.create storage
^BlobInfo blob-info
(bytes byte-arr)
(into-array Storage$BlobTargetOption []))))
You don't need the type hint on blob-info
if you have the type hint on the function
This works
user=> (import '(com.google.cloud.storage Storage))
com.google.cloud.storage.Storage
user=> (import '(com.google.cloud.storage BlobInfo))
com.google.cloud.storage.BlobInfo
user=> (import '(com.google.cloud.storage Storage$BlobTargetOption))
com.google.cloud.storage.Storage$BlobTargetOption
user=> (defn get-storage ^Storage [] nil)
#'user/get-storage
user=> (defn get-blob-info ^BlobInfo [] nil)
#'user/get-blob-info
user=> (.create (get-storage) (get-blob-info) (byte-array []) (into-array Storage$BlobTargetOption []))
Execution error (NullPointerException) at user/eval158 (REPL:1).
null
(The NPE is from inside the call -- so it resolves the constructor just fine)
The only variable at this point is byte-arr
-- so that needs to be the correct type.
user=> (def blob-info (storage/get-blob-info "bossjock-convert" "new-file.txt"))
#'user/blob-info
user=> blob-info
#object[com.google.cloud.storage.BlobInfo$BuilderImpl 0x3c690936 "com.google.cloud.storage.BlobInfo$BuilderImpl@3c690936"]
it's a BuilderImpl
, not explicitly a BlobInfo
- but that shouldn't matter to java - does it matter to clojure matching the function to a java method signature?
That's why I used nil
-- I'm trying to eliminate the values and focus on the type hints first.
Since that works (for me), the possibilities are that your byte-arr
is the wrong type (or needs a type hint).
once you have the types working, you can look at the mechanics of your functions.
I certainly would not expect a function that returns a BuildImpl
to be compatible with a BlobInfo
tho'... that seems wrong to me...
OK, your problem is calling .build
inside doto
-- that will return the builder instead of the built thing.
You want (.build (doto (BlobInfo/newBuilder blob-id) (.setContentType content-type)))
ok, seriously, i have to attend to the baby - you are the man, and if we ever meet, it's a party
glad it worked