Thursday, July 5, 2012

Solved - Weird exceptions while starting Intellij IDEA

Intellij IDEA has been my favourite IDE for nearly the past 4 years. The amazing set of user-friendly options and functionalities offered to the developers by the IDE have clearly gotten me attracted towards it.

However, recently when I tried to boot up my IDEA instance it started throwing a flurry of exceptions at the my command line console out of the blue. Although the server was started, most of the options such as attaching dependencies to my projects, etc were not functioning properly. The following log depicts part of the error logged at the server startup.



Though I tried re-installing the distribution and various other options I couldn't really get it to work. Finally, I backed up the "config" and "system" directories that contain your IDEA configuration settings and data cache residing in "~/.IntelliJIdea90/" directory and deleted them from the file system. Then restarted the IDEA instance and that seemed to have fixed all the aforementioned issues!

Note : This may result in you losing all the metadata stored in the data cache resides in the "~/.IntelliJIdea90/system" folder and your configuration settings stored in the "~/.IntelliJIdea90/config" directory. You also will have to re-install your license if you're using enterprise edition of Intellij IDEA.

Thursday, May 3, 2012

Query UDTs(User Defined Types) with WSO2 Data Service Server



In this brief tutorial I ll be guiding you through the process of developing a simple dataservice which is capable of retrieving an Oracle UDT (User Defined Type) from a database using WSO2 Data Services Server.

First, login to your preferred Oracle database via your favourite SQL client tool or the sqlplus command line utility and run the following script. This will create necessary UDT structures, a table to store the UDT type as well as some sample data which will later be queried via dataservice.



CREATE OR REPLACE TYPE address_t AS OBJECT(num NUMBER, street VARCHAR2(100), city VARCHAR2(100), STATE VARCHAR2(100), country VARCHAR2(100));
/
CREATE OR REPLACE TYPE customer_t AS OBJECT(id NUMBER, name VARCHAR2(50));
/
CREATE TABLE customer_tbl (customer_id NUMBER, customer_name VARCHAR2(100), customer_address ADDRESS_T);
/
INSERT INTO customer_tbl
VALUES (1,
        'john',
        address_t(25, 'flower road', 'Brooklyn', 'Western London', 'United Kingdom'));

INSERT INTO customer_tbl
VALUES (2,
        'peter',
        address_t(25, 'flower road', 'El Camino Real', 'Palo Alto', 'California'));

CREATE OR REPLACE PROCEDURE getCustomer(cust OUT customer_t) IS BEGIN cust := customer_t(1, 'prabath'); END;
/

Next, download the latest version of WSO2 Data Service Pack from here and extract it to a proper location in your file system. Let's call it DSS_HOME. Then copy the Oracle JDBC jar downloaded from here to DSS_HOME/repository/components/lib directory.

Now we're done with preparing the surroundings for creating the dataservice.

Let's now start the WSO2 Data Service Server and start building up the dataservice. (You can find more detailed information about developing a simple dataservice from here.). Depicted below is a sample dataservice descriptor file (.dbs) that carries a dataservice queries for retrieving and inserting UDT values in customer_address column of the customer_tbl table.

