Arun Gupta, Miles to go ...

Arun Gupta is a technology enthusiast, a passionate runner, and a community guy who works for Sun Microsystems.
« Previous month (Jul 2007) | Main | Next page of month (Aug 2007) »

http://blogs.sun.com/arungupta/date/20070831 Friday August 31, 2007

San Francisco Marathon 07 Finishers Certificate

Read all about my race participation here.

Technorati: running runsfm

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070830 Thursday August 30, 2007

First time - Blog at top rank

Oh gosh, this is exciting!

Thanks Eduardo for the tip!

Technorati: blogs rank bsc hotblog

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

TOTD #5: Loading data from beans in jMaki widgets

The jMaki tutorial from SWDP explained the different approaches to load your own data into a jMaki widget. The jMaki widget models have formalized since then and so the code there no longer works. This TOTD explains how a combo box widget in a JSP page gets it data from a bean.

This TOTD uses NetBeans IDE configured with jMaki plugin and GlassFish.

  1. Create a new Web application project using NetBeans IDE, enable "jMaki Framework" and use all the defaults. Choose GlassFish as the "Server".
  2. In the default generated "index.jsp" page, drag-and-drop "Dojo Combobox" in the "Main Content Area".
  3. Replace the generated code with the following fragment

    <jsp:useBean id="itemBean" scope="session" class="server.ItemValueBean" />
    <a:widget name="dojo.combobox" value="${itemBean.value}"/>

    jsp:useBean tag instantiates the bean "server.ItemValueBean" in session scope. a:widget tag uses ${itemBean.value} expression to load the data by invoking getValue() method from the bean.
  4. Add a new class to the project and name it "ItemValueBean" in the package "server". Replace the entire generated code with the following:

    package server;

    import org.json.JSONArray;
    import org.json.JSONException;
    import org.json.JSONObject;

    public class ItemValueBean {
      public String getValue() {
        JSONArray value = new JSONArray();
        for (int i=0; i<2; i++) {
          try {
            JSONObject item = new JSONObject();
            item.put("name", "name" + i);
            item.put("label", "label" + i);
            value.put(item);
          } catch (JSONException ex) {
            ex.printStackTrace();
          }
        }

        try {
          return jsonArrayToString(value, null);
        } catch (JSONException ex) {
          ex.printStackTrace();
        }

        return null;
      }

      /**
      * Converts a JSON Object to an Object Literal
      *
      */
      public String jsonToObjectLibertal(JSONObject jo, StringBuffer buff) throws JSONException {
        if (buff == null)
          buff = new StringBuffer("{");
        else
          buff.append("{");
        JSONArray names = jo.names();
        for (int l=0; (names != null) && l < names.length(); l++) {
          String key = names.getString(l);
          String value = null;
          if (jo.optJSONObject(key) != null) {
            value = key + ":";
            buff.append(value);
            jsonToObjectLibertal(jo.optJSONObject(key), buff);
          } else if (jo.optJSONArray(key) != null) {
            value = key + ":";
            buff.append(value);
            jsonArrayToString(jo.optJSONArray(key), buff);
          } else if (jo.optLong(key, -1) != -1) {
            value = key + ":" + jo.get(key) + "";
            buff.append(value);
          } else if (jo.optDouble(key, -1) != -1) {
            value = key + ":" + jo.get(key) + "";
            buff.append(value);
          } else if (jo.opt(key) != null) {
            Object obj = jo.opt(key);
            if (obj instanceof Boolean) {
              value = key + ":" + jo.getBoolean(key) + "";
            } else {
              value = key + ":" + "'" + jo.get(key) + "'";
            }
            buff.append(value);
          }
          if (l < names.length() -1) buff.append(",");
        }
        buff.append("}");
        return buff.toString();
      }
     
      public String jsonArrayToString(JSONArray ja, StringBuffer buff) throws JSONException {
        if (buff == null)
          buff = new StringBuffer("[");
        else
          buff.append("[");

        for (int key=0; (ja != null) && key < ja.length(); key++) {
          String value = null;
          if (ja.optJSONObject(key) != null){
            jsonToObjectLibertal(ja.optJSONObject(key), buff);
          } else if (ja.optJSONArray(key) != null) {
            jsonArrayToString(ja.optJSONArray(key), buff);
          } else if (ja.optLong(key, -1) != -1) {
            value = ja.get(key) + "";
            buff.append(value);
          } else if (ja.optDouble(key, -1) != -1) {
            value = ja.get(key) + "";
            buff.append(value);
          } else if (ja.optBoolean(key)) {
            value = ja.getBoolean(key) + "";
            buff.append(value);
          } else if (ja.opt(key) != null) {
            Object obj = ja.opt(key);
            if (obj instanceof Boolean) {
              value = ja.getBoolean(key) + "";
            } else {
              value = "'" + ja.get(key) + "'";
            }
            buff.append(value);
          }
          if (key < ja.length() -1) buff.append(",");
        }
        buff.append("]");
        return buff.toString();
      }
    }

    The getValue methods contains the logic to generate the business data. In this case, the method generates the data model expected by ComboBox using JSON APIs. This data can very well be generated by creating a Persistence Unit and querying a database using JPA or any other mechanism.

    The jsonToObjectLibertal and jsonArrayToString methods were originally posted here. These two methods are required because the JSON parser does not allow you to create object literals but only JSON objects. By default these contain key : value pairs where the keys are enclosed in double quotes which does not match with the expected data model.

  5. Deploy and Run the application. The browser windows shows the default page with a drop-down list box. The expanded list box shows the items that are added to the combo box.


     

