java.lang.InternalError: Malformed class name with distributed pubsub extension

995 views
Skip to first unread message

ch...@ochsnet.com

unread,
Jun 24, 2013, 1:40:49 AM6/24/13
to akka...@googlegroups.com
Reading up on this error it appears that scala can create class names that java doesn't like, in a nutshell.

The stack trace ends up in jruby where it calls the first ruby method in my actor that inherits from UntypedActor.  What causes this is setting up a distributed pubsub subscription (basic one from the docs).  Doesn't matter if the actor is in jruby or pure java, I still get the same error. I think it's actually getting triggered when the bad class ends up in a DeadLetter, which even with a pure java actor still gets sent through jruby as I have jruby actors that handle dead letters.

The trigger is when I run a cluster seed, then join a member, then stop the member.  As soon as I stop the member the seed throws the exception.  That's why I think it's a bad class in a deadletter message that's causing this, because there is no other way for the bad class to get into jruby when using a pure java pubsub actor.

I haven't yet wired a pure java dead letter handler to see if that fixes the issue, or at least lets me see the class that's causing a problem.  Was hoping someone might have a quick fix:)

Chris

--------------------------------------------------------------------------------------------------------------------------------
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)

Roland Kuhn

unread,
Jun 24, 2013, 1:59:17 AM6/24/13
to akka...@googlegroups.com
Hi Chris,

24 jun 2013 kl. 07:40 skrev ch...@ochsnet.com:

Reading up on this error it appears that scala can create class names that java doesn't like, in a nutshell.

