The Source for Java Technology Collaboration
User: Password:



Vivek Pandey's Blog

Community: Java Enterprise Archives


My first Jython web app on GlassFish v3

Posted by vivekp on March 26, 2008 at 04:17 PM | Permalink | Comments (6)

I have been thinking of playing with Jython and GlassFish for quite some time. I thought of taking the first shot at it. So after looking around a bit I found out that I can simply use PyServlet to delegate the HTTP requests to my Jython servlet which can do whatever with the Python script and write it back to the Servlet output stream. Let us see how I did it:

Setup

Create a Python Servlet

  • Create the servlet layout:

    cd c:/dev
    mkdir calendar
    cd calendar
    mkdir WEB-INF
    mkdir WEB-INF/lib
    

    Now, create Show.py, which is a Python Servlet and save it at c:/dev/calendar:

    from javax.servlet.http import HttpServlet 
    class Show (HttpServlet): 
        def doGet(self,request,response): 
            self.doPost (request,response) 
        def doPost(self,request,response): 
            toClient = response.getWriter() 
            response.setContentType ("text/html") 
            toClient.println ("<body><h1>Calendar</h1><pre>No 
    Calendar</pre></body></html>")
    
  • Create web.xml to serve all the python files by PyServlet:

    <?xml version="1.0" encoding="UTF-8"?>
    <web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
    http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
        <servlet>
            <servlet-name>PyServlet</servlet-name>
            <servlet-class>org.python.util.PyServlet</servlet-class>
            <load-on-startup>1</load-on-startup>
        </servlet>
        <servlet-mapping>
            <servlet-name>PyServlet</servlet-name>
            <url-pattern>*.py</url-pattern>
        </servlet-mapping>
        <session-config>
            <session-timeout>
                30
            </session-timeout>
        </session-config>
    </web-app>    
    
  • Copy jython.jar and python libraries to WEB-INF/lib. The Python libraries are located under Lib directory of Jython installation directory. You will also find jython.jar under the Jython installation directory.
    cd c:/tools/jython
    cp jython.jar c:/dev/calendar/WEB-INF/lib
    cp -rf Lib c:/dev/calendar/WEB-INF/lib
    

Deploy the Python web application

  • Start GlassFish v3

    gfstart-jython.png
[/c/dev]
$./glassfish/bin/asadmin deploy calendar
properties=(name=calendar)

Now access http://localhost:8080/calendar/Show.py, it should show this page:

cal1.png

This was simply a jython servlet but there was no Python specific libraries involved.

Invoke Python libraries

We will show Year 2008 calendar using python class calendar.

Let us modify Show.py.

import sys,calendar,time 
from javax.servlet.http import HttpServlet 
class Show (HttpServlet): 
    def doGet(self,request,response): 
        self.doPost (request,response) 
    def doPost(self,request,response): 
        toClient = response.getWriter() 
        response.setContentType ("text/html") 
        toClient.println 
("<body><h1>Calendar</h1><pre>%s</pre></body></html>" % 
calendar.calendar(time.localtime()[0]))

Notice that the main change made to Show.py is that we invoke calendar.calendar() and pass it the localtime. Also, there is an import of calendar and time.

Now, go back to your browser and refresh the page and you would see Year 2008 calendar:
cal2.png

This is it! However it involves Jython Servlet and some wiring and could be lot simpler. Frank plans to work on simplified and better integrated support for Jython on GlassFish. Stay tuned there is more to come...



Using JPA with Rails on GlassFish and MySQL

Posted by vivekp on March 21, 2008 at 12:56 AM | Permalink | Comments (2)

In my last post I mentioned that "...with Rails there are some known limitations, such as the ORM in Rails is not pluggable" by which I basically meant that you can't plug in another ORM and the Rails Model creation and db migration will not generate the correct code for another kind of ORM. The good news is that with little bit of coding you can reuse your entity classes. caroljmcdonald commented on my blog that Brian in his blog succssfully tried out JPA and Rails on WEBRick using JavaDB. So, in this blog I would go over what you would need to do to make JPA and Rails work on GlassFish v2.

Let's first try to understand how it is going to work: Rails by default uses ActiveRecords for Object Relational Mapping purposes or ORM. JPA is another ORM technique in JavaEE. Model class and database migration in Rails is what Entity class and persistence provider does for you in Java. Essentially In Java you just provide the Entity class and on the Rails side, you would provide the Model corresponding to the Entity class to do CRUD and that is pretty much it. The JPA provider does the rest.

This just means that to use Rails with JPA we simply do not use ActiveRecords - this means we don't create Model using Rails and we dont migrate the database. Just define your Entity class and code up the Rails Model without extending from ActiveRecord::Base.

Here is how I did it, which is basically few changes in Brian's sample and setting up GlassFish v2 with JRuby on Rails UC module.

Setup GlassFish v2 and NetBeans

  1. Install NetBeans 6.1 Beata with Web and Java EE profile.
  2. Follow these directions to install and setup JRuby on GlassFish v2.
  3. Setup JRuby jars as shared libraries on Glassfish

    cd $GLASSFISH_HOME/jruby
    $ant -f install.xml setup-shared-env
    
  4. Copy MySQL driver from your NetBeans installation:

    cp "C:\Program Files\NetBeans 6.1 Beta\ide9\modules\ext\mysql-connector-java-5.1.5-bin.jar" c:/tools/glassfish/lib
    
    or from here to $GLASSFISH_HOME/lib.
  5. Start MySQL server and create test database if not already there

    mysqladmin -u root create test;
    

Create Java Entity Beans with MySQL

First we create an entity class and a persistence unit.

  1. Create a new Java Application named Post. There's no need for a Main Class.
  2. Create a new Persistence Unit. Select jdbc:mysql://localhost:3306/test [root on Default Schema] as the database connection and the persistence unit name as PostPUclick Finish. This will generate src/META-INF/persistence.xml
  3. .
  4. Create a new Entity Class named Posts. Set the package name to entity.
  5. Add fields and accessors for title and body. Your completed class should look as follows:

    package entity;
    
    import java.io.Serializable;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    
    /**
     *
     * @author vivek
     */
    @Entity
    public class Posts implements Serializable {
        private static final long serialVersionUID = 1L;
        private Long id;
        private String title;
        private String body;
    
        public void setId(Long id) {
            this.id = id;
        }
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        public Long getId() {
            return id;
        }
    
        @Override
        public int hashCode() {
            int hash = 0;
            hash += (id != null ? id.hashCode() : 0);
            return hash;
        }
    
        @Override
        public boolean equals(Object object) {
            // TODO: Warning - this method won't work in the case the id fields are not set
            if (!(object instanceof Posts)) {
                return false;
            }
            Posts other = (Posts) object;
            if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
                return false;
            }
            return true;
        }
    
        @Override
        public String toString() {
            return "entity.Post[id=" + id + "]";
        }
        
        public String getTitle() {
            return title;
        }
    
        public void setTitle(String title) {
            this.title = title;
        }
    
        public String getBody() {
            return body;
        }
    
        public void setBody(String body) {
            this.body = body;
        }
    
    }
        
  6. Create Post.jar by clicking Build->Clean and Build Main Project or Shift+F11. This will create dist/Post.jar inside your project.
  7. Copy Post.jar to $GLASSFISH_HOME/lib directory. $GLASSFISH_HOME is where you installed GlassFish.
        cp dist/Post.jar c:/tools/glassfish/lib
        

Create the Rails Application

Simply download the Rails application then do the following:


cd $GLASSFISH_HOME/jruby/samples
unzip jpa_blog.zip
cd jpa_blog

Brian's sample Rails application was created using Rails 1.2.3 and GlassFish v2 JRuby module includes Rails version 1.2.6. So edit config/environment.rb and replace RAILS_GEM_VERSION = '1.2.3' with RAILS_GEM_VERSION = '1.2.6'.

The last thing you want to do is prepare this rails application for deployment over GlassFish v2:

[/c/tools/glassfish/jruby/samples/jpa_blog]
$ant -f ../../install.xml create-shared
Buildfile: ..\..\install.xml

create-shared:
    [mkdir] Created dir: c:\tools\glassfish\jruby\samples\jpa_blog\WEB-INF
     [copy] Copying 1 file to c:\tools\glassfish\jruby\samples\jpa_blog\WEB-INF

BUILD SUCCESSFUL
Total time: 0 seconds

Simply deploy your rails application on to GlassFish (if you have not started Glassfish during GlassFish setup, you should do it now):

[/c/tools/glassfish/jruby/samples/jpa_blog]
$cd ..
[/c/tools/glassfish/jruby/samples]
$../../bin/asadmin.bat deploy jpa_blog
Command deploy executed successfully.

In the GlassFish server.log you should see:

[#|2008-03-20T17:46:32.250-0700|INFO|sun-appserver9.1|javax.enterprise.system.to
ols.deployment|_ThreadID=20;_ThreadName=Thread-28;|deployed with moduleid = jpa_
blog|#]

[#|2008-03-20T17:46:33.531-0700|INFO|sun-appserver9.1|javax.enterprise.system.co
ntainer.web|_ThreadID=21;_ThreadName=ObjectPoolManager;|PWC1412: WebModule[/jpa_
blog] ServletContext.log():JRuby init time: 94ms|#]

[#|2008-03-20T17:46:39.296-0700|INFO|sun-appserver9.1|javax.enterprise.system.co
ntainer.web|_ThreadID=21;_ThreadName=ObjectPoolManager;|PWC1412: WebModule[/jpa_
blog] ServletContext.log():Rails init time: 5750ms|#]

[#|2008-03-20T17:46:39.296-0700|INFO|sun-appserver9.1|javax.enterprise.system.co
ntainer.web|_ThreadID=21;_ThreadName=ObjectPoolManager;|PWC1412: WebModule[/jpa_
blog] ServletContext.log():Runtime 0 loaded|#]

[#|2008-03-20T17:46:39.296-0700|INFO|sun-appserver9.1|javax.enterprise.system.co
ntainer.web|_ThreadID=21;_ThreadName=ObjectPoolManager;|PWC1412: WebModule[/jpa_
blog] ServletContext.log():Requests can now be processed|#]

Now, accessing http://localhost:8080/jpa_blog/blog/ should show you:

index.PNG

Create a new Blog entry:

new.png

See the list of all the blogs:

list.PNG

I wanted to try it out on Glassfish gem but JPA is under development in GlassFish v3 and I get exception coming form inside GlassFish v3 where it can't find the PersistenceProvider:

javax.persistence.PersistenceException: No resource files named META-INF/services/javax.persistence.spi.PersistenceProvider were found. Please make sure that the persistence provider jar file is in your classpath.

Mitesh is working on JPA support in Glassfish v3, I would do a follow-up blog for GlassFish gem as soon as I see it working.

You can get the Rails and Entity code using the following link:

Continue using JRuby on GlassFish and keep sending us feedback on GlassFish forums, dev@glassfish or gem mailing list. For the latest information about the gem and JRuby Update Center module can be found at GlassFish JRuby wiki.

Report on JRuby On Glassfish@Silicon Valley JUG

Posted by vivekp on March 19, 2008 at 11:22 AM | Permalink | Comments (2)

I was at Silicon Valley JUG (Java User's Group) to talk about Ruby on Rails in GlassFish. See Arun's announcement on this talk. The slides used in this presentation can be found here.

The main theme of my presentation was on highlighting Rails development and deployment on GlassFish v2 and using GlassFish gem with live demos.

These are some of the questions asked during presentation and my answer to those

Q:This is cool that Rails applications can be deployed and run over GlassFish a JavaEE application server, but can the JavaEE features be invoked from inside a Rails application?

A:Yes we think it can be done, with JRuby you can call anything in Java. We know from one of the JRuby users that he is able to call in to EJB service form Rails. Having said that with Rails there are some known limitations, such as the ORM in Rails is not pluggable, so we can't plugin GlassFish JPA implementation in to Rails to take benefit of it. Merb allows such pluggable ORM. As a followup we would provide samples/blogs on Rails and JavaEE features.

Q:What is the performance comparison between JRuby vs Ruby?

Q:No formal performance study has been done. There are some blog posts that talk about it, such as this one by Nick, that shows with warm up JRuby/GlassFish as good as C-Ruby/Mogreal and there is another JRuby on GlassFish comparison to Ruby/Mogrel. We expect with GlassFish gem these numbers would look even better. In next few months the focus is going to be on performance and scalability, so stay tuned.

Q:Can you call in to Ruby from Java?

A:Yes, you can do it using JSR-223 APIs. JSR-223 scripting APIs are part of JDK6, with JDK 5 or earlier versions, you can get it from here.

Q:Does standalone JRuby programs can also get affect from PermGen issue?

A:It really depends on the application. For example, in a Rails application, because Rails being single threaded and so it results in to creating Rails for each of the concurrent requests and hence each Rails instance ends up consuming more of Permanent heap space.

There were more questions that I can't recall now. The talk was video recorded, I am not sure where and when it will be posted but when I get that link, I will add it to this blog.

Please use JRuby on GlassFish and send us feedback on GlassFish forums, dev@glassfish or gem mailing list. For the latest information about the gem and JRuby Update Center module can be found at GlassFish JRuby wiki.



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