Newbie questions

View: New views
2 Messages — Rating Filter:   Alert me  

Newbie questions

by Kevin S. Lim :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,
Here are some of my questions regarding java integration with ruby app.
Thanks in advance,
Kevin


1) Jruby on Rails
I'm trying to have a java process created when rails app is started by 'jruby -S start/server'.

I do this by putting my_init.rb under config/initializers

# run on initialization
include Java
require "./lib/myjava.jar"
java_service = ServiceInitializer.new

where myjava.jar contains ServiceIntializer java class.

[Q1]  Is this right way to initialize java process for rails app?  What is the general approach?
[Problem]  Even when I do other operations, for example, 'jruby -S rake db:migrate', this initialization routine seems to run.

2) Implementing java interface with jruby
In my ServiceInitializer java code, I create an instance of ruby class as the implementation of one java interface. 
I wanted this ruby implementation to be able to access all rails facilities that rails app uses.

[Q2]  However, I had to manually connect to db and all, to get this work.  Does this sound right?
To me, it looks defeating its purpose of initializing from rails init.
My implementation class file rubyinterfacehandler.rb had to have all these

require "rubygems"
require "active_record"
require "app/models/dbmodel.rb"

# We had to do this manually since interface is
# called from outside of rails?
ActiveRecord::Base::establish_connection(
:adapter=>"jdbcmysql",
:database=>"db_development",
:pool=>5,
:username=>"root",
:password=>"",
:host=>"localhost")

class RubyInterfaceHandler
  def interface_method
    ...
  end
end

3) Creating war with warble and putting rails on Tomcat.
[Problem] My RubyFactory who is instantiating rubyinterfacehandler cannot find rubyinterfacehandler.rb file which is located in rails project directory.
I see the file gets populated in WEB-INF folder when war expanded.  
I tried to copy the ruby files to WEB-INF/lib also inside WEB-INF/lib/myjava.jar where RubyFactory class is but all didn't work.
[Q3] Where will be the root path from the java class that were in a jar file in the lib directory?  How can I make it to find ruby files in rails app?
[Q4] Shall I move out the java process initialization code to Tomcat web app context initialization area? Perhaps add a ContextListener?  
What is the general approach if I want to add webapp context init codes and still want to use warbler?

4) Running rails app using glassfish gem.
[Problem] When I issue command 'glassfish', log shows followings where XXXX is the java interface class (implemented with ruby) that is in rails' lib/myjava.jar.
This must be coming out from RubyFactory

