The Source for Java Technology Collaboration
User: Password:



Arun Gupta

Arun Gupta's Blog

TOTD #9: Using JDBC connection pool/JNDI name from GlassFish in Rails Application

Posted by arungupta on September 12, 2007 at 06:50 AM | Comments (6)

Using the instructions followed in JRuby Hack Day and taking some help from Nick, I figured out how to use the JDBC connection pools configured in GlassFish using the JNDI names.

All the commands given below are relevant for GlassFish but the same concept will work where ever you deploy your WARed up JRuby on Rails application.

  1. Follow the bullet #1 and #2 from here to create a new application and database with the following exceptions:
    1. Use the name "jndi_rails" instead of "RailsApplication9" for the Project Name.
    2. Make sure to select "Access database using JDBC" in bullet # 2.2. This will bundle ActionRecord-JDBC plugin in your application.
  2. Create database using bullet # 3 from here. Use the following command instead to create the database instead:

    mysqladmin -u root create jndi_rails_production
  3. Create Model and Controller as described in bullet #4 here.
  4. Configure Model and Controller
    1. Configure Model
      1. In the NetBeans IDE, expand "Database Configurations", "migrate" and open "001_create_greetings.rb". Change the "self.up" helper method such that it looks like:

        def self.up
          create_table :greetings do |t|
            t.column :data, :string
          end
        end
      2. Expand "Configuration", open "database.yml", change the database name for development configuration from "jndi_rails_development" to "jndi_rails_production".
      3. Right-select the project, select 'Run Rake Target', 'db', 'migrate'. This generates the appropriate database tables and the following is shown in the output window:

        (in C:/Users/Arun Gupta/Documents/NetBeansProjects/jndi_rails)
        == CreateGreetings: migrating =================================================
        -- create_table(:greetings)
        -> 0.2650s
        == CreateGreetings: migrated (0.2650s) ========================================
      4. Add data to the database tables and give appropriate privileges using the following commands in a shell window:

        C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -u root
        Welcome to the MySQL monitor. Commands end with ; or \g.
        Your MySQL connection id is 14
        Server version: 5.0.45-community-nt MySQL Community Edition (GPL)

        Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

        mysql> use jndi_rails_production;
        Database changed
        mysql> insert into greetings values (1, "Hello from MySQL JNDI pool!");
        Query OK, 1 row affected (0.03 sec)

        mysql> grant all on jndi_rails_production.* to arun@localhost identified by 'noway';
        Query OK, 0 rows affected (0.26 sec)

        mysql> flush privileges;
        Query OK, 0 rows affected (0.16 sec)

        mysql> quit;
        Bye
      5. Change the production database environment from:

        production:
          adapter: mysql
          database: jndi_rails_production
          username: root
          password:
          host: localhost


        to

        production:
          adapter: jdbc
          jndi: jdbc/jndi_rails
          driver: com.mysql.jdbc.Driver

        Notice only JDBC adpater and JNDI name is specified in the database configuration. This ensures that the database is resolved using only the JNDI name. Although "database", "username" and "password" attributes may be specified in addition to "jndi" and "driver" attributes. In this case, the Rails configuration falls back to pure-Ruby MySQL adapter.
    2. Configure Controller using bullet # 5.2 from here.
  5. Create the JDBC connection pool and resource
    1. In GLASSFISH_HOME\bin, create the JDBC connection pool by giving the following command:

      asadmin create-jdbc-connection-pool --datasourceclassname com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource --restype javax.sql.DataSource --property User=arun:Password=noway:URL=jdbc\:mysql\://localhost/jndi_rails_production jdbc/jndi_rails_pool

      The following output should be seen on the console:

      Command create-jdbc-connection-pool executed successfully.
    2. Create the JDBC resource by giving the following command:

      asadmin create-jdbc-resource --connectionpoolid jdbc/jndi_rails_pool jdbc/jndi_rails

      The following output should be seen on the console:

      Command create-jdbc-resource executed successfully.
  6. Create a WAR file as described in bullet #6 here
  7. Download, Install and Start GlassFish as described in bullet #7 here.
  8. Download and Install MySQL/J Connector in a new directory. Copy the JAR file from the main installation directory to 'GLASSFISH_HOME/lib' directory.
  9. Copy the WAR file (jndi_rails.war) in "domains/domain/autodeploy" directory.

