xsc / thrift-clj

Thrift and Clojure!
http://xsc.github.io/thrift-clj/
MIT License
65 stars 15 forks source link

ClassCastException: Cannot convert String to ByteBuffer #9

Closed mishadoff closed 9 years ago

mishadoff commented 9 years ago

In thrift IDL I have a struct with binary field

struct A {
 1: binary field;
}

What is correct way to create this field on server side?

For example to create binary from int I use

(doto (ByteBuffer/allocate 4)
  (.putInt (int 3))
  (.array)))
xsc commented 9 years ago

This is a weird one. The field is marked as STRING (and it says in the docs that it "[...] is currently a specialized form of the string type [...]"), reading it produces a byte[] array but setting it needs a ByteBuffer. This is inconsistent to say the least...

I'll look into it.

charlie-harvey commented 9 years ago

Anything ever come of this? I just ran into the same issue. Essentially, I cannot set anything as a binary field.

namespace java com.example
struct SomeMessage {
  1: binary body
}
service SomeService {
  1: sendMsg(1:SomeMessage m)
}
(thrift/import
  (:types [com.example SomeMessage])
  (:clients [com.example SomeService]))

(def msg
  (SomeMessage. (ByteBuffer/wrap (.getBytes "the body" "UTF-8"))))

Produces this:

Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to java.nio.ByteBuffer
    at com.example.SomeMessage.setFieldValue(SomeMessage.java:135)
    at ns_225746209.SomeMessage.to_thrift_STAR_(producer.clj:32)
    at thrift_clj.gen.core$__GT_thrift.invoke(core.clj:19)
    at ns404766290$sendMsg.invoke(producer.clj:32)
xsc commented 9 years ago

@charlie-harvey There is 3fbcf1e399fd4dcca7112804eb5d116bb08c846a (from #10), introducing handling of binary fields, with the caveat that there is no longer an automatic conversion to String for string fields. I just noticed that this has never been released - sorry for that.

Could you try out the latest SNAPSHOT? I'll then package a full release once I hear back from you.

[thrift-clj "0.3.0-SNAPSHOT"]
charlie-harvey commented 9 years ago

Works!!

(with-open [c (thrift/connect! Clt "localhost:7007")]
  (Clt/sendAmqpMessage c
    (AmqpMessage. (ByteBuffer/wrap (.getBytes "hello foo")))))
struct AmqpMessage {
  1: binary body,
}

service AmqpForwardingService {
  bool sendAmqpMessage(1:AmqpMessage m)
}

Thanks so much for pushing that out. Huge help.