[jruby-user] Using java -jar jruby.jar does not pick up environment CLASSPATH

19 views
Skip to first unread message

Johnny P

unread,
Jun 20, 2008, 7:46:07 PM6/20/08
to us...@jruby.codehaus.org
Using a bash shell script such as:

CLASSPATH=foo.jar:build/:lib/
export CLASSPATH
java -jar jruby.jar myruby.rb

Inside myruby.rb

puts ENV['CLASSPATH']
require 'java'
#....


The classpath prints correctly; However, when I import, or use anything from that classpath I get class not found exceptions.  I cannot seem to find anyway to fix this.  TIA for any help.

PS:  Using jruby myruby.rb works fine, but I want to launch using java -jar jruby.jar.

TIA

Damian Steer

unread,
Jun 21, 2008, 7:53:53 AM6/21/08
to us...@jruby.codehaus.org

On 21 Jun 2008, at 00:46, Johnny P wrote:

> Using a bash shell script such as:
>
> CLASSPATH=foo.jar:build/:lib/
> export CLASSPATH
> java -jar jruby.jar myruby.rb

A classic java gotcha!

From the java man page section on -jar:

"When you use this option, the JAR file is the source of all user
classes, and other user class path settings are ignored."

So either 1) don't use -jar or 2) require 'my.jar'.

Damian

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

http://xircles.codehaus.org/manage_email


dennis zhuang

unread,
Jun 21, 2008, 8:26:30 AM6/21/08
to us...@jruby.codehaus.org
put this statement in your ruby script

CLASSPATH="foo.jar:build/:lib/"

2008/6/21 Damian Steer <pl...@mac.com>:

Johnny P

unread,
Jun 23, 2008, 7:09:08 PM6/23/08
to us...@jruby.codehaus.org
Thanks Damian.  I ended up just putting the jruby jar in the -classpath on the command line then I used org.jruby.Main as the main class.  That worked.

Dennis setting/changing the CLASSPATH const does not work.  For example

# myruby.rb
CLASSPATH="spring.jar"
import org.springframework.context.support.ClassPathXmlApplicationContext;

$ jruby myruby.rb

You will get class not found ClassPathXmlApplicationContext.  Where if you do:
$ export CLASSPATH="spring.jar"
# myruby2.rb
import org.springframework.context.support.ClassPathXmlApplicationContext;

$ java org.jruby.Main -w myruby2.rb

That will work.  Yes you can require "spring.jar", but that does not help when you need to reference ".class, .xml, .properties" files expected in the classpath.  Thanks

Vladimir Sizikov

unread,
Jun 24, 2008, 5:03:50 AM6/24/08
to us...@jruby.codehaus.org
Hi Johnny,

On Tue, Jun 24, 2008 at 1:09 AM, Johnny P <jpyw...@gmail.com> wrote:
> Thanks Damian. I ended up just putting the jruby jar in the -classpath on
> the command line then I used org.jruby.Main as the main class. That worked.
>
> Dennis setting/changing the CLASSPATH const does not work. For example
>
> # myruby.rb
> CLASSPATH="spring.jar"
> import org.springframework.context.support.ClassPathXmlApplicationContext;

The code should be a bit different, you should use $CLASSPATH global variable,
it is an array, and you need to add your JAR files there:

$CLASSPATH << "ant.jar"
import org.apache.tools.ant.AntClassLoader

This works wine for me.

Thanks,
--Vladimir

Johnny P

unread,
Jun 24, 2008, 6:44:30 PM6/24/08
to us...@jruby.codehaus.org
Vladimir, thanks, but it does not work for all class path cases.  For example Spring.  If you use the spring class path xml app context the below fails.  I believe the reason why is because this circumvents the jruby url class loader.  So, being able to set the CLASSPATH outside the script could be essential.  I would imagine in Springs case I could use ruby to load the context and then pass the file contents to it, but I did not investigate that.

Thanks

Stephen Bannasch

unread,
Jun 24, 2008, 9:20:20 PM6/24/08
to us...@jruby.codehaus.org
At 3:44 PM -0700 6/24/08, Johnny P wrote:
>Vladimir, thanks, but it does not work for all class path cases. For example Spring. If you use the spring class path xml app context the below fails. I believe the reason why is because this circumvents the jruby url class loader. So, being able to set the CLASSPATH outside the script could be essential. I would imagine in Springs case I could use ruby to load the context and then pass the file contents to it, but I did not investigate that.
>
>Thanks

Hi Johnny,

I think this Jira bug report I entered about 6 weeks ago might describe the underlying cause for the problem you are having.

http://jira.codehaus.org/browse/JRUBY-2495
Requiring and using a Java library that ends up using a Thread Context classloader doesn't work.

I included a simplified test case but have had no comments yet from anybody.

Vladimir Sizikov

unread,
Jun 25, 2008, 6:47:35 AM6/25/08
to us...@jruby.codehaus.org
Hi Stephen, Johnny,

On Wed, Jun 25, 2008 at 3:20 AM, Stephen Bannasch


> I think this Jira bug report I entered about 6 weeks ago might describe the underlying cause for the problem you are having.
>
> http://jira.codehaus.org/browse/JRUBY-2495
> Requiring and using a Java library that ends up using a Thread Context classloader doesn't work.

Yes, that's the same issue. Also, I've encountered another case when
proper thread context classloader is required: loading JDBC drivers
that are not on CLASSPATH.

Luckily, there is a more or less straightforward way to adjust the
context classloader:
require 'jruby'
java.lang.Thread.currentThread.setContextClassLoader(JRuby.runtime.jruby_class_loader)

With that, I verified that the test case from the bug report pass. And
JDBC drivers are loaded OK too.

Johnny P

unread,
Jun 25, 2008, 6:47:02 PM6/25/08
to us...@jruby.codehaus.org
Vladimir and Stephen thanks.  java.lang.Class.forName was still not happy and I was getting ClassNotFound; However, thankfully for_name is overloaded and I swithed the call to for_name("my.java.class", false, JRuby
.runtime.jruby_class_loader)

To summarize I used the following:
require 'java'
require 'jruby'

["#{File.dirname __FILE__}/../build/", "#{File.dirname __FILE__}/../lib/"].concat(Dir["#{File.dirname __FILE__}/../lib/*.jar"]).each { |jar| $CLASSPATH << jar }
java.lang.Thread.currentThread.context_class_loader = JRuby.runtime.jruby_class_loader
#... and
jklass = java.lang.Class.for_name("com.company.JavaClass", false, JRuby.runtime.jruby_class_loader)


That did the trick.  Thanks to all.
Reply all
Reply to author
Forward
0 new messages