The application is accessible at "http://localhost:8080/jndi_rails/say/hello".

An alternative approach to use the connection pools is discussed here. Lou also nicely describes the benefits of connection pooling.

Please leave suggestions on other TOTD that you'd like to see. A complete archive is available here.

Technorati: totd rubyonrails jruby netbeans glassfish connectionpooling jndi jdbc jrubyonglassfish


Bookmark blog post: del.icio.us del.icio.us Digg Digg DZone DZone Furl Furl Reddit Reddit
Comments
Comments are listed in date ascending order (oldest first) | Post Comment

  • Your blog is very informative and usefull.

    I have followed your instructions on all the different ways to connect to a database from rails in glassfish. Today i tried the JNDI method, but no luck. I get the same error no matter what method i choose. I am using an oracle database. (i have the right JDBC driver).

    Failed to load Rails: java.lang.NumberFormatException: For input string: "?"

    PWC1412: WebModule[/PDFCollater] ServletContext.log():rails: Ruby is running in standalone mode
    PWC1412: WebModule[/PDFCollater] ServletContext.log():JRuby init time: 5499ms
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/actionmailer-1.3.3/lib/action_mailer.rb:49 warning: already initialized constant MAX_LINE_LEN
    PWC1412: WebModule[/PDFCollater] ServletContext.log():Failed to load Rails: java.lang.NumberFormatException: For input string: "?"
    NumberFormatException.java:48:in `java.lang.NumberFormatException.forInputString'
    Integer.java:447:in `java.lang.Integer.parseInt'
    RubyYaccLexer.java:1411:in `org.jruby.lexer.yacc.RubyYaccLexer.yylex'
    RubyYaccLexer.java:123:in `org.jruby.lexer.yacc.RubyYaccLexer.advance'
    DefaultRubyParser.java:883:in `org.jruby.parser.DefaultRubyParser.yyparse'
    DefaultRubyParser.java:835:in `org.jruby.parser.DefaultRubyParser.yyparse'
    DefaultRubyParser.java:3299:in `org.jruby.parser.DefaultRubyParser.parse'
    Parser.java:78:in `org.jruby.parser.Parser.parse'
    Parser.java:56:in `org.jruby.parser.Parser.parse'
    Ruby.java:1024:in `org.jruby.Ruby.parse'
    RubyObject.java:885:in `org.jruby.RubyObject.evalWithBinding'
    RubyKernel.java:755:in `org.jruby.RubyKernel.eval'
    null:-1:in `org.jruby.RubyKernelInvokerSevalxx1.call'
    InvocationCallback.java:49:in `org.jruby.runtime.callback.InvocationCallback.execute'
    FullFunctionCallbackMethod.java:78:in `org.jruby.internal.runtime.methods.FullFunctionCallbackMethod.internalCall'
    DynamicMethod.java:79:in `org.jruby.internal.runtime.methods.DynamicMethod.call'
    EvaluationState.java:1023:in `org.jruby.evaluator.EvaluationState.fCallNode'
    EvaluationState.java:253:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:164:in `org.jruby.evaluator.EvaluationState.eval'
    Block.java:220:in `org.jruby.runtime.Block.yield'
    EvaluationState.java:1828:in `org.jruby.evaluator.EvaluationState.yieldNode'
    EvaluationState.java:391:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:531:in `org.jruby.evaluator.EvaluationState.blockNode'
    EvaluationState.java:201:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:984:in `org.jruby.evaluator.EvaluationState.ensureNode'
    EvaluationState.java:247:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:164:in `org.jruby.evaluator.EvaluationState.eval'
    DefaultMethod.java:135:in `org.jruby.internal.runtime.methods.DefaultMethod.internalCall'
    DynamicMethod.java:79:in `org.jruby.internal.runtime.methods.DynamicMethod.call'
    RubyObject.java:564:in `org.jruby.RubyObject.callMethod'
    EvaluationState.java:1030:in `org.jruby.evaluator.EvaluationState.fCallNode'
    EvaluationState.java:253:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:531:in `org.jruby.evaluator.EvaluationState.blockNode'
    EvaluationState.java:201:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:164:in `org.jruby.evaluator.EvaluationState.eval'
    DefaultMethod.java:135:in `org.jruby.internal.runtime.methods.DefaultMethod.internalCall'
    DynamicMethod.java:79:in `org.jruby.internal.runtime.methods.DynamicMethod.call'
    EvaluationState.java:1023:in `org.jruby.evaluator.EvaluationState.fCallNode'
    EvaluationState.java:253:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:164:in `org.jruby.evaluator.EvaluationState.eval'
    Block.java:220:in `org.jruby.runtime.Block.yield'
    Block.java:186:in `org.jruby.runtime.Block.yield'
    RubyArray.java:1278:in `org.jruby.RubyArray.each'
    null:-1:in `org.jruby.RubyArrayInvokereach0.call'
    InvocationCallback.java:49:in `org.jruby.runtime.callback.InvocationCallback.execute'
    FullFunctionCallbackMethod.java:78:in `org.jruby.internal.runtime.methods.FullFunctionCallbackMethod.internalCall'
    DynamicMethod.java:79:in `org.jruby.internal.runtime.methods.DynamicMethod.call'
    EvaluationState.java:581:in `org.jruby.evaluator.EvaluationState.callNode'
    EvaluationState.java:207:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:531:in `org.jruby.evaluator.EvaluationState.blockNode'
    EvaluationState.java:201:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:164:in `org.jruby.evaluator.EvaluationState.eval'
    DefaultMethod.java:135:in `org.jruby.internal.runtime.methods.DefaultMethod.internalCall'
    DynamicMethod.java:79:in `org.jruby.internal.runtime.methods.DynamicMethod.call'
    EvaluationState.java:1756:in `org.jruby.evaluator.EvaluationState.vcallNode'
    EvaluationState.java:382:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:531:in `org.jruby.evaluator.EvaluationState.blockNode'
    EvaluationState.java:201:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:164:in `org.jruby.evaluator.EvaluationState.eval'
    DefaultMethod.java:135:in `org.jruby.internal.runtime.methods.DefaultMethod.internalCall'
    DynamicMethod.java:79:in `org.jruby.internal.runtime.methods.DynamicMethod.call'
    RubyObject.java:564:in `org.jruby.RubyObject.callMethod'
    RubyObject.java:462:in `org.jruby.RubyObject.callMethod'
    RubyObject.java:1385:in `org.jruby.RubyObject.send'
    null:-1:in `org.jruby.RubyObjectInvokersendxx1.call'
    InvocationCallback.java:49:in `org.jruby.runtime.callback.InvocationCallback.execute'
    FullFunctionCallbackMethod.java:78:in `org.jruby.internal.runtime.methods.FullFunctionCallbackMethod.internalCall'
    DynamicMethod.java:79:in `org.jruby.internal.runtime.methods.DynamicMethod.call'
    EvaluationState.java:568:in `org.jruby.evaluator.EvaluationState.callNode'
    EvaluationState.java:207:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:531:in `org.jruby.evaluator.EvaluationState.blockNode'
    EvaluationState.java:201:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:164:in `org.jruby.evaluator.EvaluationState.eval'
    DefaultMethod.java:135:in `org.jruby.internal.runtime.methods.DefaultMethod.internalCall'
    DynamicMethod.java:79:in `org.jruby.internal.runtime.methods.DynamicMethod.call'
    EvaluationState.java:581:in `org.jruby.evaluator.EvaluationState.callNode'
    EvaluationState.java:207:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:531:in `org.jruby.evaluator.EvaluationState.blockNode'
    EvaluationState.java:201:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:1609:in `org.jruby.evaluator.EvaluationState.rootNode'
    EvaluationState.java:356:in `org.jruby.evaluator.EvaluationState.evalInternal'
    EvaluationState.java:164:in `org.jruby.evaluator.EvaluationState.eval'
    Ruby.java:1185:in `org.jruby.Ruby.loadScript'
    ExternalScript.java:53:in `org.jruby.runtime.load.ExternalScript.load'
    LoadService.java:307:in `org.jruby.runtime.load.LoadService.smartLoad'
    LoadService.java:333:in `org.jruby.runtime.load.LoadService.require'
    RailsFactory.java:177:in `org.jruby.webapp.RailsFactory.require'
    RailsFactory.java:117:in `org.jruby.webapp.RailsFactory.makeObject'
    GenericObjectPool.java:840:in `org.apache.commons.pool.impl.GenericObjectPool.borrowObject'
    AbstractRailsServlet.java:144:in `org.jruby.webapp.AbstractRailsServlet.serviceRequest'
    AbstractRailsServlet.java:131:in `org.jruby.webapp.AbstractRailsServlet.service'
    HttpServlet.java:831:in `javax.servlet.http.HttpServlet.service'
    ApplicationFilterChain.java:411:in `org.apache.catalina.core.ApplicationFilterChain.servletService'
    ApplicationDispatcher.java:855:in `org.apache.catalina.core.ApplicationDispatcher.doInvoke'
    ApplicationDispatcher.java:703:in `org.apache.catalina.core.ApplicationDispatcher.invoke'
    ApplicationDispatcher.java:542:in `org.apache.catalina.core.ApplicationDispatcher.processRequest'
    ApplicationDispatcher.java:440:in `org.apache.catalina.core.ApplicationDispatcher.doForward'
    ApplicationDispatcher.java:366:in `org.apache.catalina.core.ApplicationDispatcher.forward'
    FileServlet.java:102:in `org.jruby.webapp.FileServlet.doGet'
    HttpServlet.java:718:in `javax.servlet.http.HttpServlet.service'
    HttpServlet.java:831:in `javax.servlet.http.HttpServlet.service'
    ApplicationFilterChain.java:411:in `org.apache.catalina.core.ApplicationFilterChain.servletService'
    ApplicationFilterChain.java:317:in `org.apache.catalina.core.ApplicationFilterChain.internalDoFilter'
    ApplicationFilterChain.java:198:in `org.apache.catalina.core.ApplicationFilterChain.doFilter'
    MonitorFilter.java:368:in `org.netbeans.modules.web.monitor.server.MonitorFilter.doFilter'
    ApplicationFilterChain.java:230:in `org.apache.catalina.core.ApplicationFilterChain.internalDoFilter'
    ApplicationFilterChain.java:198:in `org.apache.catalina.core.ApplicationFilterChain.doFilter'
    StandardWrapperValve.java:288:in `org.apache.catalina.core.StandardWrapperValve.invoke'
    StandardContextValve.java:271:in `org.apache.catalina.core.StandardContextValve.invokeInternal'
    StandardContextValve.java:202:in `org.apache.catalina.core.StandardContextValve.invoke'
    StandardPipeline.java:632:in `org.apache.catalina.core.StandardPipeline.doInvoke'
    StandardPipeline.java:577:in `org.apache.catalina.core.StandardPipeline.doInvoke'
    WebPipeline.java:94:in `com.sun.enterprise.web.WebPipeline.invoke'
    StandardHostValve.java:206:in `org.apache.catalina.core.StandardHostValve.invoke'
    StandardPipeline.java:632:in `org.apache.catalina.core.StandardPipeline.doInvoke'
    StandardPipeline.java:577:in `org.apache.catalina.core.StandardPipeline.doInvoke'
    StandardPipeline.java:571:in `org.apache.catalina.core.StandardPipeline.invoke'
    ContainerBase.java:1080:in `org.apache.catalina.core.ContainerBase.invoke'
    StandardEngineValve.java:150:in `org.apache.catalina.core.StandardEngineValve.invoke'
    StandardPipeline.java:632:in `org.apache.catalina.core.StandardPipeline.doInvoke'
    StandardPipeline.java:577:in `org.apache.catalina.core.StandardPipeline.doInvoke'
    StandardPipeline.java:571:in `org.apache.catalina.core.StandardPipeline.invoke'
    ContainerBase.java:1080:in `org.apache.catalina.core.ContainerBase.invoke'
    CoyoteAdapter.java:270:in `org.apache.coyote.tomcat5.CoyoteAdapter.service'
    DefaultProcessorTask.java:637:in `com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.invokeAdapter'
    DefaultProcessorTask.java:568:in `com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.doProcess'
    DefaultProcessorTask.java:813:in `com.sun.enterprise.web.connector.grizzly.DefaultProcessorTask.process'
    DefaultReadTask.java:339:in `com.sun.enterprise.web.connector.grizzly.DefaultReadTask.executeProcessorTask'
    DefaultReadTask.java:261:in `com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask'
    DefaultReadTask.java:212:in `com.sun.enterprise.web.connector.grizzly.DefaultReadTask.doTask'
    PortUnificationPipeline.java:361:in `com.sun.enterprise.web.portunif.PortUnificationPipeline$PUTask.doTask'
    TaskBase.java:265:in `com.sun.enterprise.web.connector.grizzly.TaskBase.run'
    SSLWorkerThread.java:106:in `com.sun.enterprise.web.connector.grizzly.ssl.SSLWorkerThread.run'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/rails-1.2.3/lib/initializer.rb:400:in `load_plugin'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/rails-1.2.3/lib/initializer.rb:184:in `silence_warnings'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/rails-1.2.3/lib/initializer.rb:402:in `load_plugin'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/rails-1.2.3/lib/initializer.rb:184:in `load_plugins'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/rails-1.2.3/lib/initializer.rb:106:in `each'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/rails-1.2.3/lib/initializer.rb:185:in `load_plugins'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/rails-1.2.3/lib/initializer.rb:106:in `process'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/rails-1.2.3/lib/initializer.rb:43:in `send'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/WEB-INF/gems/gems/rails-1.2.3/lib/initializer.rb:43:in `run'
    /usr/local/glassfish-v2-b58f/domains/domain1/applications/j2ee-modules/PDFCollater/config/environment.rb:54
    :0

    Do you have any idea what is wrong?

    Posted by: evilgeenius on September 12, 2007 at 10:38 AM

  • I've not tried Oracle database but will follow up and let you know what I find. Can you try MySQL (it's freely available) and see if that helps ?

    Posted by: arungupta on September 12, 2007 at 11:03 AM

  • MySQL does work but my company uses Oracle so that's what I need. I have quite a few applications that i'd like to deploy on our java server. Thanks, Chris

    Posted by: evilgeenius on September 13, 2007 at 02:06 AM

  • I have a post that explains how to successfully connect to Oracle with JRuby: Connecting to Oracle From Rails

    This works in a container-agnostic way.

    Posted by: digitalsanctum on September 13, 2007 at 09:32 AM

  • This is very cool! I suspected something similar :)

    Posted by: arungupta on September 13, 2007 at 11:12 AM

  • evilgeenius, I posted the issue you are facing at: http://archive.jruby.codehaus.org/user/21ef583e0709130655m67907f99k9cf92e6be5bc9185%40mail.gmail.com. Can you please respond on that alias ?

    Posted by: arungupta on September 13, 2007 at 11:14 AM



Only logged in users may post comments. Login Here.


Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds