15

I'm trying to pass a binary string in JRuby as a byte[] through some Java library and into JRuby again, where I want to convert it back into a string, but I can't figure out how to do it without the string getting messed up.

Specifically I'm encoding a Ruby hash as BSON and passing it over AMQP, but it's the conversion to and from byte[] that doesn't work. This code

import org.jruby.RubyString
blob = BSON.serialize({'test' => 123123123123}).to_s
p blob
p RubyString.bytes_to_string(RubyString.string_to_bytes(blob))

outputs

"\x13\x00\x00\x00\x12test\x00\xB3\xC3\xB5\xAA\x1C\x00\x00\x00\x00"
"\x13\x00\x00\x00\x12test\x00\xC2\xB3\xC3\x83\xC2\xB5\xC2\xAA\x1C\x00\x00\x00\x00"

I have also tried

java.lang.String.new(blob.to_java.bytes).to_s

but it outputs the same, wrong, string.

Is there any easier/safer way to convert to and from a JRuby string and byte[]?

Theo
  • 131,503
  • 21
  • 160
  • 205

2 Answers2

24

I found the answer myself, turned out there was a #to_java_bytes on String, and a helper method .from_java_bytes that handle the conversion without issue:

blob = BSON.serialize({'test' => 123123123123}).to_s
p blob
p String.from_java_bytes(blob.to_java_bytes)
Theo
  • 131,503
  • 21
  • 160
  • 205
  • Can you explain more? How to import BSON. I am not able to execute it on BSON. I want to convert String to a byte array in ruby – minhas23 Apr 17 '18 at 19:10
2

As mentioned already, this works:

irb(main):002:0> String.from_java_bytes(java_bytes)
=> "\x01\x02\x03"

But this also works:

irb(main):003:0> java_bytes.to_s
=> "\x01\x02\x03"

And I would argue that it's more sensible. :D

Hakanai
  • 12,010
  • 10
  • 62
  • 132