[armedbear-devel] is there a good method to read/write java byte arrays?

David Kirkman dkirkman at ucsd.edu
Tue Mar 16 23:06:04 UTC 2010


Does anybody know of a good way to serialize lisp objects into
java byte arrays?  I've got a method that almost works, but if anybody
has a better/canonical way of doing this I'd love to know!

I've been trying to use cl-store, outputting to a stream I create with
sys::%make-byte-array-output-stream, and then getting the byte array with
sys::%get-output-stream-bytes.  I've only been using abcl for a few days,
and I found those functions by grepping through the sources, so I apologize
if I'm inviting trouble by messing around with functions you never meant users
to play with.

Anyway, the output works fine.  But I can't find the equivalent of
sys::%make-byte-array-output-stream to create an input stream, so I
attempted to make my own

(defun make-byte-array-input-stream (bytes)
  (let ((bis (jnew (jconstructor "java.io.ByteArrayInputStream" "[B") bytes)))
    (jnew
     (jconstructor "org.armedbear.lisp.Stream" "java.io.InputStream") bis)))

This almost seems to work, but if I try to use it I get a java
exception and a (very long) java stack trace.  I put a copy of
the stack trace at the end of this message.  Here is an
expression which will produce the problem in abcl-18.1

(let ((outbytes (with-open-stream
                 (stream (sys::%make-byte-array-output-stream))
                 (write-byte 101 stream)
                 (sys::%get-output-stream-bytes stream))))
  ;; now open the byte array as an input stream
  (with-open-stream
   (stream (make-byte-array-input-stream outbytes))
   ;; all works fine until here
   (read-byte stream)))

I don't need to read the stream, asking for the element type of the input
stream is enough to cause trouble ...

(let ((outbytes (with-open-stream
                 (stream (sys::%make-byte-array-output-stream))
                 (write-byte 101 stream)
                 (sys::%get-output-stream-bytes stream))))
  (with-open-stream
   (stream (make-byte-array-input-stream outbytes))
   (stream-element-type stream)))


I can fix the problem and make my code work, but I have to change Stream.java
to make it work.  I added

elementType = UNSIGNED_BYTE_8;

to the initAsBinaryInputStream(InputStream in) method.  I did this because
the stack trace suggested that the problem was stream_element_type.execute()
was returning null.

Anyway, that fixes the problem, and I'm happily serializing/deserializing
lisp objects to a Berkeley DB ... so I guess I'm happy!  But I don't know how
rational that fix is, because I don't really know how Stream is supposed to
work.  I suspect that my 'fix' probably breaks something else that I'm just not
using yet.

Any ideas?

Thanks,

-david k.

Here's the first few lines of the stack trace ...

CL-USER(2): Debugger invoked on condition of type SIMPLE-TYPE-ERROR:
java.lang.NullPointerException
	at org.armedbear.lisp.Primitives$49.execute(Primitives.java:795)
	at org.armedbear.lisp.Symbol.execute(Symbol.java:781)
	at org.armedbear.lisp.LispThread.execute(LispThread.java:579)
	at org.armedbear.lisp.print_8.execute(print.lisp:127)
	at org.armedbear.lisp.Symbol.execute(Symbol.java:781)
	at org.armedbear.lisp.LispThread.execute(LispThread.java:579)
	at org.armedbear.lisp.print_14.execute(print.lisp:279)

...  (and it ends with)

	at org.armedbear.lisp.AutoloadedFunctionProxy.execute(AutoloadedFunctionProxy.java:139)
	at org.armedbear.lisp.Symbol.execute(Symbol.java:760)
	at org.armedbear.lisp.LispThread.execute(LispThread.java:546)
	at org.armedbear.lisp.top_level_51.execute(top-level.lisp:415)
	at org.armedbear.lisp.AutoloadedFunctionProxy.execute(AutoloadedFunctionProxy.java:139)
	at org.armedbear.lisp.LispThread.execute(LispThread.java:546)
	at org.armedbear.lisp.Interpreter.run(Interpreter.java:310)
	at org.armedbear.lisp.Main$1.run(Main.java:50)
	at java.lang.Thread.run(Thread.java:613)
  READ-BYTE: unsupported element type
Debugger invoked on condition of type ERROR:
  Caught java.lang.NullPointerException.
Restarts:
  0: TOP-LEVEL Return to top level.




More information about the armedbear-devel mailing list