Clojure Java взаимодействия для com.google.cloud.storage.StorageImpl - PullRequest
0 голосов
/ 25 февраля 2019

Попытка сделать некоторое 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 с байтовым массивом.

У меня есть в моем repl:

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 ]

0 голосов
/ 25 февраля 2019

Ответ был получен (из seancorfield на слабости клоюрийцев), что 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 []))))

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

0 голосов
/ 25 февраля 2019

Я не уверен, (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 

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

...