Java package woes

Hi,

I’m in the process of attempting to move my MRI ruby program over to
JRuby. Most of the stuff is working, but I’m experimenting with putting
some code into Java for speed reasons, despite not really knowing Java
(have used C/C++ before, so have had experience with much stricter
languages).

I have some code working, but I’m trying to make use of:
https://commons.apache.org/math/api-3.1.1/org/apache/commons/math3/distribution/NormalDistribution.html

I was able to get javac to work by running it from the root directory,
with the apache commons jar in that folder. My Java code includes:

package test.gen;

import org.apache.commons.math3.distribution.*;

public class TestGenerator {
public int x_size = 0;
public int y_size = 0;
public int z_size = 0;

public TestGenerator(int xs, int ys, int zs) {
x_size = xs;
y_size = ys;
z_size = zs;
NormalDistribution n_temperature = new NormalDistribution(1.0, 1.0);
}

}

I have no problem with javac, and this code all works fine without the
normal distribution stuff. As soon as I add in the NormalDistribution
it doesn’t work (though I can use javac and jar to create my test.jar
package successfully). Once I add that in, I can’t seem to get it to
work:
sh-3.2# jirb
irb(main):001:0> require ‘./commons-math3-3.1.1.jar’
=> true
irb(main):002:0> require ‘./test.jar’
=> true
irb(main):003:0> a = Java.test.gen.TestGenerator.new(100,100,100)
Java::JavaLang::NoClassDefFoundError:
org/apache/commons/math3/distribution/NormalDistribution
from test.gen.TestGenerator.(TestGenerator.java:21)
from sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native
Method)
from
sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
from
sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
from java.lang.reflect.Constructor.newInstance(Constructor.java:513)
from
org.jruby.javasupport.JavaConstructor.newInstanceDirect(JavaConstructor.java:307)
from
org.jruby.java.invokers.ConstructorInvoker.call(ConstructorInvoker.java:118)
from
org.jruby.java.invokers.ConstructorInvoker.call(ConstructorInvoker.java:217)
from
org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:376)
from
org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:247)
from
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:251)
from
org.jruby.java.proxies.ConcreteJavaProxy$2.call(ConcreteJavaProxy.java:60)
from
org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:376)
from
org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:247)
from
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:251)
from org.jruby.RubyClass.newInstance(RubyClass.java:881)
… 132 levels…
from
org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:75)
from
org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
from
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:188)
from
org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326)
from
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
from
usr.local.rvm.rubies.jruby_minus_1_dot_7_dot_1.bin.jirb.file(/usr/local/rvm/rubies/jruby-1.7.1/bin/jirb:13)
from
usr.local.rvm.rubies.jruby_minus_1_dot_7_dot_1.bin.jirb.load(/usr/local/rvm/rubies/jruby-1.7.1/bin/jirb)
from org.jruby.Ruby.runScript(Ruby.java:779)
from org.jruby.Ruby.runScript(Ruby.java:772)
from org.jruby.Ruby.runNormally(Ruby.java:649)
from org.jruby.Ruby.runFromMain(Ruby.java:498)
from org.jruby.Main.doRunFromMain(Main.java:375)
from org.jruby.Main.internalRun(Main.java:264)
from org.jruby.Main.run(Main.java:230)
from org.jruby.Main.run(Main.java:214)
from org.jruby.Main.main(Main.java:194)irb(main):004:0>

Any ideas what’s going wrong and how to get it working?

Thanks!

did you try putting the dependent jar on the class path?

On Sat, Jan 19, 2013 at 4:13 PM, Na Na [email protected] wrote:

Java for speed reasons, despite not really knowing Java
(have used C/C++ before, so have had experience with much stricter
languages).

-Brian W.

On Sat, Jan 19, 2013 at 6:13 PM, Na Na [email protected] wrote:

=> true
irb(main):003:0> a = Java.test.gen.TestGenerator.new(100,100,100)
Java::JavaLang::NoClassDefFoundError:
org/apache/commons/math3/distribution/NormalDistribution
from test.gen.TestGenerator.(TestGenerator.java:21)

Your problem here is that calling JRuby’s require on a jar only helps
the
JRuby runtime load a class. It still relies upon Java’s classloading
mechanisms to resolve dependencies for any loaded classes, and Java
requires that dependent classes be available on the classpath.

If you change your jirb invocation slightly, it’ll work:

$ jruby -J-cp commons-math3-3.1.1.jar -S jirb
irb(main):001:0> require ‘test.jar’
=> true
irb(main):002:0> a = Java.test.gen.TestGenerator.new(100, 100, 100)
=> #Java::TestGen::TestGenerator:0x1147791
irb(main):003:0>

Great thanks!

For some reason it worked when I replaced jirb with my ruby file, but
not jirb. But then I put in the full path to jirb instead of just
“jirb”, and that works now too.