Hello list,
I wrote a rails app and deployed it (with warbler and JRuby-Rack) in
tomcat.
Now, I need some sheduling functionality for health check, reporting,
…
Because I have a java background and I’m familiar with, I decided to use
Quartz (http://www.opensymphony.com/quartz/).
My first (naive) approache was, to implement the (java) interface
org.quartz.Job in jruby and provide a simple logging Job:
RAILS_ROOT/lib/logging_job.rb:
require ‘java’
require ‘lib/commons-logging-1.1.jar’
require ‘lib/commons-collections-3.2.jar’
require ‘lib/commons-pool-1.3.jar’
require ‘lib/quartz-all-1.6.4.jar’
include_class ‘org.quartz.Job’
include_class ‘org.quartz.JobExecutionContext’
class LoggingJob
include org.quartz.Job
def execute context
RAILS_DEFAULT_LOGGER.info “LoggingJob scheduled at #{Time.now}”
end
end
The next thing was to shedule the job. This is finished with some lines
of
code:
RAILS_ROOT/config/initializers/quartz_sheduler.rb
require ‘java’
require ‘lib/commons-logging-1.1.jar’
require ‘lib/commons-collections-3.2.jar’
require ‘lib/commons-pool-1.3.jar’
require ‘lib/quartz-all-1.6.4.jar’
require ‘logging_job’
include_class ‘org.quartz.impl.StdSchedulerFactory’
include_class ‘org.quartz.JobDetail’
include_class ‘org.quartz.CronTrigger’
RAILS_DEFAULT_LOGGER.info ‘intializing Quartz Scheduler…’
scheduler = org.quartz.impl.StdSchedulerFactory.getDefaultScheduler
scheduler.startDelayed 30
scheduler.start
RAILS_DEFAULT_LOGGER.info ‘intializing LoggingJob…’
job = org.quartz.JobDetail.new(‘LoggingJob’, ‘railsJob’,
LoggingJob.java_class) # failed also with LoggingJob.new.java_class
trigger = org.quartz.CronTrigger.new(‘LoggingCronTrigger’, ‘railsJob’,
'0 *
-
-
- ?') # runs every minute
scheduler.scheduleJob(job, trigger)
- ?') # runs every minute
-
RAILS_DEFAULT_LOGGER.info ‘Finished initializing quartz scheduler and
jobs’
But the problem is, that quartz can’t instantiate the (j)ruby class
LoggingJob from java…
I hope it is possible in the future.
But if i wrong, please point it out.
My next attempt was to write in java a ServletContextListener which has
the
same functionality as the quartz_sheduler.rb and a RailsJob, which
implements the org.quartz.Job interface and simply load a ruby script
and
execute it. I found an article and a plugin from Jens Krämer
http://www.jkraemer.net/2008/1/12/job-scheduling-with-jruby-and-rails.
The
code is now hosted here
http://github.com/macarthy/mirror-quartz-jruby-plugin/tree/master.
But the code is incompatible with the JRuby-Rack trunk. So, I deceided
to
use this code as a starting point and update it. To lookup the ruby
runtime,
I do the following:
RackApplicationFactory factory = (RackApplicationFactory)
application.getAttribute(RackServletContextListener.FACTORY_KEY);
RackApplication rackApplication = null;
try {
rackApplication = factory.getApplication();
Ruby runtime = rackApplication.getRuntime();
} finally {
if (rackApplication != null) {
factory.finishedWithApplication(rackApplication);
}
}
But the code crashes and I have no idee why…
Then, I wrote a simple JSP to find the reason:
WEB-INF/index2.jsp
<%@ page language=“java” contentType=“text/html; charset=ISO-8859-1”
pageEncoding=“ISO-8859-1”%>
<%@ page import=“org.jruby., org.jruby.rack.”%>
This gives me the following stack trace (JRuby-Rack 0.9.2 and JRuby
1.1.4):
org.jruby.rack.RackInitializationException: exit
from
/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:38:in
run' from file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/jruby/rack/rails_boot.rb:20:in
run’
from
/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:11:in
boot!' from /Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:109 from /Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:11:in
require’
from
/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/environment.rb:11
from
/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/environment.rb:29:in
load' from file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/jruby/rack/rails.rb:29:in
load_environment’
from
file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/jruby/rack/rails.rb:152:in
new' from <script>:3 from file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/rack/builder.rb:22:in
instance_eval’
from
file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/rack/builder.rb:22:in
`initialize’
from :3
org.jruby.rack.DefaultRackApplicationFactory$4.init(DefaultRackApplicationFactory.java:154)
org.jruby.rack.DefaultRackApplicationFactory.getApplication(DefaultRackApplicationFactory.java:53)
org.jruby.rack.PoolingRackApplicationFactory.getApplication(PoolingRackApplicationFactory.java:92)
org.apache.jsp.index2_jsp._jspService(index2_jsp.java:68)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:374)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:342)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
org.jruby.rack.RackFilter.doFilter(RackFilter.java:47)
root cause
org.jruby.exceptions.RaiseException
#Class:01xde81ff.load_rubygems(/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:52)
Rails::GemBoot.load_initializer(/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:38)
Rails::Boot.run(file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/jruby/rack/rails_boot.rb:20)
Rails::BootHook.run(/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:11)
#Class:01xe6f118.boot!(/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:109)
(unknown).(unknown)(/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:11)
Kernel.require(/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/environment.rb:11)
(unknown).(unknown)(/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/environment.rb:29)
Kernel.load(file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/jruby/rack/rails.rb:29)
JRuby::Rack::RailsServletHelper.load_environment(file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/jruby/rack/rails.rb:152)
#Class:01x22d561.new(:3)
(unknown).(unknown)(file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/rack/builder.rb:22)
Kernel.instance_eval(file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/rack/builder.rb:22)
Kernel.instance_eval(file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/rack/builder.rb:22)
Rack::Builder.initialize(:3)
(unknown).(unknown)(:1)
Any idee why my code blows up?
Thanks for every help,
Christian