<?xml version="1.0" encoding="UTF-8"?>
<data name="UDTSample">
   <config id="default">
      <property name="org.wso2.ws.dataservice.driver">oracle.jdbc.driver.OracleDriver</property>
      <property name="org.wso2.ws.dataservice.protocol">jdbc:oracle:thin:@localhost:1521:XE</property>
      <property name="org.wso2.ws.dataservice.user">djpro</property>
      <property name="org.wso2.ws.dataservice.password">admin</property>
   </config>
   <query id="q1" useConfig="default">
      <sql>SELECT customer_id, customer_name, customer_address FROM customer_tbl</sql>
      <result element="Entries" rowName="Entry">
         <element name="ID" column="customer_id" xsdType="xs:integer" />
         <element name="Name" column="customer_name" xsdType="xs:string" />
         <element name="Number" column="customer_address[0]" xsdType="xs:integer" />
         <element name="Street" column="customer_address[1]" xsdType="xs:string" />
         <element name="City" column="customer_address[2]" xsdType="xs:string" />
         <element name="State" column="customer_address[3]" xsdType="xs:string" />
         <element name="Country" column="customer_address[4]" xsdType="xs:string" />
      </result>
   </query>
   <query id="q2" useConfig="default">
      <sql>INSERT INTO customer_tbl VALUES(?,?,address_t(?,?,?,?,?))</sql>
      <param name="ID" sqlType="INTEGER" />
      <param name="Name" sqlType="STRING" />
      <param name="Number" sqlType="INTEGER" />
      <param name="Street" sqlType="STRING" />
      <param name="City" sqlType="STRING" />
      <param name="State" sqlType="STRING" structType="null" />
      <param name="Country" sqlType="STRING" />
   </query>
   <query id="q3" useConfig="default">
      <sql>call getCustomer(?)</sql>
      <result element="customers" rowName="customer">
         <element name="id" column="cust[0]" xsdType="xs:integer" />
         <element name="name" column="cust[1]" xsdType="xs:string" />
      </result>
      <param name="cust" sqlType="STRUCT" type="OUT" structType="CUSTOMER_T" />
   </query>
   <operation name="op1">
      <call-query href="q1" />
   </operation>
   <operation name="op2">
      <call-query href="q2">
         <with-param name="ID" query-param="ID" />
         <with-param name="Name" query-param="Name" />
         <with-param name="Number" query-param="Number" />
         <with-param name="Street" query-param="Street" />
         <with-param name="City" query-param="City" />
         <with-param name="State" query-param="State" />
         <with-param name="Country" query-param="Country" />
      </call-query>
   </operation>
   <operation name="op3">
      <call-query href="q3" />
   </operation>
</data>
NOTE: 
If you carefully look at the input mappings defined for the dataservice query "q1", the UDT attributes that are being retrieved are specified in the format of "database_column_name[UDT_attribute_index]"

Once you deploy the "UDTSample" dataservice in the WSO2 Data Services Server it will be displayed under the service list. 


You can then click on the Tryit client functionality using which you will be able to test the data service operations that manipulate the aforementioned UDT structures. 

I trust this simple tutorial helps you understand the basics of manipulating UDTs with WSO2 Data Services Server. Further, I'm hoping to come up with more complex samples explaining scenarios such as how to retrieve UDTs as OUT parameters of stored procedures, how to query SQL Arrays via stored procedures/ordinary SQL queries/Ref cursors, etc soon.

Retrieve the classes implementing a particular interface programmatically in Java

I recently had a requirement to retrieve all the classes that implement a particular service interface programmatically in Java. While searching for some way to get my requirement fulfilled I came across the class ServceLoader exposed by java.util.* package as a part of Java 1.6 APIs. 

Shown below is a sample scenario where you can use the aforementioned class effectively to retrieve the service providers (typically implementer classes of an interface or an abstract class) list that implement a particular service (typically a well known interface or abstract classs).

Assume I want to register the set of implementer classes of the java.sql.Driver interface that exists in my current thread's classloader explicitely. You can accomplish that task in the following manner.

NOTE:
If a particular service provider implements a service interface then the jar containing those implementer classes carries the provider-configuration file in the resource directory similar to the following format.

Eg: META-INF/services/java.sql.Driver
ClassLoader callerCL = Thread.currentThread().getContextClassLoader();
ServiceLoader<Driver> servLoader = ServiceLoader.load(java.sql.Driver.class, callerCL);
for (Driver driver : servLoader) {
   String driverName = driver.getClass().getName();
   try {
       Class.forName(driverName);
   } catch (ClassNotFoundException e) {
       log.error("Unable to registery driver class '" + driverName + "'", e);
   }
}