MarkW
MarkW

Reputation: 1351

Why isn't this working: attempting to call Ruby GEM from java using jRuby

I am trying to use the chronic gem in java via jRuby

I have installed jruby

I have installed the chronic gem

C:\>jruby -S gem list --local

*** LOCAL GEMS ***

chronic (0.10.2)
did_you_mean (default: 1.0.1)
jar-dependencies (default: 0.3.5)
...

I have confirmed my environment setup

C:\>jruby -S gem env
RubyGems Environment:
  - RUBYGEMS VERSION: 2.6.6
  - RUBY VERSION: 2.3.1 (2016-09-07 patchlevel 0) [java]
  - INSTALLATION DIRECTORY: C:/jruby-9.1.5.0/lib/ruby/gems/shared
  - USER INSTALLATION DIRECTORY: C:/Users/markw/.gem/jruby/2.3.0
  - RUBY EXECUTABLE: C:/jruby-9.1.5.0/bin/jruby.exe
  - EXECUTABLE DIRECTORY: C:/jruby-9.1.5.0/bin
  - SPEC CACHE DIRECTORY: C:/Users/markw/.gem/specs
  - SYSTEM CONFIGURATION DIRECTORY: C:/jruby-9.1.5.0/etc
  - RUBYGEMS PLATFORMS:
    - ruby
    - universal-java-1.8
  - GEM PATHS:
     - C:/jruby-9.1.5.0/lib/ruby/gems/shared
     - C:/Users/markw/.gem/jruby/2.3.0
  - GEM CONFIGURATION:
    ...

I have tested the config in jruby's IRB

irb(main):006:0> require 'chronic'
true
irb(main):007:0> Chronic.parse('tomorrow')
2016-10-22 12:00:00 -0700

Making the same call to jruby via java fails:

        ...
       runtime = new ScriptEngineManager().getEngineByName("jruby");
       jruby = new StringBuffer();

       jruby.append("puts 2+3");
       jruby.append("\r\n");
       jruby.append("require 'chronic'");
       jruby.append("\r\n");
       jruby.append("Chronic.parse('tomorrow')");

       runtime.eval(jruby.toString());
       ...

OUTPUT:

5
LoadError: no such file to load -- chronic
  require at org/jruby/RubyKernel.java:956
   <main> at <script>:2

Attempting to inspect the GEM_PATH also works in the irb, but fails in java:

        ...
        runtime.eval("Gem.path");
        ...

OUTPUT:

NoMethodError: undefined method `path' for Gem:Module
  <main> at <script>:1

What obvious configuration steps am I missing?

***** UPDATE *****

Great suggestion EricDuminil. Logically I expected that to work but it didn't work. Here's what I get:

First, I should mention that jruby was installed using the windows installer. The chronic gem is installed in C:\jruby-9.1.5.0\lib\ruby\gems\shared:

C:\jruby-9.1.5.0\lib\ruby\gems\shared>tree /A

+---build_info
+---cache
+---doc
+---extensions
+---gems
|   +---chronic-0.10.2
|   +---jruby-win32ole-0.8.5
|   +---rake-10.4.2
|   \---rdoc-4.2.0
...

The GEM.path in the IRB is set to this:

irb(main):027:0> Gem.path
["C:/Users/markw/.gem/jruby/2.3.0", "C:/jruby-9.1.5.0/lib/ruby/gems/shared"]

Taking your suggestion, I set ENV[GEM_PATH] to same (and echo'ed it to confirm):

jruby.append("ENV[\"GEM_PATH\"] = \"C:/Users/markw/.gem/jruby/2.3.0;C:/jruby-9.1.5.0/lib/ruby/gems/shared\"");
jruby.append("\r\n");
jruby.append("puts ENV[\"GEM_PATH\"]");
jruby.append("\r\n");

OUTPUT:

C:/Users/markw/.gem/jruby/2.3.0;C:/jruby-9.1.5.0/lib/ruby/gems/shared
LoadError: no such file to load -- chronic
  require at org/jruby/RubyKernel.java:956
   <main> at <script>:3

It (jruby) still can't seem to find it!??

Upvotes: 2

Views: 399

Answers (1)

Eric Duminil
Eric Duminil

Reputation: 54223

You could define the needed environments variables inside your ruby script, before requiring chronic.

   jruby.append("ENV[\"GEM_PATH\"] = \"C:/Users/markw/.gem/jruby/2.3.0\"");
   jruby.append("\r\n");

I'm not sure which other variables are needed.

Upvotes: 1

Related Questions