duplicate class definition when reifying classes #1229

Closed
nirvdrum opened this Issue Nov 15, 2013 · 11 comments

Projects

None yet

2 participants

@nirvdrum
Contributor

Since JRuby 1.7.8 had a reification fix, I figured I'd try running my project specs with that enabled again and ran into a new problem. I'm not sure if the duplicate class definition is due to class re-opening or what. There's a couple gems that patch Net::HTTP in play.

     Failure/Error: Unable to find matching line from backtrace
     Java::JavaLang::LinkageError:
       loader (instance of  org/jruby/util/ClassCache$OneShotClassLoader): attempted  duplicate class definition for name: "rubyobj/Net/HTTP"
     # java.lang.ClassLoader.defineClass1(Native Method)
     # java.lang.ClassLoader.defineClass(ClassLoader.java:800)
     # org.jruby.util.ClassCache$OneShotClassLoader.defineClass(ClassCache.java:74)
     # org.jruby.RubyClass.reify(RubyClass.java:1477)
     # org.jruby.RubyClass.reifyWithAncestors(RubyClass.java:1185)
     # org.jruby.RubyClass.reifyWithAncestors(RubyClass.java:1160)
     # org.jruby.RubyObject$13.allocate(RubyObject.java:268)
     # org.jruby.RubyClass.allocate(RubyClass.java:224)
     # org.jruby.RubyClass.newInstance(RubyClass.java:810)
     # org.jruby.RubyClass$INVOKER$i$newInstance.call(RubyClass$INVOKER$i$newInstance.gen)
     # org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroOrOneOrTwoOrNBlock.call(JavaMethod.java:314)
     # org.jruby.internal.runtime.methods.AliasMethod.call(AliasMethod.java:66)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:202)
     # org.jruby.ast.CallTwoArgNode.interpret(CallTwoArgNode.java:59)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:225)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:214)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:202)
     # org.jruby.ast.CallTwoArgNode.interpret(CallTwoArgNode.java:59)
     # org.jruby.ast.LocalAsgnNode.interpret(LocalAsgnNode.java:123)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.ast.IfNode.interpret(IfNode.java:118)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:198)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:168)
     # org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
     # org.jruby.ast.YieldThreeNode.interpret(YieldThreeNode.java:33)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.ast.RescueNode.executeBody(RescueNode.java:221)
     # org.jruby.ast.RescueNode.interpret(RescueNode.java:116)
     # org.jruby.ast.BeginNode.interpret(BeginNode.java:83)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:204)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:206)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:336)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:179)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:188)
     # org.jruby.ast.FCallOneArgBlockNode.interpret(FCallOneArgBlockNode.java:34)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:204)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:206)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:336)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:179)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:188)
     # org.jruby.ast.FCallOneArgBlockNode.interpret(FCallOneArgBlockNode.java:34)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:204)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:206)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:336)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:179)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:183)
     # org.jruby.ast.FCallOneArgBlockPassNode.interpret(FCallOneArgBlockPassNode.java:32)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.RescueNode.executeBody(RescueNode.java:221)
     # org.jruby.ast.RescueNode.interpret(RescueNode.java:116)
     # org.jruby.ast.BeginNode.interpret(BeginNode.java:83)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.UntilNode.interpret(UntilNode.java:120)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:161)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:190)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:149)
     # org.jruby.ast.FCallNoArgBlockPassNode.interpret(FCallNoArgBlockPassNode.java:27)
     # org.jruby.ast.ReturnNode.interpret(ReturnNode.java:92)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:182)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:198)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
     # org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:247)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:222)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:211)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:217)
     # org.jruby.ast.CallTwoArgBlockPassNode.interpret(CallTwoArgBlockPassNode.java:62)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:247)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:222)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:211)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:222)
     # org.jruby.ast.CallTwoArgBlockNode.interpret(CallTwoArgBlockNode.java:62)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
     # org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:206)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:157)
     # org.jruby.runtime.Block.yield(Block.java:142)
     # org.jruby.RubyContinuation.enter(RubyContinuation.java:107)
     # org.jruby.RubyKernel.rbCatch19Common(RubyKernel.java:1291)
     # org.jruby.RubyKernel.rbCatch19(RubyKernel.java:1284)
     # org.jruby.RubyKernel$INVOKER$s$rbCatch19.call(RubyKernel$INVOKER$s$rbCatch19.gen)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:177)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:188)
     # org.jruby.ast.FCallOneArgBlockNode.interpret(FCallOneArgBlockNode.java:34)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
     # org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:206)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:157)
     # org.jruby.runtime.Block.yield(Block.java:142)
     # org.jruby.RubyContinuation.enter(RubyContinuation.java:107)
     # org.jruby.RubyKernel.rbCatch19Common(RubyKernel.java:1291)
     # org.jruby.RubyKernel.rbCatch19(RubyKernel.java:1284)
     # org.jruby.RubyKernel$INVOKER$s$rbCatch19.call(RubyKernel$INVOKER$s$rbCatch19.gen)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:177)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:188)
     # org.jruby.ast.FCallOneArgBlockNode.interpret(FCallOneArgBlockNode.java:34)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:225)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:214)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:346)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:204)
     # org.jruby.ast.CallTwoArgNode.interpret(CallTwoArgNode.java:59)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
     # org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:206)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:194)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:177)
     # org.jruby.runtime.Block.yieldNonArray(Block.java:153)
     # org.jruby.RubyBasicObject.yieldUnder(RubyBasicObject.java:1626)
     # org.jruby.RubyBasicObject.specificEval(RubyBasicObject.java:1650)
     # org.jruby.RubyBasicObject.instance_eval19(RubyBasicObject.java:1536)
     # org.jruby.RubyBasicObject$INVOKER$i$instance_eval19.call(RubyBasicObject$INVOKER$i$instance_eval19.gen)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:149)
     # rubyjit$RSpec::Core::Example$$run_ECA6F1685FDED377BC9CC48F4E9EA14B9A3B1AF71974835391$block_0$RUBY$__file__.call(rubyjit$RSpec::Core::Example$$run_ECA6F1685FDED377BC9CC48F4E9EA14B9A3B1AF71974835391$block_0$RUBY$__file__)
     # org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:159)
     # org.jruby.runtime.CompiledBlock19.call(CompiledBlock19.java:87)
     # org.jruby.runtime.Block.call(Block.java:101)
     # org.jruby.RubyProc.call(RubyProc.java:290)
     # org.jruby.RubyProc.call19(RubyProc.java:271)
     # org.jruby.RubyProc$INVOKER$i$0$0$call19.call(RubyProc$INVOKER$i$0$0$call19.gen)
     # org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:202)
     # org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:198)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
     # rubyjit$Module$$extended_F107466764F9D32CA4547344930B7396EADE443E1974835391$method__0$RUBY$run.call(rubyjit$Module$$extended_F107466764F9D32CA4547344930B7396EADE443E1974835391$method__0$RUBY$run)
     # rubyjit$Module$$extended_F107466764F9D32CA4547344930B7396EADE443E1974835391$method__0$RUBY$run.call(rubyjit$Module$$extended_F107466764F9D32CA4547344930B7396EADE443E1974835391$method__0$RUBY$run)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
     # org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:60)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
     # org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:206)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:157)
     # org.jruby.runtime.Interpreted19Block.yieldSpecific(Interpreted19Block.java:135)
     # org.jruby.runtime.Block.yieldSpecific(Block.java:120)
     # org.jruby.ast.executable.AbstractScript.__file__(AbstractScript.java:46)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:241)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:211)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:217)
     # rubyjit$Sequel::Database$$transaction_271D73A6C09BCCBD8B5BB622D7D9F17EB9A2700C1974835391$block_0$RUBY$__file__.call(rubyjit$Sequel::Database$$transaction_271D73A6C09BCCBD8B5BB622D7D9F17EB9A2700C1974835391$block_0$RUBY$__file__)
     # org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:135)
     # org.jruby.runtime.CompiledBlock19.yieldSpecific(CompiledBlock19.java:97)
     # org.jruby.runtime.Block.yieldSpecific(Block.java:120)
     # org.jruby.ast.executable.AbstractScript.__file__(AbstractScript.java:42)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:201)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:177)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:183)
     # org.jruby.ast.executable.AbstractScript.__file__(AbstractScript.java:42)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:201)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:177)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:188)
     # org.jruby.ast.executable.AbstractScript.__file__(AbstractScript.java:42)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:201)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:177)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:188)
     # org.jruby.ast.CallOneArgBlockNode.interpret(CallOneArgBlockNode.java:60)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.IfNode.interpret(IfNode.java:118)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
     # org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:206)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:194)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:177)
     # org.jruby.runtime.Block.yieldNonArray(Block.java:153)
     # org.jruby.RubyBasicObject.yieldUnder(RubyBasicObject.java:1586)
     # org.jruby.RubyBasicObject.instance_exec19(RubyBasicObject.java:1565)
     # org.jruby.RubyBasicObject$INVOKER$i$0$3$instance_exec19.call(RubyBasicObject$INVOKER$i$0$3$instance_exec19.gen)
     # org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:210)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:177)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:183)
     # org.jruby.runtime.callsite.CachingCallSite.callVarargs(CachingCallSite.java:113)
     # org.jruby.ast.executable.AbstractScript.__file__(AbstractScript.java:42)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:201)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:177)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:183)
     # org.jruby.runtime.callsite.CachingCallSite.callVarargs(CachingCallSite.java:113)
     # org.jruby.ast.executable.AbstractScript.__file__(AbstractScript.java:42)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:201)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:177)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:183)
     # rubyjit$RSpec::Core::Hooks::AroundHookCollection$$run_63B279001C638DBF9D91AFCAA27824A0B19D014A1974835391$block_1$RUBY$__file__.call(rubyjit$RSpec::Core::Hooks::AroundHookCollection$$run_63B279001C638DBF9D91AFCAA27824A0B19D014A1974835391$block_1$RUBY$__file__)
     # org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:159)
     # org.jruby.runtime.CompiledBlock19.call(CompiledBlock19.java:87)
     # org.jruby.runtime.Block.call(Block.java:101)
     # org.jruby.RubyProc.call(RubyProc.java:290)
     # org.jruby.RubyProc.call19(RubyProc.java:271)
     # org.jruby.RubyProc$INVOKER$i$0$0$call19.call(RubyProc$INVOKER$i$0$0$call19.gen)
     # org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:202)
     # org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:198)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:141)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:306)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:136)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:121)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:70)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:221)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:202)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:161)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:143)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:221)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:202)
     # rubyjit$RSpec::Core::ExampleGroup$$run_examples_4B7FD91B81FE45AE191B6940E4BF97821BB70E121974835391$block_0$RUBY$__file__.call(rubyjit$RSpec::Core::ExampleGroup$$run_examples_4B7FD91B81FE45AE191B6940E4BF97821BB70E121974835391$block_0$RUBY$__file__)
     # org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:135)
     # org.jruby.runtime.Block.yield(Block.java:142)
     # org.jruby.RubyArray.collect(RubyArray.java:2400)
     # org.jruby.RubyArray.map19(RubyArray.java:2413)
     # org.jruby.RubyArray$INVOKER$i$0$0$map19.call(RubyArray$INVOKER$i$0$0$map19.gen)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:181)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:181)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
     # rubyjit$RSpec::Core::ExampleGroup$$run_98B46A5A09BA87240DA58E2F655A3BB289E655621974835391$block_0$RUBY$__file__.call(rubyjit$RSpec::Core::ExampleGroup$$run_98B46A5A09BA87240DA58E2F655A3BB289E655621974835391$block_0$RUBY$__file__)
     # org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:135)
     # org.jruby.runtime.Block.yield(Block.java:142)
     # org.jruby.RubyArray.collect(RubyArray.java:2400)
     # org.jruby.RubyArray.map19(RubyArray.java:2413)
     # org.jruby.RubyArray$INVOKER$i$0$0$map19.call(RubyArray$INVOKER$i$0$0$map19.gen)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:181)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
     # rubyjit$RSpec::Core::ExampleGroup$$run_98B46A5A09BA87240DA58E2F655A3BB289E655621974835391$block_0$RUBY$__file__.call(rubyjit$RSpec::Core::ExampleGroup$$run_98B46A5A09BA87240DA58E2F655A3BB289E655621974835391$block_0$RUBY$__file__)
     # org.jruby.runtime.CompiledBlock19.yield(CompiledBlock19.java:135)
     # org.jruby.runtime.Block.yield(Block.java:142)
     # org.jruby.RubyArray.collect(RubyArray.java:2400)
     # org.jruby.RubyArray.map19(RubyArray.java:2413)
     # org.jruby.RubyArray$INVOKER$i$0$0$map19.call(RubyArray$INVOKER$i$0$0$map19.gen)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
     # org.jruby.internal.runtime.methods.JittedMethod.call(JittedMethod.java:181)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
     # org.jruby.ast.CallOneArgNode.interpret(CallOneArgNode.java:57)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
     # org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:206)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:157)
     # org.jruby.runtime.Block.yield(Block.java:142)
     # org.jruby.RubyArray.collect(RubyArray.java:2400)
     # org.jruby.RubyArray.map19(RubyArray.java:2413)
     # org.jruby.RubyArray$INVOKER$i$0$0$map19.call(RubyArray$INVOKER$i$0$0$map19.gen)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:316)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:145)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:154)
     # org.jruby.ast.CallNoArgBlockNode.interpret(CallNoArgBlockNode.java:64)
     # org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:60)
     # org.jruby.ast.IfNode.interpret(IfNode.java:110)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.ast.EnsureNode.interpret(EnsureNode.java:96)
     # org.jruby.ast.BeginNode.interpret(BeginNode.java:83)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
     # org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:206)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:157)
     # org.jruby.runtime.Interpreted19Block.yieldSpecific(Interpreted19Block.java:135)
     # org.jruby.runtime.Block.yieldSpecific(Block.java:120)
     # org.jruby.ast.YieldOneNode.interpret(YieldOneNode.java:35)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.EnsureNode.interpret(EnsureNode.java:96)
     # org.jruby.ast.BeginNode.interpret(BeginNode.java:83)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:247)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:222)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:356)
     # org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:213)
     # org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:222)
     # org.jruby.ast.CallTwoArgBlockNode.interpret(CallTwoArgBlockNode.java:62)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:225)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:214)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:346)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:204)
     # org.jruby.ast.CallTwoArgNode.interpret(CallTwoArgNode.java:59)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.IfNode.interpret(IfNode.java:118)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.ast.EnsureNode.interpret(EnsureNode.java:96)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
     # org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:268)
     # org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:230)
     # org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:366)
     # org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:238)
     # org.jruby.ast.FCallThreeArgNode.interpret(FCallThreeArgNode.java:40)
     # org.jruby.ast.CallNoArgNode.interpret(CallNoArgNode.java:60)
     # org.jruby.ast.DAsgnNode.interpret(DAsgnNode.java:110)
     # org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
     # org.jruby.ast.BlockNode.interpret(BlockNode.java:71)
     # org.jruby.evaluator.ASTInterpreter.INTERPRET_BLOCK(ASTInterpreter.java:112)
     # org.jruby.runtime.Interpreted19Block.evalBlockBody(Interpreted19Block.java:206)
     # org.jruby.runtime.Interpreted19Block.yield(Interpreted19Block.java:194)
     # org.jruby.runtime.Interpreted19Block.call(Interpreted19Block.java:125)
     # org.jruby.runtime.Block.call(Block.java:101)
     # org.jruby.RubyProc.call(RubyProc.java:290)
     # org.jruby.RubyProc.call(RubyProc.java:228)
     # org.jruby.Ruby.tearDown(Ruby.java:3026)
     # org.jruby.Ruby.tearDown(Ruby.java:3010)
     # org.jruby.Main.internalRun(Main.java:294)
     # org.jruby.Main.run(Main.java:217)
     # org.jruby.Main.main(Main.java:197)
