Details
-
Type:
New Feature
-
Status:
Resolved
-
Priority:
Minor
-
Resolution: Not A Bug
-
Affects Version/s: None
-
Fix Version/s: JRuby 1.7.0.pre2
-
Component/s: None
-
Labels:None
-
Number of attachments :0
Description
Probably more of a question but in preview2 I noticed that JRuby.runtime no longer exists. Is there an equivalent? The BSON gem depends on it.
Activity
Oops, sorry to bring this up without doing better research. We do a require 'java' which looks like it would load the JRuby module in 1.6 but not in 1.7.
I'm having the same problem right after switching to 1.7.0-preview2 from 1.6.7:
NoMethodError: undefined method `runtime' for JRuby:Module
serialize at ....../.rbenv/versions/jruby-1.7.0-preview2/lib/ruby/gems/shared/gems/bson-1.6.4-jruby/lib/bson/bson_java.rb:9
I'm using warbler to create a jar. I guess I don't understand the problem (I'm somewhat of a newbie). I added a "require 'jruby'" to my main script (should be loaded right off), but still had the problem.
What would a workaround be? (Can't imagine that we are the only ones seeing this, unless it does not show up in rails ![]()
Thanks.
Greg: Adding "require 'jruby'" is the right workaround, but it's very likely that the use of JRuby.runtime happens before your target script, if for example you are using Bundler and it is booting libraries for you. I'm still 100% sure the issue is not having 'jruby' loaded early enough.
$ java -jar jruby-complete-1.7.0.preview2.jar -rjava -e 'JRuby.runtime'
NoMethodError: undefined method `runtime' for JRuby:Module
(root) at -e:1
$ java -jar jruby-complete-1.7.0.preview1.jar -rjava -e 'p JRuby.runtime'
#<Java::OrgJruby::Ruby:0x68916a2>
I do these error on all the (rspec|minitest|cucumber|runit)-maven-plugin there you can give a list of jrubies to use for the test like -Djruby.versions=1.6.7,1.7.0.preview1,1.7.0.preview2
the last version does not work - the ruby code is always the same and there is no require 'jruby' anywhere. the workaround I can add to a new version of these maven-plugins but it feels like a regression to me - or a break of habit ![]()
Got bitten while doing inputStream.to_io() (java.io.rb)
Definitely seems related to Java 1.6 vs. 1.7.
Small test, on Windows 7 32-bit, with 32-bit JVMs:
Java 1.7:
C:\Program Files\Java>set java_home=c:\Program Files\Java\jdk1.7.0_07
C:\Program Files\Java>d:\jruby-1.7.0.preview2\bin\jruby -rjava -e 'p java.lang.System.getProperty("java.version"); p JRuby; p JRuby.runtime'
"1.7.0_07"
JRuby
#<Java::OrgJruby::Ruby:0x1bab2c3>
Java 1.6:
C:\Program Files\Java>set java_home=C:\Program Files\Java\jdk1.6.0_34
C:\Program Files\Java>d:\jruby-1.7.0.preview2\bin\jruby -rjava -e 'p java.lang.System.getProperty("java.version"); p JRuby; p JRuby.runtime'
"1.6.0_34"
JRuby
NoMethodError: undefined method `runtime' for JRuby:Module
(root) at -e:1
My complete backtrace, with Java 1.6:
53383 [qtp11947822-17] WARN org.eclipse.jetty.server.AbstractHttpConnection - /
org.jruby.exceptions.RaiseException: (NoMethodError) undefined method `runtime' for JRuby:Module
at RUBY.to_io(file:/D:/ntuser/git/Alecto/lib/jruby-complete-1.7.0.preview2.jar!/jruby/java/java_ext/java.io.rb:5)
at RUBY.buffered_body_from_servlet_request(/D:/ntuser/git/Alecto/request.rb:29)
at RUBY.fromServletRequest(/D:/ntuser/git/Alecto/request.rb:38)
at RUBY.handle(/D:/ntuser/git/Alecto/jettyhandler.rb:42)
It's my own code - can work around it by using the InputStream methods to read to a byte array.
good catch. on my linux box it does indeed work with java1.7 and jruby-1.7.0.preview2 and fails with java1.6
The "this is an internal API" part of me wants to again mark this as "not a bug" or "won't fix" but I'm almost to the point of just making JRuby 1.7 load 'java' and 'jruby' by default, since more and more we need the functionality in those libraries to make it possible to write more of JRuby itself in Ruby.
The reason you see the 'jruby' library getting loaded in JRuby 1.7 on Java 7 is because Java 7 provides a better process management API, which we use to implement backquotes entirely in Ruby (to avoid statically binding or using reflection tricks). This alone may be justification for simply loading those libraries out of the box.
Pondering...
personally I was not aware of the "jruby" library until I ran into that issue here and reading about it.
the problem here is not similar to "rails-2.3.8 does not work with newer rubygems versions" since rails-2.3.8 depended on 'mutex' which newer rubygems versions do not require anymore. so people just use things which the "environment" provides.
in case of jruby require 'java' sometimes loads 'jruby' and sometimes it does not. I am sure there will be always people falling into that hole. ideally that should not depend on the java version - IMO.
. . . .
for my side I will release a new version of the jruby-maven-plugins and since everyone tends to move towards newer versions of java, jruby, jruby-maven-plugins things should be fine.
Now I may be nitpicking, but:
java.io.rb begins with this:
require 'jruby' unless defined? JRuby
This suggests that JRuby is somehow defined even under Java 1.6, but without runtime.
My code requires java, never jruby.
This was an explicit change when fixing a circular require bug. We don't always need to require 'jruby' and startup overhead of loading it when nothing uses it means it slows startup time. I considered this an oversight (e.g. bug) that we unconditionally load something.
The secondary justification is it is an API for giving access to JRuby's internals. It is an internal API and if you are using it you need to expressly request it. As Charlie noted this is used by some of our internal libraries so sometimes it does appear to be loaded by default, but it is entirely dependent on what is being loaded. It sounds like Java 7 will end up loading it, but that is a coincidence.
I am inclined to WONTFIX this. I hate it when we don't clearly communicate intent, but this behavioral change was not ever supposed to be an required-by-default library.
The debate rages on. It's still not clear whether we should load 'jruby' (and since it needs java integration, 'java' as well) by default, or if we should be moving toward loading less. I'm trending toward loading more in an efficient way (loading raw extensions is pretty cheap compared to full .rb requires) so we can start guaranteeing the same set of modules and features are available all the time, and that set includes java integration.
We also want to be able to start implementing more and more of JRuby in Ruby, which requires both 'java' and 'jruby' functionality.
But we worry about loading more, changing more stuff in global namespaces (like the java/javax/etc methods), and slowing down boot times.
from that "bug" I did learn that it is important to run CI over different versions of jruby combined with a set of different versions of java.
I am sure to provide a consistent preloaded API across JVMs is very helpful for lazy programmers like me - if JRuby.runtime works I would never get the idea to maybe require something "more" since it might be not there in some other context.
As Charlie notes 'jruby' requires 'java'. This change is a little broader in that if we require 'jruby' by default then we are really saying both 'java' and 'jruby' are always available.
Personally, I like the idea of not requiring these additional libraries if you don't want them, but as we keep implementing more of JRuby in Ruby we find ourselves increasingly using 'java' and to a slightly lesser extent 'jruby'. This means the point may eventually become moot (as in Java 7 atm).
If we do turn them on by default we should take some measurements beforehand to understand the sort of impact this adds. I know over time the files req
uired by 'java' has grown.....don't know how that submitted prematurely ![]()
Some of the hit of loading 'java' could be reduced by condensing the files it loads into fewer files; that's fewer load path searches and fewer parser start/stops.
We could also do what we're doing with the 'kernel' files and just load (rather than require) them directly from classloader resources, avoiding any load path searches at all.
I will try to play with this today.
That should certainly not be the case, and I can't reproduce here:
More likely is that some library that used to require 'jruby' no longer does so, and as a result JRuby.runtime is not being defined.