Forum: JRuby JRuby-Rack internal questions to integrate Quartz in JRoR

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Afcbc505100242cabd5f8eba7d7e793b?d=identicon&s=25 Christian Mueller (muellerc)
on 2008-12-07 19:58
(Received via mailing list)
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)

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-w....
The
code is now hosted here
http://github.com/macarthy/mirror-quartz-jruby-plu....
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.*"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "
http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html;
charset=ISO-8859-1">
        <title>Insert title here</title>
    </head>
    <body>
        <%    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);
                }
            }
        %>
    </body>
</html>

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 <script>: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(<script>: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(<script>:3)
  (unknown).(unknown)(:1)



Any idee why my code blows up?

Thanks for every help,
Christian
A00896682682432bc0c1bd0ba30aa80a?d=identicon&s=25 Nick Sieger (Guest)
on 2008-12-07 23:33
(Received via mailing list)
On Sun, Dec 7, 2008 at 12:57 PM, Christian
Müller<christian.mueller@gmail.com> wrote:
> 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/).

Cool. Let me know how this progresses, maybe I can integrate it into
either JRuby-Rack or an offshoot project. Or start your own if you
like.

> 
(unknown).(unknown)(/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:11)
>
> 
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(<script>:3)
>   (unknown).(unknown)(:1)
>
>
> Any idee why my code blows up?

If you look in config/boot.rb, there are a number of ways that Rails
exits, either if you don't have the Rails gem properly installed, or
if you don't have a recent enough version of Rubygems. Are either of
these the problem?

/Nick

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Afcbc505100242cabd5f8eba7d7e793b?d=identicon&s=25 Christian Mueller (muellerc)
on 2008-12-08 10:52
(Received via mailing list)
> Cool. Let me know how this progresses, maybe I can integrate it into
> either JRuby-Rack or an offshoot project. Or start your own if you
> like.


I will share my knowledge with the community and create a gem/plugin.
Maybe
we find an other integration solution (JRuby-Rack, ...). I will keep you
up-to-date...


If you look in config/boot.rb, there are a number of ways that Rails
> exits, either if you don't have the Rails gem properly installed, or
> if you don't have a recent enough version of Rubygems. Are either of
> these the problem?


My favorite combinations are jruby-1.1.5 + jruby-rack-0.9.2 +
rails-2.2.2 +
rubyGems-1.3.1 or jruby-1.1.6RC1 + jruby-rack-0.9.3 + rails-2.2.2 +
rubyGems-1.3.1. It is ok?
At this moment, what are your recommendation for the development?

Christian
526d60de6472502bb570a9df2842b33b?d=identicon&s=25 Nick Sieger (Guest)
on 2008-12-08 14:49
(Received via mailing list)
On Mon, Dec 8, 2008 at 3:51 AM, Christian
Müller<christian.mueller@gmail.com> wrote:
>> If you look in config/boot.rb, there are a number of ways that Rails
>> exits, either if you don't have the Rails gem properly installed, or
>> if you don't have a recent enough version of Rubygems. Are either of
>> these the problem?
>
> My favorite combinations are jruby-1.1.5 + jruby-rack-0.9.2 + rails-2.2.2 +
> rubyGems-1.3.1 or jruby-1.1.6RC1 + jruby-rack-0.9.3 + rails-2.2.2 +
> rubyGems-1.3.1. It is ok?
> At this moment, what are your recommendation for the development?

I have personally seen some problems with JRuby 1.1.5 and Rubygems
1.3.1, but I can't tell if that's what is causing your problem. Is
there any difference in the error you see when using JRuby 1.1.5 vs.
JRuby 1.1.6RC1? I'll be recommending JRuby 1.1.6 as soon as it's
released.

/Nick

---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
5a579b3ae2e98ebcc09403f38a390216?d=identicon&s=25 Matt Burke (Guest)
on 2008-12-08 14:57
(Received via mailing list)
Out of curiosity, have you looked at the quartz_rails plugin? It's still
built for jruby 1.0.1, so it'd need to be rebuilt, but might be a good
starting point for you.

http://www.jkraemer.net/2008/1/12/job-scheduling-w...
http://github.com/macarthy/mirror-quartz-jruby-plu...

--
Matt

