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=>
variadic
is the ellipsis after the BlobTargetOption
, ya?
got the same exception when using just b
instead of (bytes b)
as well
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 š
is that right? just pulled from the java interop page
this function call is looking funnier and funnier š
(.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
also tried with (bytes b)
same result
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).
does that make any sense?
[com.google.cloud/google-cloud-storage "1.63.0"]
What are s
and b
?
(import [com.google.cloud.storage
StorageOptions
BlobId
BlobInfo])
(def s (-> (StorageOptions/getDefaultInstance) (.getService)))
(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))
(def b (.getBytes "whoa baby"))
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
thanks so very much!
a hopefully more usable version:
(ns my-lib.utils.gcp.storage
(:require [<http://clojure.java.io|clojure.java.io> :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 [<http://clojure.java.io|clojure.java.io> :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 []))))
still same š type hint the stuff in the (.create ...)
call as well?
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 []))))
aaaaaaaaaand still same error
You don't need the type hint on blob-info
if you have the type hint on the function
yeah, i didn't think so, just grasping at straws a bit
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)
so you think the functions might be doing the wrong thing
The only variable at this point is byte-arr
-- so that needs to be the correct type.
dumb question:
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 - i'm sorry, i have to handle real-life stuff for a bit
i really appreciate your help, and will continue working
if we ever meet, i owe you whatever drink you choose
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)))
BOO YAH
that baby can wait! (jk jk jk jk)
ok, seriously, i have to attend to the baby - you are the man, and if we ever meet, it's a party
thanks man, you're a hero
glad it worked