JRuby/Tomcat thread hanging issue

Hi -

I saw a tomcat thread issue on the forum, but it did not have an answer
to my question.

JRuby on Rails (2.1.1), Tomcat (6.0.18)

I have successfully deployed a JRuby app to Tomcat that starts a new
thread, here is the code:

Thread.new {

scheduler = Rufus::Scheduler.start_new

scheduler.cron “0 2 * * *”, :tags => “sov” do
#do some stuff
end

ActiveRecord::Base.verify_active_connections!()

}

This works well. However, the next time I deploy, I get an exception
in catalina.out after Tomcat undeploys my original app and the Thread
is still alive and tries to access the environment, but it’s been
undeployed. See stack below. The new app deploys, but the old thread
is still out there. Looks like the unschedule method in the
rufus-scheduler gem fails because it can’t find the app. So I end up
with old threads hanging out there. Only solution is to restart tomcat,
which isn’t a great solution. Is there anyway to force this thread to
die?

I do a kill -3 after redeploying and I can see the new and old threads.

I believe this to be a tomcat issue in how it handles java threads. It
just hangs on to them, and eventually PermGen is full. Please offer any
ideas. Thanks.

Oct 7, 2008 2:25:24 PM org.apache.catalina.loader.WebappClassLoader
loadClass
INFO: Illegal access: this web application instance has been stopped
already. Could not load org.jruby.runtime.Frame$1. The eventual
following stack trace is caused by an error thrown for debugging
purposes as well as to attempt to terminate the thread which caused
the illegal access, and has no functional impact.
java.lang.IllegalStateException
at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:
1273)
at
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:
1233)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:
319)
at org.jruby.runtime.Frame
$BackrefAndLastline.(Frame.java:92)
at org.jruby.runtime.Frame.lazyBackrefAndLastline(Frame.java:
343)
at org.jruby.runtime.Frame.(Frame.java:133)
at org.jruby.runtime.Frame.duplicate(Frame.java:250)
at org.jruby.runtime.Binding.(Binding.java:63)
at
org.jruby.runtime.CompiledBlock.newCompiledClosure(CompiledBlock.java:
74)
at
org.jruby.javasupport.util.RuntimeHelpers.createBlock(RuntimeHelpers.java:
84)
at ruby.jit.ruby....releases.
$20081007185354.WEB_minus_INF.gems.gems.rufus_minus_scheduler_minus_1_dot_0_dot_11.lib.rufus.scheduler.step_unschedule30681653_33198469.file(scheduler.rb:
897)
at
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:
202)
at org.jruby.runtime.CallSite
$InlineCachingCallSite.call(CallSite.java:340)
at ruby.jit.ruby.
.
.***.releases.
$20081007185354.WEB_minus_INF.gems.gems.rufus_minus_scheduler_minus_1_dot_0_dot_11.lib.rufus.scheduler.step10715419_33198469.file(scheduler.rb:
879)
at
org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:
202)
at org.jruby.runtime.CallSite
$InlineCachingCallSite.call(CallSite.java:340)
at org.jruby.ast.VCallNode.interpret(VCallNode.java:82)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:101)
at org.jruby.ast.BlockNode.interpret(BlockNode.java:67)
at
org.jruby.runtime.InterpretedBlock.evalBlockBody(InterpretedBlock.java:
202)
at
org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:153)
at org.jruby.runtime.Block.yield(Block.java:105)
at org.jruby.RubyKernel.loop(RubyKernel.java:1039)
at org.jruby.RubyKernel$s_method_0_0$RUBYFRAMEDINVOKER
$loop.call(org/jruby/RubyKernel$s_method_0_0$RUBYFRAMEDINVOKER
$loop.gen)
at org.jruby.runtime.CallSite
$InlineCachingCallSite.cacheAndCall(CallSite.java:144)
at org.jruby.runtime.CallSite
$InlineCachingCallSite.callIter(CallSite.java:374)
at
org.jruby.ast.FCallNoArgBlockNode.interpret(FCallNoArgBlockNode.java:
31)
at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:101)
at org.jruby.ast.BlockNode.interpret(BlockNode.java:67)
at
org.jruby.runtime.InterpretedBlock.evalBlockBody(InterpretedBlock.java:
202)
at
org.jruby.runtime.InterpretedBlock.yield(InterpretedBlock.java:190)
at org.jruby.runtime.BlockBody.call(BlockBody.java:64)
at org.jruby.runtime.Block.call(Block.java:101)
at org.jruby.RubyProc.call(RubyProc.java:200)
at org.jruby.RubyProc.call(RubyProc.java:187)
at
org.jruby.internal.runtime.RubyRunnable.run(RubyRunnable.java:90)
at java.lang.Thread.run(Thread.java:595)