@nirvdrum
Contributor

Just to clarify, my ruby version is:

jruby 1.7.8 (1.9.3p392) 2013-11-14 0ce429e on Java HotSpot(TM) 64-Bit Server VM 1.7.0_45-b18 [linux-amd64]

@headius
Member
headius commented Nov 19, 2013

Ok, so I realized after looking at the code that it doesn't ever try to load the class it's about to generate, so that's something. However, if a given class has been reified, it should have its reifiedClass field to that class and reification shouldn't start up agin. Continuing investigation.

@nirvdrum
Contributor

I finally got a reproduction case. You'll need the webmock gem installed (I'm using 1.8.11) and something else that tries to use Net::HTTP. For simplicity, I'll use rest-client here:

require 'webmock'
require 'rest-client'

RestClient.get('http://google.com/')

That will blow up with something like:

Java::JavaLang::LinkageError: loader (instance of  org/jruby/util/ClassCache$OneShotClassLoader): attempted  duplicate class definition for name: "rubyobj/Net/HTTP"
    from java.lang.ClassLoader.defineClass1(Native Method)
    from java.lang.ClassLoader.defineClass(ClassLoader.java:800)
    from org.jruby.util.ClassCache$OneShotClassLoader.defineClass(ClassCache.java:74)
    from org.jruby.RubyClass.reify(RubyClass.java:1477)
    from org.jruby.RubyClass.reifyWithAncestors(RubyClass.java:1185)
    from org.jruby.RubyClass.reifyWithAncestors(RubyClass.java:1160)
    from org.jruby.RubyObject$13.allocate(RubyObject.java:268)
    from org.jruby.RubyClass.allocate(RubyClass.java:224)
    from org.jruby.RubyClass.newInstance(RubyClass.java:810)
    from org.jruby.RubyClass$INVOKER$i$newInstance.call(RubyClass$INVOKER$i$newInstance.gen)
    from org.jruby.internal.runtime.methods.JavaMethod$JavaMethodZeroOrOneOrTwoOrNBlock.call(JavaMethod.java:314)
    from org.jruby.internal.runtime.methods.AliasMethod.call(AliasMethod.java:66)
    from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:346)
    from org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:204)
    from home.nirvdrum.$_dot_rbenv.versions.jruby_minus_1_dot_7_dot_8.lib.ruby.$1_dot_9.net.http_dot_rb.method__20$RUBY$new(/home/nirvdrum/.rbenv/versions/jruby-1.7.8/lib/ruby/1.9/net/http.rb:569)
    from home$nirvdrum$$_dot_rbenv$versions$jruby_minus_1_dot_7_dot_8$lib$ruby$$1_dot_9$net$http_dot_rb$method__20$RUBY$new.call(home$nirvdrum$$_dot_rbenv$versions$jruby_minus_1_dot_7_dot_8$lib$ruby$$1_dot_9$net$http_dot_rb$method__20$RUBY$new)