Another way to populate jMaki widgets with your data (using JPA) is explained here.

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

Technorati: totd jmaki beans glassfish netbeans

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070829 Wednesday August 29, 2007

Excel using WSIT - Metro and .NET interoperability sample

If you attended JavaOne 2007 or any other conference afterwards where Metro (JAX-WS + WSIT/Tango) team presented, then you've probably seen this demo. The demo shows an Excel 2007 spreadsheet invoking a Secure and Reliable endpoint deployed on GlassFish. Today, I'm announcing the availability of the WSIT endpoint and Excel client code with full instructions to build, deploy and run the sample.

Metro Release Candidate 1 was announced recently and is integrated in GlassFish RC4. You can learn more about .NET interoperability aspects of Metro by watching this deep dive interview or reading this 26-page article.

The source code for this sample is available in "wsit/wsit/samples/excelclient" directory. It can be checked out using the command:

cvs -d :pserver:yourid@cvs.dev.java.net:/cvs co wsit/wsit/samples/excelclient

A compressed bundle of the sample is available here.

Running the demo involves an extensive setup for .NET client. Please make sure to review the software requirements before proceeding with the installation.

Try it and send us feedback at users@metro or Metro Forum.

Technorati: webservices metro glassfish dotnet .net interoperability netbeans wcf

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070828 Tuesday August 28, 2007

Dynamic Data in jMaki Widgets Using JPA - Updated for formal data models

Doris pointed out that one of my earlier post is not working any more. That entry explained the steps to create a Web application, deployed on GlassFish V2, and contained a jMaki-wrapped Yahoo Data Table widget pulling data from JavaDB using the JPA.

The main reason for this is because jMaki data models have evolved since I wrote the original entry and are now formalized. Here is the delta from the previous entry to make it working:

  1. Use the following code in bullet 6 instead:

    <%@ page import="java.util.*" %>
    <%@ page import="server.Company" %>
    <%@ page import="javax.persistence.*" %>

    <%
      EntityManagerFactory emf = Persistence.createEntityManagerFactory("jmaki-jpaPU");
      EntityManager em = emf.createEntityManager();

      List<Company> list = em.createQuery("select c from Company c").getResultList();

      out.println("{columns : [" +
        "{ label : 'Company Name', id : 'companyName'}," +
        "{ label :'Price', id : 'price'}," +
        "{ label :'Change', id : 'change'}," +
        "{ label :'% Change', id : 'pctChange'}," +
        "{ label :'Last Updated', id : 'lastUpdated'}" +
        "],");

      out.println("rows: [");
      for (int i=0; i<list.size(); i++) {
        Company c = list.get(i);
        out.print("{ companyName: '" + c.getCompanyname() + "'," +
          "price: '" + c.getPrice() + "'," +
          "change: '" + c.getChange() + "'," +
          "pctChange: '" + c.getPercentchange() + "'," +
          "lastUpdated: '" + c.getLastupdated() + "'}");
          if (i < list.size()-1)
            out.println(",");
          else
            out.println();
      }
      out.println("] }");
    %>
  2. The new generated code fragment in bullet 7.2 is now:

     <a:widget name="yahoo.dataTable"
      service="data.jsp" />

