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 Objectsan 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
https://docs.oracle.com/javase/8/docs/api/java/lang/Byte.html#TYPE
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)) ;; errorWhat 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!!!”
and I’m starting to get it
https://docs.oracle.com/javase/7/docs/api/java/io/package-summary.html
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