Christian Müller wrote:
>
>   include org.quartz.Job
>
>
> '0 * * * * ?') # runs every minute
>
>
> }
> <html>
>                 Ruby runtime = rackApplication.getRuntime();
>
>   from 
/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/environment.rb:29:in 
`load'
>
>   javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
>
> 
(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)
> Thanks for every help,
> Christian


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Afcbc505100242cabd5f8eba7d7e793b?d=identicon&s=25 Christian Mueller (muellerc)
on 2008-12-08 16:54
(Received via mailing list)
Hi Matt,

yes I have. But first, I looking for a more ruby like solution and when
this
failed, I found Jens plugin and the "rebuild" or update of this plugin
failes... :-(

Christian
5a579b3ae2e98ebcc09403f38a390216?d=identicon&s=25 Matt Burke (Guest)
on 2008-12-08 21:46
(Received via mailing list)
We ran into that problem too. I forked the git repo I had linked to, and
added java source, our changes, and a quick change to use jruby-rack
instead of goldspike. It builds now, but I haven't tested it.

http://github.com/spraints/mirror-quartz-jruby-plu...

Hope that helps,
Matt


Christian Müller wrote:
>
>
>         My first (naive) approache was, to implement the (java)
>         include_class 'org.quartz.JobExecutionContext'
>         some lines of code:
>         include_class 'org.quartz.JobDetail'
>         LoggingJob.java_class) # failed also with LoggingJob.new.java_class
>         I hope it is possible in the future. :-)
>         http://github.com/macarthy/mirror-quartz-jruby-plu....
>         } finally {
>         charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
>                <%    RackApplicationFactory factory =
>                    }
> 
/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/config/boot.rb:38:in
>                from
>         `load_environment'
> 
file:/Applications/apache-tomcat-6.0.18/webapps/quartz_demo/WEB-INF/lib/jruby-rack-0.9.2.jar!/rack/builder.rb:22:in
>                org.apache.jsp.index2_jsp._jspService(index2_jsp.java:68)
>          org.apache.jasper.servlet.JspServlet.service(JspServlet.java:267)
>
>
>
>
>       http://xircles.codehaus.org/manage_email
>
>
>


---------------------------------------------------------------------
To unsubscribe from this list, please visit:

    http://xircles.codehaus.org/manage_email
Afcbc505100242cabd5f8eba7d7e793b?d=identicon&s=25 Christian Mueller (muellerc)
on 2008-12-08 23:08
(Received via mailing list)
Hi Matt,

it look like my attempt to solve the problem. I will try it in the next
days...
At this moment, I looking again for a more ruby like solution, so that
other
ruby people easier can understand it. My current state is following:

RAILS_ROOT/config/initializers/quartz_scheduler.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 'sharing_stateless_job_factory'
require 'sharing_stateless_job_detail'

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.setJobFactory SharingStatelessJobFactory.new
scheduler.startDelayed 5

RAILS_DEFAULT_LOGGER.info 'intializing LoggingJob...'
job = SharingStatelessJobDetail.new('LoggingJob', 'schedulingGroup',
LoggingJob.new)
trigger = org.quartz.CronTrigger.new('LoggingJobTrigger',
'schedulingGroup',
'0 * * * * ?')
scheduler.scheduleJob(job, trigger)

RAILS_DEFAULT_LOGGER.info 'Finished initializing quartz scheduler and
jobs'



RAILS_ROOT/lib/logging_job.rb

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




RAILS_ROOT/lib/sharing_stateless_job_detail.rb

include_class 'org.quartz.JobDetail'
include_class 'org.quartz.SchedulerException'

class SharingStatelessJobDetail < org.quartz.JobDetail

  attr_accessor :job

  def initialize(name, group, job)
    super()
    setName name
    setGroup group
    @job = job
  end

  def validate
    raise org.quartz.SchedulerException.new("Job's name cannot be null",
org.quartz.SchedulerException.ERR_CLIENT_ERROR) if getName == nil
    raise org.quartz.SchedulerException.new("Job's group cannot be
null",
org.quartz.SchedulerException.ERR_CLIENT_ERROR) if getGroup == nil
  end
end




RAILS_ROOT/lib/sharing_stateless_job_factory.rb

include_class 'org.quartz.spi.JobFactory'
include_class 'org.quartz.spi.TriggerFiredBundle'
include_class 'org.quartz.JobDetail'

class SharingStatelessJobFactory
  include org.quartz.spi.JobFactory

  def newJob bundle
    jobDetail = bundle.getJobDetail
    jobDetail.job
  end
end


added
   RAILS_ROOT/lib/commons-logging-1.1.jar
   RAILS_ROOT/lib/commons-collections-3.2.jar
   RAILS_ROOT/lib/commons-pool-1.3.jar
   RAILS_ROOT/lib/quartz-all-1.6.4.jar



And look, it works... :-)

** Rails loaded.
** Loading any Rails specific GemPlugins
** Signals ready.  TERM => stop.  USR2 => restart.  INT => stop (no
restart).
** Rails signals registered.  HUP => reload (without restart).  It might
not
work well.
** Mongrel 1.1.5 available at 0.0.0.0:3000
** Use CTRL-C to stop.
Dec 8, 2008 10:39:56 PM org.quartz.core.QuartzScheduler start
INFO: Scheduler DefaultQuartzScheduler_$_NON_CLUSTERED started.
LoggingJob scheduled at Mon Dec 08 22:40:00 +0100 2008
LoggingJob scheduled at Mon Dec 08 22:41:00 +0100 2008
LoggingJob scheduled at Mon Dec 08 22:42:00 +0100 2008

This version has a lot of issues:
   - CTRL + C does't work (you must kill the process) --> implement a
shutdown hook
   - ensure, we start only one Scheduler per web app
   - many more... :-)

But I think it is a good starting point for my first rails plugin/gem...

Regards,
Christian

P.S. Sorry for the java code style. I will fix this...
This topic is locked and can not be replied to.