With jMaki 0.9.7.1, here is a snapshot of the updated web page:

And the updated NetBeans project is available here.

Technorati: jmaki glassfish jpa netbeans

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070827 Monday August 27, 2007

ActiveRecord-JDBC 0.5 - simplified database configuration

ActiveRecord-JDBC 0.5 is now available. As mentioned earlier, one of the main features in this release is simplified database configuration for JRuby-on-Rails applications. From the release notes:

It is no longer necessary to specify :driver and :url configuration parameters for the mysql,  postgresql, oracle, derby, hsqldb, and h2 adapters.

This means that if you deploy a Rails application as a WAR file on GlassFish as described here, then there is no need to specify the JDBC adapter, the JDBC driver class name or the database connection URL. The ActiveRecord-JDBC uses the native MySQL adapter to connect directly to the database. And so there is no need to even copy MySQL Connector/J driver JAR file in GlassFish\lib directory.

This means the database configuration

production:
  adapter: jdbc
  driver: com.mysql.jdbc.Driver
  url: jdbc:mysql://localhost:3306/helloworld_development
  username: root
  password:

can now be written as

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

And this is the default configuration generated by Rails app anyway.

This really simplifies the database configuration for deploying Rails applications on GlassFish. As a result the steps described here (bullet 2 & 3),  here (bullet 4.2.1 & 4.2.2) and in screencast #web6 (10:52 - 11:56) are not required any more.

I'd like to point out that it's not necessary to specify this information. But if you have any applications deployed with these settings, they'll continue to work. Installing the plugin using the standard way (jruby script\plugin install activerecord-jdbc) will give you the latest version anyway.

I'm particularly excited about this change as it brings C-based Ruby and JRuby applications one step closer to each other.

Tom explained other simplifications.

Technorati: rubyonrails jrubyonglassfish jruby ruby glassfish mysql

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070824 Friday August 24, 2007

jMaki, PHP and GlassFish - again using Caucho Quercus

jMaki is a light-weight framework for build Web 2.0 applications. It provides support for multiple languages - Java (1, 2, 3, 4, 5, 6) , PHP, Ruby (1, 2), Phobos (1). The numbers in parentheses indicate the entries that I've created showing jMaki support for that language. As evident, I've not created a single entry for PHP yet. This entry is going to change that :)

This entry shows how to deploy a jMaki-enabled PHP web application in GlassFish. It builds upon an earlier entry that showed how to deploy a simple PHP application in GlassFish.

  1. PHP-enable GlassFish and verify it's working correctly following these steps.
  2. Build, Install and Run a simple jMaki/PHP sample
    1. Download and Unzip the contents of jMaki/PHP release (0.9.7.2 as of this writing). This creates "jmaki-php-0.9.7.2\jmaki-php" in the current directory.
    2. Go to "jmaki-php-0.9.7.2\jmaki-php\core" and invoke "ant". This creates "dist\jmaki-core.zip".
    3. Unzip the contents of "jmaki-core.zip" under the "web" directory of the project created in the link followed from first step.
    4. Redeploy your project and your first jMaki widget in a PHP page deployed on GlassFish is now available at "http://localhost:8080/hellophp/jmaki-core/index.php".

      If you look at "index.php" in the IDE, the page contains the following code fragments:

      <?php addWidget("hello"); ?>

      <?php addWidget( array( "name" => "hello2",
                              "args" => "{name: 'Duke'}")
      ); ?>


      If you look at the source code of the generated page, the PHP code is converted to JavaScript code as shown below:

      <link type='text/css' rel='stylesheet' href='http://localhost:8080:8080/hellophp/jmaki-core/resources/hello/component.css'></link>
      <script type='text/javascript' src='http://localhost:8080:8080/hellophp/jmaki-core/resources/hello/component.js'></script>
      <script type='text/javascript'>
        jmaki.addWidget({uuid:"hello_2",
                         name:"hello",
                         widgetDir:"http://localhost:8080:8080/hellophp/jmaki/resources/hello",
                         script:"http://localhost:8080:8080/hellophp/jmaki/resources/hello/component.js"});
      </script>

      and

      <link type='text/css' rel='stylesheet' href='http://localhost:8080:8080/hellophp/jmaki-core/resources/hello2/component.css'></link>
      <script type='text/javascript' src='http://localhost:8080:8080/hellophp/jmaki-core/resources/hello2/component.js'></script>
        <div id="hello2_3" class="hello2"></div>
        <script type='text/javascript'>
        jmaki.addWidget({uuid:"hello2_3",
                         name:"hello2",
                         widgetDir:"http://localhost:8080:8080/hellophp/jmaki-core/resources/hello2",
                         args: {name: 'Duke'},
                         script:"http://localhost:8080:8080/hellophp/jmaki-core/resources/hello2/component.js"});
      </script>


      Notice the JavaScript code shows the host + port as "localhost:8080:8080". This issue is followed here.
  3. Build, Install and Run a slightly advanced sample.
    1. Go to "jmaki-php-0.9.7.2\jmaki-php\samples\loadtable" and invoke "ant". This creates "dist\jmaki-loadtable-php-0.9.7.2.zip".
    2. Unzip the contents of this zip file under the "web" directory of your project.
    3. Redeploy you project and the sample is now deployed at "http://localhost:8080/hellophp/web/jmaki-loadtable/index.php".

      This sample shows a Dojo DataTable loading static data. The code fragment to add the widget to the page is:

      <?php
        addWidget('dojo.table', null, null, null, "tabledata.json");
      ?>


      You can look at the generated source using "View Source". A nice twist to try is to dynamically load the data from a database using JPA as shown here.

