Details
-
Type:
Bug
-
Status:
Open
-
Priority:
Major
-
Resolution: Unresolved
-
Affects Version/s: JRuby 1.5
-
Fix Version/s: None
-
Component/s: Java Integration
-
Labels:None
-
Number of attachments :
Description
This is a problem with earlier versions of jruby-rack, which has an interface org.jruby.rack.RackApplication with a getRuntime method of identical signature to our own getRuntime on IRubyObject. The implementation of that interface then provides its own getRuntime method.
Under JRuby 1.4, where the class generated for an interface impl was off to the side of the org.jruby.RubyObject class hierarchy, this worked fine. Under JRuby 1.5, where the interface impl is actually a subclass of RubyObject, getRuntime in that hierarchy is now final and so the implementation fails to load properly.
There are a few fixes required for this:
- We should have a better error when an interface method is already final in the Ruby class hierarchy (or in the extending class hierarchy for Ruby-extending-Java) rather than letting the verification error to bubble out.
- jruby-rack needs a fix; Nick Sieger has so far fixed this by dodging the interface impl logic by < java.lang.Object. this causes the impl class to not descend from RubyObject, and so getRuntime can be implemented ok. This may or may not be an ok fix; since the concrete extension logic is rather involved, it could be a performance issue. But it's not a bad fix from a functional perspective.
Since jruby-rack has already been patched for this, there's no criticality to this issue for JRuby 1.5. However we should get a better error in place for JRuby 1.6 at the latest, and potentially also prioritize getting "real class" extension logic fully functional so that jruby-rack's current fix does not incur any (potential) perf penalty.
Here is a session showing a trivial reproduction of the problem:
~/projects/jruby ➔ cat blah.duby
import org.jruby.Ruby
interface GetRuntime do
def getRuntime() returns Ruby; end
end
~/projects/jruby ➔ ../duby/bin/dubyc blah.duby
~/projects/jruby ➔ javap GetRuntime
Compiled from "blah.duby"
public interface GetRuntime{
public abstract org.jruby.Ruby getRuntime();
}
~/projects/jruby ➔ jruby -rjava -e "class Foo; include Java::GetRuntime; def getRuntime; nil; end; end; Foo.new"
ClassLoader.java:-2:in `defineClass1': java.lang.VerifyError: class Foo_379897791 overrides final method getRuntime.()Lorg/jruby/Ruby;
from ClassLoader.java:698:in `defineClass'
from JRubyClassLoader.java:39:in `defineClass'
from RealClassGenerator.java:462:in `defineRealImplClass'
from RealClassGenerator.java:70:in `createRealImplClass'
from Java.java:1169:in `generateRealClass'
from JavaInterfaceTemplate.java:269:in `call'
from DynamicMethod.java:182:in `call'
from DynamicMethod.java:178:in `call'
from CachingCallSite.java:289:in `cacheAndCall'
from CachingCallSite.java:108:in `call'
from -e:1:in `__file__'
from -e:-1:in `load'
from Ruby.java:683:in `runScript'
from Ruby.java:566:in `runNormally'
from Ruby.java:412:in `runFromMain'
from Main.java:286:in `run'
from Main.java:128:in `run'
from Main.java:97:in `main'