SEVERE: org.jruby.exceptions.RaiseException: cannot load Java class XXXX
Oct 28, 2009 1:55:13 PM com.sun.grizzly.config.GrizzlyServiceListener
SEVERE: java.lang.NoClassDefFoundError: XXXX
        from java/lang/ClassLoader.java:700:in `defineClass'
        from org/jruby/util/JRubyClassLoader.java:22:in `defineClass'
        from org/jruby/java/MiniJava.java:576:in `defineOldStyleImplClass'
        from org/jruby/java/MiniJava.java:194:in `createOldStyleImplClass'
        from org/jruby/javasupport/Java.java:1570:in `new_proxy_instance2'
        from org/jruby/java/proxies/JavaInterfaceTemplate.java:262:in `jcreateProxy'
        from org/jruby/java/proxies/JavaInterfaceTemplate.java:22:in `access$000'
        from org/jruby/java/proxies/JavaInterfaceTemplate.java:165:in `call'
         ... 132 levels...
        from /usr/local/jruby/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/initializer.rb:113:in `run'

[Q5] With glassfish, is there different way to specify classpath of rails app libs?  (for GrizzlyServiceListener?)
[Q6] Again, shall I move app context init code to somewhere else in case with glassfish?  Is there better approach?




Re: Newbie questions

by Nick Sieger-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Nov 2, 2009 at 2:47 PM, Kevin S. Lim <slim@...> wrote:

> Hi,
> Here are some of my questions regarding java integration with ruby app.
> Thanks in advance,
> Kevin
>
> 1) Jruby on Rails
> I'm trying to have a java process created when rails app is started by
> 'jruby -S start/server'.
> I do this by putting my_init.rb under config/initializers
> # run on initialization
> include Java
> require "./lib/myjava.jar"
> java_service = ServiceInitializer.new
> where myjava.jar contains ServiceIntializer java class.
> [Q1]  Is this right way to initialize java process for rails app?  What is
> the general approach?

Seems like a reasonable thing to do.

> [Problem]  Even when I do other operations, for example, 'jruby -S rake
> db:migrate', this initialization routine seems to run.

Right. The Rails environment gets loaded for many things, not just
when the server is run. You might be able to workaround by adding a
"lib/tasks/constants.rake" file with the contents "IN_RAKE = true".
Then you can guard the above initialization code with "unless
defined?(IN_RAKE) ... end".

> 2) Implementing java interface with jruby
> In my ServiceInitializer java code, I create an instance of ruby class as
> the implementation of one java interface.
> (I've used RubyFactory approach seen at
> http://lawrencesong.net/2008/01/implement-java-interface-in-ruby/)
> I wanted this ruby implementation to be able to access all rails facilities
> that rails app uses.
> [Q2]  However, I had to manually connect to db and all, to get this work.
>  Does this sound right?
> To me, it looks defeating its purpose of initializing from rails init.
> My implementation class file rubyinterfacehandler.rb had to have all these
> require "rubygems"
> require "active_record"
> require "app/models/dbmodel.rb"
> # We had to do this manually since interface is
> # called from outside of rails?
> ActiveRecord::Base::establish_connection(
> :adapter=>"jdbcmysql",
> :database=>"db_development",
> :pool=>5,
> :username=>"root",
> :password=>"",
> :host=>"localhost")
> class RubyInterfaceHandler
>   def interface_method
>     ...
>   end
> end

You can use the ActiveRecord connection from initializers and pass
that into your Java class. The actual JDBC Connection object can be
reached with "ActiveRecord::Base.connection.raw_connection.connection".
Yeah, it's a bit much, but it should work. :)

You can also grab database connection info by grabbing the hash from
"ActiveRecord::Base.configurations[RAILS_ENV]".

> 3) Creating war with warble and putting rails on Tomcat.
> [Problem] My RubyFactory who is instantiating rubyinterfacehandler cannot
> find rubyinterfacehandler.rb file which is located in rails project
> directory.
> I see the file gets populated in WEB-INF folder when war expanded.
> I tried to copy the ruby files to WEB-INF/lib also inside
> WEB-INF/lib/myjava.jar where RubyFactory class is but all didn't work.
> [Q3] Where will be the root path from the java class that were in a jar file
> in the lib directory?  How can I make it to find ruby files in rails app?

You shouldn't assume any specific current directory. Rather, make use
of the load path to ensure that ruby and jar files are found. For
example, if you put your rubyinterfacehandler.rb and myjava.jar files
both in the ./lib directory of your Rails application, they should end
up in WEB-INF/lib of your war file. Since WEB-INF/lib should be put on
the load path by the Rails initialization process, simply requiring
them as follows should suffice:

require 'rubyinterfacehandler'
require 'myjava.jar'

> [Q4] Shall I move out the java process initialization code to Tomcat web app
> context initialization area? Perhaps add a ContextListener?
> What is the general approach if I want to add webapp context init codes and
> still want to use warbler?

You can still use Warbler to bundle java classes -- see the Warbler
documentation and/or config/warble.rb for more options. Also, you can
copy Warbler's web.xml.erb to your Rails config/ directory and
customize it to add more web.xml options.

> 4) Running rails app using glassfish gem.
> [Problem] When I issue command 'glassfish', log shows followings where XXXX
> is the java interface class (implemented with ruby) that is in rails'
> lib/myjava.jar.
> This must be coming out from RubyFactory
> SEVERE: org.jruby.exceptions.RaiseException: cannot load Java class XXXX
> Oct 28, 2009 1:55:13 PM com.sun.grizzly.config.GrizzlyServiceListener
> SEVERE: java.lang.NoClassDefFoundError: XXXX
>         from java/lang/ClassLoader.java:700:in `defineClass'
>         from org/jruby/util/JRubyClassLoader.java:22:in `defineClass'
>         from org/jruby/java/MiniJava.java:576:in `defineOldStyleImplClass'
>         from org/jruby/java/MiniJava.java:194:in `createOldStyleImplClass'
>         from org/jruby/javasupport/Java.java:1570:in `new_proxy_instance2'
>         from org/jruby/java/proxies/JavaInterfaceTemplate.java:262:in
> `jcreateProxy'
>         from org/jruby/java/proxies/JavaInterfaceTemplate.java:22:in
> `access$000'
>         from org/jruby/java/proxies/JavaInterfaceTemplate.java:165:in `call'
>          ... 132 levels...
>         from
> /usr/local/jruby/lib/ruby/gems/1.8/gems/rails-2.3.4/lib/initializer.rb:113:in
> `run'
> [Q5] With glassfish, is there different way to specify classpath of rails
> app libs?  (for GrizzlyServiceListener?)
> [Q6] Again, shall I move app context init code to somewhere else in case
> with glassfish?  Is there better approach?

Try the approach above leveraging load path and see if that helps with
Glassfish too.

Cheers,
/Nick

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

    http://xircles.codehaus.org/manage_email