java 2023-03-09

I’m attempting to do serious business with Java interop for pretty much the first time. I know way more Clojure than Java. Can someone explain what’s happening here? (An artifacts is an array of bytes that, had I just downloaded it, would be a zip file):

(let [{:keys [artifacts job]} (first batched-with-artifacts)]
  (type artifacts)                                ;; clojure.lang.PersistentVector
  (type (.toArray artifacts))                     ;;[Ljava.lang.Object; ...I thought it would be java.lang.Array or something
  (ByteArrayInputStream. (.toArray artifacts)))   ;; THROWS


Execution error (ClassCastException) at logicgate.pass-fail-stats.data-acquisition/eval53644 (data_acquisition.clj:244). class [Ljava.lang.Object; cannot be cast to class [B ([Ljava.lang.Object; and [B are in module java.base of loader 'bootstrap') 

its an array of objects

[Ljava.lang.Object;
is jvm for array of Objects

an array of primitive bytes is [B

(-> artifacts first type) => java.lang.Long

it doesn't matter the actualy type of the elements

does that mean that what I think is an array of bytes actually isn’t? or do I need to tell Java, you think this is an object but I know more about it, it’s specifically a byte ?

if you look at the other thread I gave some example code for turning a vector of numbers into a byte array

oh shit, you sure did

i went ahead and started trying to apply Alex’s starting point and forgot you did that uh…. not a coercion but….

that transformation

what you have is a vector of java.lang.Longs, those are boxed numbers, numbers as Objects, because the general purpose clojure vector only can hold Objects

i just kind of thought, “well a clojure.lang.PersistentVector probably knows how to become an array, and a ByteInputStream would know what to do with that…”

so when you ask for an array, it returns an object array, which each element is a Long

(.toArray artifacts) => “An array of, I dunno, Stuff. You didn’t say” (into-array Byte/TYPE artifacts) => “Bytes have a type; we’ll get that from the Byte namespace, and specify what this array is full of.”

Byte/TYPE is actually a static field reference

HMM and yet, streams don’t know how to construct from an array of bytes…. I’ve gotta be missing something on either constructors or a hierarchy

(let [bytes (into-array Byte/TYPE artifacts)]
    (BufferedInputStream. bytes) ;; error
    (InputStream. bytes))        ;; error

What I’m attempting to replace is the bit Alex Miller linked where it goes, (ZipInputStream. (BufferedInputStream. (FileInputStream. zip-file)))

you need to wrap the byte array with a bytearrayinputstream

I don’t have a file, so I figured, it’s binary, so that’s InputStream?

an inputstream has extra associate state, so not just the bytes to be read, needs to keep track of where you at in the read

haha ok. I read a comic where someone depicted Java becoming very upset because someone handed it a cup of coffee “But you didn’t say it was a small cup of coffee!!!”

😁 1

and I’m starting to get it

sweeeet

(let [bytes (into-array Byte/TYPE artifacts)]
    (ZipInputStream. (ByteArrayInputStream. bytes)))

oh excellent! I need an overview of these things and I keep ending up in the middle of the dependency web trying to look up down and adjacent