Forum: JRuby scala getSimpleName bug causing havoc in jruby

F48118fe74b0c7f6fd82a0ee422fa34e?d=identicon&s=25 snacktime (Guest)
on 2013-06-25 03:41
(Received via mailing list)
Not a jruby bug, but I'm curious if anyone has ideas on ways to work
around
it in jruby.

Basically, scala creates bad code for doubly nested classes that causes
getSimpleName to blow up.  They aren't fixing it from what I can tell.
I
didn't hit this bug until I was already deep into using akka on a
project.
 I can filter out these bad classes as I find them and keep them out of
jruby, but was hoping someone might have an idea on a cleaner
workaround.

Chris

-------------------------------------------------------------------------------------
Link to a scala ticket (one of several) showing the problem:
https://issues.scala-lang.org/browse/SI-2034

Sample stacktrace when it hits a bad class:

java.lang.InternalError: Malformed class name
at java.lang.Class.getSimpleName(Class.java:1155)
at org.jruby.javasupport.JavaClass.setupProxy(JavaClass.java:743)
at org.jruby.javasupport.Java.createProxyClass(Java.java:574)
at org.jruby.javasupport.Java.createProxyClassForClass(Java.java:502)
at
org.jruby.javasupport.JavaSupport$3.computeValue(JavaSupport.java:154)
at
org.jruby.javasupport.JavaSupport$3.computeValue(JavaSupport.java:151)
at
org.jruby.util.collections.MapBasedClassValue.get(MapBasedClassValue.java:18)
at
org.jruby.javasupport.JavaSupport.getProxyClassFromCache(JavaSupport.java:207)
at org.jruby.javasupport.Java.getProxyClass(Java.java:450)
at org.jruby.javasupport.Java.getInstance(Java.java:389)
at org.jruby.javasupport.Java.getInstance(Java.java:371)
at
org.jruby.javasupport.JavaUtil.convertJavaToUsableRubyObject(JavaUtil.java:167)
at org.jruby.javasupport.JavaMethod.convertReturn(JavaMethod.java:517)
at
org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(JavaMethod.java:441)
at org.jruby.javasupport.JavaMethod.invokeDirect(JavaMethod.java:304)
at
org.jruby.java.invokers.InstanceMethodInvoker.call(InstanceMethodInvoker.java:52)
at
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:134)
at org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:60)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
at org.jruby.ast.DNode.appendToString(DNode.java:70)
at org.jruby.ast.DNode.buildDynamicString(DNode.java:88)
at org.jruby.ast.DNode.interpret(DNode.java:36)
at org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
at org.jruby.ast.IfNode.interpret(IfNode.java:116)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
at
org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
at
org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
at
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:186)
at
org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
at
rubyjit.GameMachine::GameActor$$onReceive_308BD95C280F55428DF2EEAF15AD2E7CAA298944316007184.__file__(/home/chris/game_machine/ruby/lib/game_machine/game_actor.rb:78)
at
rubyjit.GameMachine::GameActor$$onReceive_308BD95C280F55428DF2EEAF15AD2E7CAA298944316007184.__file__(/home/chris/game_machine/ruby/lib/game_machine/game_actor.rb)
at
rubyjit.GameMachine::GameActor$$onReceive_308BD95C280F55428DF2EEAF15AD2E7CAA298944316007184.__file__(/home/chris/game_machine/ruby/lib/game_machine/game_actor.rb)
at
org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:121)
at
org.jruby.javasupport.proxy.JavaProxyConstructor$2.invoke(JavaProxyConstructor.java:224)
at org.jruby.proxy.akka.actor.UntypedActor$Proxy5.onReceive(Unknown
Source)
at
akka.actor.UntypedActor$$anonfun$receive$1.applyOrElse(UntypedActor.scala:163)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:498)
at akka.actor.ActorCell.invoke(ActorCell.scala:456)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:237)
at akka.dispatch.Mailbox.run(Mailbox.scala:219)
at
akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:386)
at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:262)
at
scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:975)
at
scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1478)
at
scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:104)
F1d37642fdaa1662ff46e4c65731e9ab?d=identicon&s=25 Charles Nutter (headius)
on 2013-06-25 07:43
(Received via mailing list)
No workaround I can think of, but we could modify JRuby to work around
this issue. We've already got some Scala hacks in place.

I don't believe that this is really a Scala bug though. The reflection
API in getSimpleName is enforcing Java language specification rules on
all classes loaded by the JVM. The API should trust that the simple
name of the class is the name it reports minus the name of the
enclosing class it reports, rather than trying to enforce minor
idiosyncracies of inner class naming.

I'm preparing a patch for OpenJDK and will see if I can make the case.
On the other side...perhaps you can look into JRuby where we're
calling getSimpleName and see if you can work around it?

- Charlie
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.