None of the samples that use XMLHttpProxy (rssData, cl-mashup and mapit) will work because I could not find XSLT extension for Quercus. This issue is followed here. Other users have asked similar question with no clear answer.

Technorati: jmaki php glassfish web2.0 caucho quercus

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070823 Thursday August 23, 2007

PHP in GlassFish using Caucho Quercus

Quercus is Caucho Technology's 100% Java implementation of PHP 5. Ludo described the steps to deploy PHP web applications on GlassFish. Caucho has released a new version of Quercus since then. This blog entry is an update to the steps described earlier.

  1. First, PHP-enable GlassFish.
    1. Unjar quercus-3.1.1.war and copy the JAR files in "WEB-INF/lib" directory to "GLASSFISH_HOME/domains/domain/lib" directory. That's it! Although the original entry requires to copy the JARs in "GLASSFISH_HOME/lib/addons" directory but that didn't work.
  2. Create a PHP web application
    1. Create a new Web application project, lets say "hellophp", using NetBeans IDE and choose GlassFish as the server.
    2. Replace the contents of "web.xml" with the following fragment:

      <?xml version="1.0" encoding="UTF-8"?>
      <web-app 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"
        version="2.5">
        <description>Caucho Technology's PHP Implementation, Running on GlassFish Java EE 5</description>
        <servlet>
          <servlet-name>Quercus Servlet</servlet-name>
          <servlet-class>com.caucho.quercus.servlet.QuercusServlet</servlet-class>
        </servlet>
        <servlet-mapping>
          <servlet-name>Quercus Servlet</servlet-name>
          <url-pattern>*.php</url-pattern>
        </servlet-mapping>
        <welcome-file-list>
          <welcome-file>index.php</welcome-file>
        </welcome-file-list>
      </web-app>


      This will declare PHP engine as the servlet.
    3. Add a new page "index.php" in "Web pages" folder. The contents of the page are:

      <?php
      echo "Hello World!";
      phpinfo();
      ?>

      This page prints "Hello World!" on the browser and some configuration settings of PHP. The directory structure of the created project looks like:

      META-INF/
      META-INF/MANIFEST.MF
      WEB-INF/
      WEB-INF/classes/
      WEB-INF/sun-web.xml
      WEB-INF/web.xml
      index.jsp
      index.php

      Notice, "index.jsp" is only a template file to get started with JSPs and "sun-web.xml" is GlassFish-specific deployment descriptor. These files are not required for this PHP application although it does not hurt to leave them in the webapp as well.
  3. Deploy the application by right-clicking on the project and selecting "Deploy Project". Your first PHP application in GlassFish is now deployed at "http://localhost:8080/hellophp/index.php".

Now that you have verified that your GlassFish is ready to host PHP applications, try the different applications that are described in Ludo's blog.

Technorati: php glassfish caucho quercus

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

TOTD #4: How to convert a Session EJB to a Web service ?

This TOTD describes how to convert a stateless session EJB to a Web service and uses information from this thread.

  1. Add @javax.jws.WebService annotation at the top of your EJB class. The modified code looks like:

    @javax.ejb.Stateless
    @javax.jws.WebService
    public class HelloSessionBean implements server.HelloSessionLocal {
        public String sayHello(String name) {
            return "Hello " + name + " from session bean";
        }
    }

    The new annotation is shown in this color.
  2. Re-build your project and redeploy it.

That's it!

There is no need to specify any additional deployment descriptor or parameters.The WSDL exposed by the EJB Web service endpoint is available at "http://localhost:8080/HelloSessionBeanService/HelloSessionBean?wsdl". The generated WSDL looks like:

<?xml version="1.0" encoding="UTF-8"?>
<!-- Published by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.2-hudson-182-RC1. -->
<!-- Generated by JAX-WS RI at http://jax-ws.dev.java.net. RI's version is JAX-WS RI 2.1.2-hudson-182-RC1. -->
<definitions
  xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"
  xmlns:wsp="http://schemas.xmlsoap.org/ws/2004/09/policy"
  xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
  xmlns:tns="http://server/"
  xmlns:xsd="http://www.w3.org/2001/XMLSchema"
  xmlns="http://schemas.xmlsoap.org/wsdl/"
  targetNamespace="http://server/"
  name="HelloSessionBeanService">
  <wsp:UsingPolicy></wsp:UsingPolicy>
  <wsp:Policy wsu:Id="HelloSessionBeanPortBinding_sayHello_WSAT_Policy">
    <wsp:ExactlyOne>
      <wsp:All>
        <ns1:ATAlwaysCapability xmlns:ns1="http://schemas.xmlsoap.org/ws/2004/10/wsat" wsp:Optional="false"></ns1:ATAlwaysCapability>
        <ns2:ATAssertion xmlns:ns3="http://schemas.xmlsoap.org/ws/2002/12/policy"
                         xmlns:ns2="http://schemas.xmlsoap.org/ws/2004/10/wsat" ns3:Optional="true"
                         wsp:Optional="true"></ns2:ATAssertion>
      </wsp:All>
    </wsp:ExactlyOne>
  </wsp:Policy>
  <types>
    <xsd:schema>
      <xsd:import namespace="http://server/" schemaLocation="http://localhost:8080/HelloSessionBeanService/HelloSessionBean?xsd=1"></xsd:import>
    </xsd:schema>
  </types>
  <message name="sayHello">
    <part name="parameters" element="tns:sayHello"></part>
  </message>
  <message name="sayHelloResponse">
    <part name="parameters" element="tns:sayHelloResponse"></part>
  </message>
  <portType name="HelloSessionBean">
    <operation name="sayHello">
      <input message="tns:sayHello"></input>
      <output message="tns:sayHelloResponse"></output>
    </operation>
  </portType>
  <binding name="HelloSessionBeanPortBinding" type="tns:HelloSessionBean">
    <soap:binding transport="http://schemas.xmlsoap.org/soap/http" style="document"></soap:binding>
    <operation name="sayHello">
      <wsp:PolicyReference URI="#HelloSessionBeanPortBinding_sayHello_WSAT_Policy"></wsp:PolicyReference>
      <soap:operation soapAction=""></soap:operation>
      <input>
        <soap:body use="literal"></soap:body>
      </input>
      <output>
        <soap:body use="literal"></soap:body>
      </output>
    </operation>
  </binding>
  <service name="HelloSessionBeanService">
    <port name="HelloSessionBeanPort" binding="tns:HelloSessionBeanPortBinding">
      <soap:address location="http://localhost:8080/HelloSessionBeanService/HelloSessionBean"></soap:address>
    </port>
  </service>
</definitions>

Few points to notice:

  1. A reasonable set of defaults are chosen for portType/@name, binding/@name, service/@name and even the soap:address/@location. Most of these values can be changed by specifying a different value in the @WebService annotation.

  2. Accordingly to EJB 3.0 specification, if @TransactionAttribute is not specified on the method then a default value of REQUIRED is applied. This default value is automatically converted to ATAlwaysCapability and ATAssertion policy assertions.

  3. Accordingly to Web Services for Java EE, Version 1.2, webservices.xml is optional so there is no need to write any other deployment descriptor.

  4. Be careful not to deploy a WAR file with the context root generated (HelloSessionBeanService) for the Web service endpoint. The EJB Web service endpoint will be inaccessible after that.

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

Technorati: totd webservices ejb glassfish

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070822 Wednesday August 22, 2007

Deep Dive on Project Tango

Watch a 25-minute video as Ed Ort deep dives on Project Tango (part of Metro) with me.

How to play the interview ? - Clicking on the image above takes you to the main page where different interviews are located. On that page, click on the Play button (sideways triangle) in the bottom left corner instead of "LOW BAND" or "HIGH BAND" buttons. More than one person asked me this question so it does seem slightly non-intuitive to me. Even I was confused but then figured out after playing around.

You can read more about Project Tango in this detailed article.

Technorati: webservices glassfish metro netbeans interview

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070820 Monday August 20, 2007

Ruby/JRuby Process Models Explained

In the JRuby Hackday, Nick Sieger described the process models of a Rails application deployed using

In this blog entry I'm capturing a brain dump from him after the event. The images below shows process models in each of the above mentioned approaches. The containment of boxes in each image is shown in terms of the application logic instead of the process. The legend followed in the images is as follows:

In the first approach, a C-based Ruby on Rails application is front-ended by an HTTP library - Mongrel. The typical app will be deployed on a cluster of Mongrel servers - provided by Mongrel_cluster plug-in.

This plug-in configure and control the several Mongrel servers. Mongrel is largely written in Ruby and uses native C for HTTP request parsing. Each instance of Mongrel starts a Ruby interpreter that listens on a server socket. The Ruby script has a Mongrel handler that queues up multiple requests from the client and passes the state, one at a time, to a Rails instance (that is by design single threaded).

For a Mongrel cluster, multiple Ruby interpreters are started as an OS process.

The second approach shows how a Rails application may be deployed using JRuby. This is a transition approach between traditional C-based Ruby on Mongrel deployment and JRuby-based deployment on GlassFish.

Mongrel JCluster is an update to Mongrel_cluster that only runs in JRuby. The biggest difference is that it starts only one Java Virtual Machine (JVM) that starts several Mongrels in the same JVM by spawning multiple JRuby processes, one in each thread. As in traditional approach, each Mongrel listens to the request on a server socket and passes the request state to Rails.

For a Mongrel JCluster, only one JVM is started as an OS process.

The last approach shows how a JRuby application may be deployed on GlassFish. With this approach, there are two modes to deploy an application.

In the first case, Goldspike plug-in is installed in a standard Rails application. This plug-in adds the "war:*" rake targets to a Rails project. Invoking "war:standalone:create" rake target creates a WAR file containing all the dependent JRuby and Rails libraries. This WAR file can then be deployed in GlassFish. The "web.xml" in this WAR file contains a Servlet (org.jruby.webapp.RailsServlet) that translates data from Servlet request to Rails dispatcher.
In the second case, the Grizzly connector understands the request format and dispatch it directly to a pre-configured JRuby installation (updated with the Rails gem). In both the cases, there is only one JVM running as the OS process for GlassFish. The main advantage of the second approach is that it by-passes the web application processing and delegate the request directly to the Rails framework.

A detailed screencast of the first GlassFish case (Goldspike/JRuby) is available here and for the second case (Grizzly/JRuby) is documented here.

Technorati: ruby jruby jrubyonglassfish glassfish grizzly goldspike rubyonrails ror

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070819 Sunday August 19, 2007

TOTD #3: Using JavaDB with JRuby on Rails

In a previous screencast, I showed how to develop a Rails application fetching data from the MySQL database and deploy it in GlassFish. GlassFish comes pre-bundled with JavaDB. Based upon a user request, this TOTD shows to use JavaDB database instead of MySQL.

Here are the steps required to replace MySQL database configuration with JavaDB. You can either mix these steps with the existing screencast or follow these steps altogether after the original app is created using MySQL.

  1. Copy "GLASSFISH_HOME/javadb/lib/derbyclient.jar" to "C:\Program Files\NetBeans 6.0M10\ruby1\jruby-1.0\lib" (or the directory location where JRuby for NetBeans 6 is installed). Make sure NetBeans IDE is restarted after the jar file is copied.
  2. In your application, change development database configuration in "database.yml" from:

    development:
      adapter: mysql
      database: glassfishrocks_development
      username: root
      password:
      host: localhost


    to

    development:
      adapter: jdbc
      driver: org.apache.derby.jdbc.ClientDriver
      url: jdbc:derby://localhost:1527/sample
      username: app
      password: app


    The NetBeans IDE comes pre-configured with the database URL, username and password used in this configuration.
  3. Start JavaDB using "asadmin start-database" command.
  4. Invoke db:migrate rake target to create the database required by the application. The development database configuration is used to create the database tables. If you followed the screencast, then a new table "greetings" is created in the database "sample".

  5. Change production database configuration in "database.yml" from:

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


    to

    production:
      adapter: jdbc
      driver: org.apache.derby.jdbc.ClientDriver
      url: jdbc:derby://localhost:1527/sample
      username: app
      password: app

    This new database configuration is exactly the same as for the development configuration. The production configuration is used by the WAR file.
  6. Insert value into the newly create database as "insert into GREETINGS values (1, 'Hello from JavaDB');".

  7. Create the WAR file using war:standalone:create rake target.
  8. Deploy the WAR file in the "GLASSFISH_HOME/domains/domain/autodeploy" directory.

You can also check out an early version of a tutorial that is being written about installing and configuring Ruby support in the NetBeans IDE. If you would like to get early access to Ruby documentation, learn more here.

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

Technorati: totd jrubyonglassfish jruby rubyonrails javadb glassfish ror ruby

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070817 Friday August 17, 2007

Getting Started with Ruby-on-Rails, GlassFish and NetBeans

Here are few pointers to get you started on Ruby-on-Rails in GlassFish and NetBeans:

Technorati: ruby jruby glassfish netbeans rubyonrails ror

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

TOTD #2: Change the endpoint address on a pre-generated Web services Stub

The client-side stubs generated by JAX-WS (part of Metro) are pre-configured with the endpoint address specified in the WSDL. This allows you to invoke the endpoint directly without any additional configuration. However there may be a need to send the exact same Web service request to an endpoint hosted at a different address. For example, the stubs may be generated from a WSDL hosted in the test environment and the request needs to be sent to an endpoint hosted in production environment that is very likely to be on a different machine.

This tip tells you how to change the endpoint address on a pre-generated stub so that it invokes a different endpoint.

The code to invoke a pre-configured stub (using the endpoint address from the WSDL) looks like:

Hello port = new HelloService().getHelloPort();
String result = port.sayHello("Duke!");

As per the JAX-WS 2.1 specification, each proxy implements javax.xml.ws.BindingProvider interface. In order to invoke an endpoint whose address is different from the one specified in the WSDL, you need to insert the following line between the two lines shown above:

((javax.xml.ws.BindingProvider)port).getRequestContext().put(javax.xml.ws.BindingProvider.ENDPOINT_ADDRESS_PROPERTY, "NEW_ADDRESS_HERE");

Just replace NEW_ADDRESS_HERE with your new endpoint address and the exact same request will be directed to the new endpoint. The WSDL contract must be exactly same though otherwise you may get an exception back.

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

Technorati: totd webservices metro soap glassfish

del.icio.us | furl | simpy | slashdot | technorati | digg |
|

http://blogs.sun.com/arungupta/date/20070816 Thursday August 16, 2007

Sun and Microsoft: Interoperability Now - New Article

Sun and Microsoft: Interoperability Now is a new article released from Sun Inner Circle. This is a follow up to Sun Net Talk where Greg Papadopoulos and Harold Carr provided a detailed overview of Project Tango. This article provides an update on how the 10-year collaborative agreement between Sun and Microsoft is reaping benefits for the customers.

Read more about Project Tango (part of Metro) in this 26-page article.

Sun Inner Circle is a monthly newsletter for IT professions and is available in 18 versions worldwide. A complete archive of the previous articles is available heree.

Technorati: webservices innercircle metro glassfish interoperability sun microsoft

del.icio.us | furl | simpy | slashdot | technorati | digg |
|
« Previous month (Jul 2007) | Main | Next page of month (Aug 2007) »

Valid HTML! Valid CSS!

This is a personal weblog, I do not speak for my employer.