... 92 levels...
    from org.jruby.runtime.callsite.CachingCallSite.callIter(CachingCallSite.java:188)
    from home$nirvdrum$$_dot_rbenv$versions$jruby_minus_1_dot_7_dot_8$lib$ruby$$1_dot_9$irb_dot_rb$method__5$RUBY$start.call(home$nirvdrum$$_dot_rbenv$versions$jruby_minus_1_dot_7_dot_8$lib$ruby$$1_dot_9$irb_dot_rb$method__5$RUBY$start)
    from org.jruby.internal.runtime.methods.DynamicMethod.call(DynamicMethod.java:210)
    from org.jruby.internal.runtime.methods.CompiledMethod.call(CompiledMethod.java:263)
    from org.jruby.runtime.callsite.CachingCallSite.cacheAndCall(CachingCallSite.java:326)
    from org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:170)
    from home.nirvdrum.$_dot_rbenv.versions.jruby_minus_1_dot_7_dot_8.bin.irb.__file__(/home/nirvdrum/.rbenv/versions/jruby-1.7.8/bin/irb:13)
    from home.nirvdrum.$_dot_rbenv.versions.jruby_minus_1_dot_7_dot_8.bin.irb.load(/home/nirvdrum/.rbenv/versions/jruby-1.7.8/bin/irb)
    from org.jruby.Ruby.runScript(Ruby.java:811)
    from org.jruby.Ruby.runScript(Ruby.java:804)
    from org.jruby.Ruby.runNormally(Ruby.java:673)
    from org.jruby.Ruby.runFromMain(Ruby.java:522)
    from org.jruby.Main.doRunFromMain(Main.java:395)
    from org.jruby.Main.internalRun(Main.java:290)
    from org.jruby.Main.run(Main.java:217)
    from org.jruby.Main.main(Main.java:197)
@nirvdrum
Contributor

My naive guess is it has to do with this construct:

https://github.com/bblimke/webmock/blob/5662ca4c2fdb5e9d63deca99a86d6dd99bb12c48/lib/webmock/http_lib_adapters/net_http.rb#L43

@webMockNetHTTP = Class.new(Net::HTTP) do

@headius
Member
headius commented Nov 27, 2013

Excellent job on the repro. It's perfect.

@headius
Member
headius commented Nov 27, 2013

At a quick glance, it looks like two classes in the reifying hierarchy resolve to the same name (Net::HTTP), so when they go to reify they overlap. I'm unclear why they appear to be the same class.

@headius
Member
headius commented Nov 27, 2013

You're right about things stemming from that line in webmock, but I have been unable to come up with a smaller reproduction. It does seem that the creation of that new anonymous Net::HTTP subclass is at least partially to blame.

@headius
Member
headius commented Nov 27, 2013

So here's the thing. The two classes that are conflicting actually are named the same and in a parent/child relationship.

I have a reproduction that simulates the webmock case:

module Bar
  class Foo; end
end

foo = Bar::Foo
Bar.send :remove_const, :Foo
Bar.const_set :Foo, Class.new(foo)

Bar::Foo.new

Ruby classes created via Class.new are initially nameless, anonymous classes. Once assigned to a constant, however, they gain that name. As a result, the child class ends up with the same name as the superclass.