Yes, and there is not much we can do about it :-( Do you have a hint which class name it is that trips things up? (It would be nice if the exception included that in its message … )

Regards,

Roland

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn


ch...@ochsnet.com

unread,
Jun 24, 2013, 2:17:19 AM6/24/13
to akka...@googlegroups.com


On Sunday, June 23, 2013 10:59:17 PM UTC-7, rkuhn wrote:
Hi Chris,

24 jun 2013 kl. 07:40 skrev ch...@ochsnet.com:

Reading up on this error it appears that scala can create class names that java doesn't like, in a nutshell.

Yes, and there is not much we can do about it :-( Do you have a hint which class name it is that trips things up? (It would be nice if the exception included that in its message … )

Regards,

Roland


I put the deadletter handling in pure java and passed just the enclosed message to a jruby actor, and logged all of them from the java side.  it's DistributedPubSubMediator.Status that is the culprit. 

Annoying, but I can work around it by just filtering out messages that are problematic on the java side and not sending them to jruby.

Chris

ch...@ochsnet.com

unread,
Jun 24, 2013, 2:30:20 AM6/24/13
to akka...@googlegroups.com


On Sunday, June 23, 2013 10:59:17 PM UTC-7, rkuhn wrote:
Hi Chris,

24 jun 2013 kl. 07:40 skrev ch...@ochsnet.com:

Reading up on this error it appears that scala can create class names that java doesn't like, in a nutshell.

Yes, and there is not much we can do about it :-( Do you have a hint which class name it is that trips things up? (It would be nice if the exception included that in its message … )


Well that's doubly annoying. Status is private, I can't even access it from java without calling toString and doing a regex match or something ugly like that.

Chris
 

Patrik Nordwall

unread,
Jun 24, 2013, 2:43:44 AM6/24/13
to akka...@googlegroups.com
It is getSimpleName that chokes on all classes in that nested private Internal object
I guess we could move all those to a separate top level object.


--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.
 
 



--

Patrik Nordwall
Typesafe The software stack for applications that scale
Twitter: @patriknw

Roland Kuhn

unread,
Jun 24, 2013, 2:44:40 AM6/24/13
to akka...@googlegroups.com
You’re talking either about DistributedPubSubMediator$Internal$Status or DistributedPubSubMediator$Internal$Status$, but in the end it does not matter because there is nothing special about these names (from Scala’s perspective) and there are thousands of other classes like these in Akka, so even if you filter this one out you will see the same error again eventually. And AFAICS it does not make sense for Akka to try and work around it, because the affected surface area is enormous and we would have to break a lot of API to make it happen. Is it possible to teach JRuby not to call getSimpleName? Or is it possible to catch the exception? 

Regards,

Roland


Chris
 

--
>>>>>>>>>> Read the docs: http://akka.io/docs/
>>>>>>>>>> Check the FAQ: http://akka.io/faq/
>>>>>>>>>> Search the archives: https://groups.google.com/group/akka-user
---
You received this message because you are subscribed to the Google Groups "Akka User List" group.
To unsubscribe from this group and stop receiving emails from it, send an email to akka-user+...@googlegroups.com.
To post to this group, send email to akka...@googlegroups.com.
Visit this group at http://groups.google.com/group/akka-user.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Roland Kuhn

unread,
Jun 24, 2013, 2:53:41 AM6/24/13
to akka...@googlegroups.com
I don’t think it is that simple:

scala> object A { class B }
defined module A

scala> (new A.B).getClass.getSimpleName
java.lang.InternalError: Malformed class name
at java.lang.Class.getSimpleName(Class.java:1155)

We would have to move a lot of things around—and lose the namespace boundaries. Even our best practices of putting the message types into the actor’s companion object violate getSimpleName. It is not feasible to write Scala code which makes getSimpleName happy.

Patrik Nordwall

unread,
Jun 24, 2013, 3:35:29 AM6/24/13
to akka...@googlegroups.com
On Mon, Jun 24, 2013 at 8:53 AM, Roland Kuhn <goo...@rkuhn.info> wrote:
I don’t think it is that simple:

scala> object A { class B }
defined module A

scala> (new A.B).getClass.getSimpleName
java.lang.InternalError: Malformed class name
at java.lang.Class.getSimpleName(Class.java:1155)

We would have to move a lot of things around—and lose the namespace boundaries. Even our best practices of putting the message types into the actor’s companion object violate getSimpleName. It is not feasible to write Scala code which makes getSimpleName happy.

Agreed

Chris Ochs

unread,
Jun 24, 2013, 9:54:14 PM6/24/13
to akka...@googlegroups.com


On Sunday, June 23, 2013 11:44:40 PM UTC-7, rkuhn wrote:

24 jun 2013 kl. 08:30 skrev ch...@ochsnet.com:



On Sunday, June 23, 2013 10:59:17 PM UTC-7, rkuhn wrote:
Hi Chris,

24 jun 2013 kl. 07:40 skrev ch...@ochsnet.com:

Reading up on this error it appears that scala can create class names that java doesn't like, in a nutshell.

Yes, and there is not much we can do about it :-( Do you have a hint which class name it is that trips things up? (It would be nice if the exception included that in its message … )


Well that's doubly annoying. Status is private, I can't even access it from java without calling toString and doing a regex match or something ugly like that.

You’re talking either about DistributedPubSubMediator$Internal$Status or DistributedPubSubMediator$Internal$Status$, but in the end it does not matter because there is nothing special about these names (from Scala’s perspective) and there are thousands of other classes like these in Akka, so even if you filter this one out you will see the same error again eventually. And AFAICS it does not make sense for Akka to try and work around it, because the affected surface area is enormous and we would have to break a lot of API to make it happen. Is it possible to teach JRuby not to call getSimpleName? Or is it possible to catch the exception? 

 
I posted to the jruby list to see if they have some ideas on a workaround.  It's not really reasonable to expect someone else to do a lot of work to get around a scala bug though.  I can catch the exception, but that means I still have to special case these as they show up.  The long term solution is just moving problem areas into pure java as they show up.  

Chris Ochs


Chris Ochs

unread,
Jun 25, 2013, 2:15:30 AM6/25/13
to akka...@googlegroups.com
So Charles Nutter on the jruby list seems to think this is really a java bug, and that he would try to make the case to get it fixed in openjdk.  He seemed to know what the fix should be.  Would be nice to see that happen!  I'm going to take a closer look at the jruby side to see if there is a workaround that can be put in place.

Chris

Roland Kuhn

unread,
Jun 25, 2013, 2:41:00 AM6/25/13
to akka...@googlegroups.com
Hi Chris,

fixing it in openjdk would be great! I am not on the jruby lists, would you please keep us posted?


Regards,


Dr. Roland Kuhn
Akka Tech Lead
Typesafe – Reactive apps on the JVM.
twitter: @rolandkuhn

Chris Ochs

unread,
Jun 25, 2013, 2:45:00 AM6/25/13
to akka...@googlegroups.com
Will do.  I'm sure that would make a number of people happy.

Chris
Reply all
Reply to author
Forward
0 new messages