Miles to go …

August 31, 2007

San Francisco Marathon 07 Finishers Certificate

Filed under: Running — arungupta @ 12:02 am

Read all about my race participation here.

Technorati: running runsfm

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

August 30, 2007

First time – Blog at top rank

Filed under: General — arungupta @ 4:26 pm

Oh gosh, this is exciting!

Thanks Eduardo for the tip!

Technorati: blogs rank bsc hotblog

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

TOTD #5: Loading data from beans in jMaki widgets

Filed under: web2.0 — arungupta @ 12:02 am

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();
      }
    } r>
    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

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

August 29, 2007

Excel using WSIT – Metro and .NET interoperability sample

Filed under: webservices — arungupta @ 12:02 am
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:[email protected]:/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 or Metro Forum.

Technorati: webservices metro glassfish dotnet .net interoperability netbeans wcf

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

August 28, 2007

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

Filed under: web2.0 — arungupta @ 12:02 am

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

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

August 27, 2007

ActiveRecord-JDBC 0.5 – simplified database configuration

Filed under: web2.0 — arungupta @ 12:02 am

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

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

August 24, 2007

jMaki, PHP and GlassFish – again using Caucho Quercus

Filed under: web2.0 — arungupta @ 6:00 am

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 twi
      st 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

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

August 23, 2007

PHP in GlassFish using Caucho Quercus

Filed under: web2.0 — arungupta @ 10:00 pm

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

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

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

Filed under: webservices — arungupta @ 6:09 am

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

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot

August 22, 2007

Deep Dive on Project Tango

Filed under: webservices — arungupta @ 9:57 am

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

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • StumbleUpon
  • Technorati
  • Twitter
  • Slashdot
Older Posts »

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.
Powered by WordPress