I'm using JRuby 9.0.5.0 in order to be able to invoke Ruby scripts from Java. I'd like to pass a char array containing a password to a Ruby script, but apparently I'm doing something wrong as my script only works if I use a normal string.
script.rb
contains the following function:
def action(user, password)
From Java, I can normally invoke this function, but I only get the the expected result (i.e. no exception) if password
is a String
:
ScriptEngineManager m = new ScriptEngineManager();
ScriptEngine jruby = m.getEngineByName("jruby");
...
jruby.put("user", "TestUser");
jruby.put("password", "xyz!"); // I'd like to pass "xyz!" as a char array.
// Call the script. Works as expected because password is a String.
String result = (String)jruby.eval("action($user, $password)");
My first attempt was to try to pass the password like this:
char[] password = { 'x', 'y', 'z', '!' };
jruby.put("password", password);
...
but this resulted in the exception
NoMethodError: undefined method `encoding' for char[x, y, z, !]@30abf79c:# encode_utf16le at .../jruby-9.0.5.0/lib/ruby/gems/shared/gems/rubyntlm-0.6.0/lib/net/ntlm/encode_util.rb:42
I get the same error if I try to set the password explicitly in the script.rb
itself like this, just for testing:
pwd = ['x', 'y', 'z', '!'].to_s
# use pwd inside the script ...
Next, I tried to force UTF-8 encoding like this:
pwd = ['x', 'y', 'z', '!'].to_s
pwd = pwd.force_encoding("UTF-8")
# use pwd inside the script ...
which resulted in a different error originating from the gem used inside the script, i.e. an authorization error. The same happens if I use "UTF-16".
Could it be that that the Ruby gem used by the script itself, i.e. the internal function call using the password, by itself only works with strings of a specific encoding? Or am I doing something else wrong? I know hardly anything about Ruby and am simply trying to glue this together.
The solution is to use password.to_a.pack('U*')
inside the Ruby script.
Java:
char[] password = { 'x', 'y', 'z', '!' };
jruby.put("password", password); // jruby is of type ScriptEngine
Ruby script.rb:
password_to_use = password.to_a.pack('U*')