Clojure Java взаимодействия для com.google.cloud.storage.StorageImpl

Попытка взаимодействия с Java с помощью https://github.com/googleapis/google-cloud-java/blob/master/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java#L139 - create метод с байтовым массивом.

Я имею в своем ответе:

user=> (->> s r/reflect :members 
               (filter #(instance? clojure.reflect.Method %)) 
               (filter #(:public (:flags %))) 
               (filter #(= (str (:name %)) "create")) 
               (print-table [:name :flags :parameter-types]))

|  :name |              :flags |                                                                                           :parameter-types |
|--------+---------------------+------------------------------------------------------------------------------------------------------------|
| create | #{:varargs :public} |             [com.google.cloud.storage.BlobInfo byte<> com.google.cloud.storage.Storage$BlobTargetOption<>] |

(Есть и другие, но это кажется наиболее актуальным.)

Также:

user=> s
#object[com.google.cloud.storage.StorageImpl 0x57fb59c8 "com.google.cloud.storage.StorageImpl@57fb59c8"]
user=> blob-info
#object[com.google.cloud.storage.BlobInfo$BuilderImpl 0x1e8ce729 "com.google.cloud.storage.BlobInfo$BuilderImpl@1e8ce729"]
user=> b
#whidbey/bin "SEVZIE1ZIEdVWQ==“

Но когда я иду, чтобы позвонить .create, Я получил:

user=> (.create s blob-info (bytes b))

java.lang.IllegalArgumentException: No matching method create found taking 2 args for class com.google.cloud.storage.StorageImpl

Если я попытаюсь добавить nil в качестве третьего аргумента я получаю ту же ошибку с 3 args,

Я что-то упускаю здесь очевидное? Спасибо!

Редактировать: Как обрабатывать аргументы Java переменной длины в clojure? был очень похож и более универсален (что хорошо). Этот вопрос оказался конкретным вопросом об одном конкретном create подпись функции.

2 ответа

В конечном итоге ответ (из Seancorfield на Clojurians провисать), что blob-info был BuilderImpl внутренний класс и должен быть фактическим BlobInfo, Код, который работает:

(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)
        builder (doto
                  (BlobInfo/newBuilder blob-id)
                  (.setContentType content-type))]

    (.build builder)))

(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 []))))

Не требуется указывать тип подсказки - просто нужно, чтобы типы правильно выстроились.

Я не уверен (bytes b) правильный синтаксис (что такое #whidbey/bin???).

Может быть попробовать

(byte-array [1 2 3]) 

или похожие. Вы также можете попробовать набрать текст в параметре:

(.create s 
    blob-info
    ^"[B" (byte-array [1 2 3])    ; type-hinted param
)

Обновить

Вот пример подсказки типа, который, я думаю, вам нужен:

(let [byte-array-obj  (byte-array [1 2 3])
      sss             (java.util.Arrays/toString  ^"[B"  byte-array-obj) ]
    (spyxx byte-array-obj)
    (spyx (type byte-array-obj))
    (spyx (aget byte-array-obj 2))
    (spyx sss))

с результатом:

byte-array-obj => <#[B #object["[B" 0x26071f95 "[B@26071f95"]>
(type byte-array-obj) => [B
(aget byte-array-obj 2) => 3
sss => "[1, 2, 3]"

Обратите внимание, что Clojure имеет простой способ ввода подсказок, не прибегая к java-native "[B" синтаксис строки:

(java.util.Arrays/toString ^"[B"  byte-array-obj)  ; type hint using a string
(java.util.Arrays/toString ^bytes byte-array-obj)  ; Clojure "build-in" type hint 

оба из которых эквивалентны.

Другие вопросы по тегам