Hello all,
Sorry if this is a (too) long message.
First a little background on my problem...
I have some java code that I'd like to wrap with jruby (eventually so I
can
use it in a jruby on rails app, but that's not relevant at the moment).
Essentially, I am trying to do the following
I 'require java'
I iterate across all the jar files I should need in the lib directory of
my
project with 'Dir["lib/\*.jar"].each { |jar| require jar }'
I 'java_import my.package.and.className'
however, when I try to use my class, it calls out to a delegate class to
take care of some initialization/singleton stuff (I didn't write it, so
don't blame me). The problem is I wind up with this error
NativeException: java.lang.RuntimeException: Unexpected
ClassNotFoundException looking up class 'org/jruby/Main'
I can only guess that the init code is doing something seriously funky,
which is why JRuby can't find it's own running class (assuming I'm
reading
the error correctly). Any ideas for dealing with this are greatly
appreciated.
Now the immediate problem...
So far, I've tried setting the log4j level to debug, so I could get a
better idea of where in the java code, the errors are actually coming
from.
That has proven to be more difficult than I imagined.
I used this code to set the log level, and print it back out, so I know
it
at least thinks the setting took
org.apache.log4j.LogManager.getLogger("my.package.className.class").setLevel(org.apache.log4j.Level.toLevel("DEBUG"))
puts "Log level is "+
org.apache.log4j.LogManager.getLogger("my.package.className.class").getEffectiveLevel.toString
Indeed, that does print out 'DEBUG', however, I'm still only seeing log
messages from my java code at INFO level.
I also threw a log4j.properties file in the directory and load it as
file = File.new("log4j.properties");
PropertyConfigurator.configure(file.toURL());
logger = Logger.getLogger("java_integ_test.rb");
logger.debug("Test of debug msg");
and it does seem to print out the debug message. I use that config file
to
set the root logger to DEBUG level
log4j.rootLogger=DEBUG, stdout
log4j.logger.com=DEBUG
However, I'm still not getting any debug messages from my java code
(only
the ruby script itself)
So, my two questions are.
1) how the @#$% can I get the logger to run in debug for my java code
2) Any idea on what the first error actually means?
I strongly suspect that if I can get 1 answered, then 2 will follow
easily.
I doubt that it matters, but I'm running jruby-1.6.7 [
darwin-x86_64-java ]
on OSX. The behavior is the same for both Mountain Lion with Java 1.7,
and
Lion with Java 1.6.
Thanks for reading this far,
Mat
on 2012-09-10 05:52
on 2012-09-10 06:32
Mathew - I think your problem is the backslash in the argument to Dir[]. Why do you have it there? I think you only want: Dir["lib/*.jar"] - Keith -- Keith R. Bennett http://about.me/keithrbennett
on 2012-09-10 06:57
I have corrected that, but the behavior appears to be unchanged.
As a test, I created a new lib directory, and changed my classpath code
to
Dir["./lib2/*.jar"].each { |jar|
require jar
puts jar.inspect
}
Now, if I run my jruby with -d, I see these errors(?), even though the
file
is there, and being seen.
java.lang.ClassNotFoundException: lib2.Slf4j-log4j12-1.6.4Service
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at org.jruby.util.JRubyClassLoader.findClass(JRubyClassLoader.java:86)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:247)
at org.jruby.javasupport.JavaSupport.loadJavaClass(JavaSupport.java:136)
at
org.jruby.runtime.load.LoadService$ExtensionSearcher.trySearch(LoadService.java:597)
at
org.jruby.runtime.load.LoadService.findFileForLoad(LoadService.java:283)
at org.jruby.runtime.load.LoadService.smartLoad(LoadService.java:330)
at org.jruby.runtime.load.LoadService.require(LoadService.java:379)
at
org.jruby.runtime.load.LoadService.lockAndRequire(LoadService.java:304)
at org.jruby.RubyKernel.requireCommon(RubyKernel.java:1050)
at org.jruby.RubyKernel.require(RubyKernel.java:1033)
at
org.jruby.RubyKernel$s$1$0$require.call(RubyKernel$s$1$0$require.gen:65535)
at
org.jruby.internal.runtime.methods.JavaMethod$JavaMethodOneOrNBlock.call(JavaMethod.java:319)
at
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:167)
at $_dot_.java_test.block_0$RUBY$__file__(./java_test.rb:9)
at
$_dot_$java_test$block_0$RUBY$__file__.call($_dot_$java_test$block_0$RUBY$__file__:65535)
at org.jruby.runtime.CompiledBlock.yield(CompiledBlock.java:112)
at org.jruby.runtime.CompiledBlock.yield(CompiledBlock.java:95)
at org.jruby.runtime.Block.yield(Block.java:130)
at org.jruby.RubyArray.eachCommon(RubyArray.java:1608)
at org.jruby.RubyArray.each(RubyArray.java:1615)
at org.jruby.RubyArray$i$0$0$each.call(RubyArray$i$0$0$each.gen:65535)
at
org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:302)
at
org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:144)
at
org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:153)
at $_dot_.java_test.__file__(./java_test.rb:8)
at $_dot_.java_test.load(./java_test.rb)
at org.jruby.Ruby.runScript(Ruby.java:697)
at org.jruby.Ruby.runScript(Ruby.java:690)
at org.jruby.Ruby.runNormally(Ruby.java:597)
at org.jruby.Ruby.runFromMain(Ruby.java:446)
at org.jruby.Main.doRunFromMain(Main.java:369)
at org.jruby.Main.internalRun(Main.java:258)
at org.jruby.Main.run(Main.java:224)
at org.jruby.Main.run(Main.java:208)
at org.jruby.Main.main(Main.java:188)
"./lib2/slf4j-log4j12-1.6.4.jar"
The last line shows that the script could see the jar file. I get this
error for each jar file I have in my new lib2 directory. I'm unsure if
this is a real error, if my jruby install is mucked up.
Mat
on 2012-09-10 07:03
Why's it looking for a class that starts with lib2 as the main package -
lib2.Slf4j-log4j12-1.6.4Service
Try using an absolute path. I am using this in my rails application and
it
seems to be fine with the jars I have in place -
Dir["#{File.dirname(__FILE__)}/../lib/jars/*.jar"].each do |jar|
require jar
end
on 2012-09-10 07:22
Good point. I reinstalled jruby through rvm (it's now 1.6.4 as the default version). I changed my code based off of what you have below. On the upside, those 'errors' are now gone from the startup, but the end result is still the same (same error as before NativeException: java.lang.RuntimeException: Unexpected ClassNotFoundException looking up class 'org/jruby/Main' (root) at ./java_test.rb:28 ) Also, I don't know if it matters, but when I added a 'puts jar.inspect' in the classpath code, it's still printing as relative. "./lib/xercesImpl-2.9.1.jar" "./lib/xml-apis-1.3.04.jar" I hardcoded the path, to the full path to the lib dir, and now they are showing with their full paths, but no real difference in behavior. I feel like we're cutting down on the noise around the real problem, but so far, it's still I'm still flummoxed. Thanks Mat
on 2012-09-10 07:37
FWIW, I ended up using a checkout from the repository and doing a local JRuby build and setting it in the PATH. Can you give a full trace for the error? The bigger the better.
on 2012-09-10 07:45
I'm not getting any stack traces now. The sum total of the error (when running with -d is the one shown below). NativeException: java.lang.RuntimeException: Unexpected ClassNotFoundException looking up class 'org/jruby/Main' (root) at ./java_test.rb:28 ) Also, I copied the jruby.jar to the lib dir (just to be on the safe side), where all the other jars are, and that didn't seem to make any difference in behavior. Mat
on 2012-09-10 08:05
On Mon, Sep 10, 2012 at 11:14 AM, mathew duafala <mduafala@gmail.com> wrote: > NativeException: java.lang.RuntimeException: Unexpected > ClassNotFoundException looking up class 'org/jruby/Main' this error I saw when I do something like $ java -cp ../../../nexus/lib/slf4j-api-1.6.4.jar:~/.m2/repository/org/jruby/jruby-complete/1.7.0.preview2/jruby-complete-1.7.0.preview2.jar org.jruby.Main -e "puts 123" Exception in thread "main" java.lang.NoClassDefFoundError: org/jruby/Main Caused by: java.lang.ClassNotFoundException: org.jruby.Main but $ java -cp ~/.m2/repository/org/jruby/jruby-complete/1.7.0.preview2/jruby-complete-1.7.0.preview2.jar:../../../nexus/lib/slf4j-api-1.6.4.jar org.jruby.Main -e "puts 123"123 since read you both were talking about CLASSPATH - make sure jruby is FIRST on the classpath. about the require and the absolute path - I usually write p require jar as debug to see if my jar is loaded. - Kristian
on 2012-09-10 08:06
Hopefully you'll get an answer from an expert. I've personally never been able to use debug mode with JRuby. But in any case, don't let the jruby.jar be added more than once. I guess the regular Java rules must apply.
on 2012-09-10 08:13
Holy Cow, it finally works with this command! java -cp ./lib/jruby-complete-1.6.7.2.jar org.jruby.Main -S ./java_test.rb I'm not sure I understand why it needed this specific invocation. I still don't understand why the log4j stuff didn't work, but I'm ok with that at the moment. Thanks for you're help everyone. Mat
on 2012-09-10 08:17
I have set jruby.jar in my CLASSPATH so that I don't have to bother with it. Other jars get loaded in the application as and when another required. For your log4j, send another email specifically about that. You might have a point there.
on 2012-09-10 08:30
I guess that is my personal way of using jruby-complete :) - I never used rvm so can not help you there. you can have a bit shorted :) java -jar ./lib/jruby-complete-1.6.7.2.jar ./java_test.rb just do not require 'jruby.jar' as Singh wrote. if you provide the java_test.rb as gist or pastebin and the list of jars in ./lib/ then I will look into why the 'jruby' invoker did not work ;) - Kristian
on 2012-09-10 08:48
Strange...I thought 1.6.7 is the default version installed by rvm. rvm is great; I highly recommend using it when working with JRuby because it saves you from having to do all that special stuff, such as saying jruby instead of ruby, and using jruby -S rake instead of just rake. I'd suggest doing: rvm install jruby-1.6.7 ...and then make an alias for it for easier use, and for easier upgrading to future versions: rvm alias create jruby jruby-1.6.7 You can make it the default for each new shell like this: rvm --default jruby Then you should be able to run your code more easily, such as: ruby java_test.rb You shouldn't need the "./" because you're not running it as a Unix command, you're just passing the filespec of the script to the JRuby interpreter. Also, regarding the log4j problem, I'd examine your configuration to see if something may be wrong. As Pradeep noticed, this: java.lang.ClassNotFoundException: lib2.Slf4j-log4j12-1.6.4Service implies that the program is trying to use the class "Slf4j-log4j12-1.6.4Service" in the package "lib2". Are you maybe specifying a filespec instead of a class in the configuration? - Keith -- Keith R. Bennett http://about.me/keithrbennett
on 2012-09-10 09:59
just one last thought (hope these many emails are not does not annoy you). why not using https://github.com/mkristian/jbundler to manage you jar files. it will take care of loading the jars. - Kristian
Please log in before posting. Registration is free and takes only a minute.
Existing account
(Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
Log in with Google account | Log in with Yahoo account
No account? Register here.