In a superclass/child class relationship, we currently create them in the same classloader. I need to refresh my memory why I did it this way, but the effect here is that we try to define two rubyobj.Net.HTTP classes.

Using a child classloader does not solve the issue either, since then we're defining a rubyobj.Net.HTTP class that extends ruby.Net.HTTP, and although the definition could normally proceed, the parent/child relationship appears to be circular to the JVM.

There are a few possible fixes here.

  • We could use the class's unique ID as part of the name. This would prevent two same-named classes from stepping on each other, but it would also produce less-attractive names like rubyobj.Net.HTTP_15.
  • We could skip generating a child class if the JVM class name we intended to use is already taken. This would silently fail to define the reified class when there's a naming conflict in the same hierarchy, but the classes it does define would still have clean names.
  • We could do some combination of the two, only adding ID when we have this sort of situation.

The latter might be a good enough option for the short term, to have a fix in 1.7.9. These cases should be pretty rare, and it would be a better choice than having reified classes under some circumstances have different names than in previous releases.

Additional to-do for me is to investigate why the child classes do not generate into their own classloaders. The current behavior could cause a class leak if many new child classes are created and reified.

@nirvdrum
Contributor

The latter would be fine for me. Even skipping the name would be likely be okay. It seems to be a pretty rare case and I'd be happy to hit the 99% case.

@headius
Member
headius commented Nov 27, 2013

I'm going to go with the case of simply not reifying the class when it conflicts with another of the same name in the same classloader. I believe this case is only possible when you have a ancestor/descendant relationship where the ancestor and the descendant have the same fully-qualified name, so this is an ok fix for 1.7.9.

@headius
Member
headius commented Nov 27, 2013

Fixed by 6a14a09 on jruby-1_7 and c50fb9b on master.

@headius headius closed this Nov 27, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment