Wednesday, June 9, 2010

WSIMPORT configuration in Maven

While developing a webservice client, we need to generate the client stub from the wsdl. There are many ways of doing this. One way is to use the Maven wsimport plugin.

Below is the way how we do it.

Use "mvn -P wsimport" generate a fresh JAX-WS client, then check that client
into subversion as source. Whenever the service contract changes, run mvn wsimport again. (Each time you
run it with the wsimport profile, maven will clean the source folder and regenerate all the JAX-WS client Javas)

Use the following link to learn how to make a Spring config for Spring-loading the JAX-WS client:
http://static.springsource.org/spring/docs/2.5.x/reference/remoting.html#remoting-web-services-jaxws-access

Note: if you don't specify the wsimport profile with the "mvn -P wsimport" command, then this module simply builds
a straight java jar. This nice selective build feature of maven lets us checkin the jaxws java artifacts to
subversion, and lets us control when we do new java generation only when the service interface changes.


<profiles>
<profile>
<id>wsimport</id>
<build>
<defaultGoal>install</defaultGoal>

<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.6</source>
<target>1.6</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-3</version>
<configuration>
<descriptorRefs>
<descriptorRef>
jar-with-dependencies
</descriptorRef>
</descriptorRefs>
<archiverConfig>
<duplicateBehavior>
skip
</duplicateBehavior>
</archiverConfig>
</configuration>
</plugin>

<plugin>
<artifactId>maven-clean-plugin</artifactId>
<version>2.2</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>clean</goal>
</goals>
<configuration>
<filesets>
<fileset>
<directory>
src/main/java/com/company/proj/serviceclient/module
</directory>
<includes>
<include>
**/*.java
</include>
<include>
**/*.properties
</include>
</includes>
<followSymlinks>
false
</followSymlinks>
</fileset>
</filesets>
</configuration>
</execution>
</executions>
</plugin>

<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>jaxws-maven-plugin</artifactId>
<version>1.12</version>
<executions>

<execution>
<id>UserManagementClient</id>
<goals>
<goal>wsimport</goal>
</goals>
<configuration>
<keep>true</keep>
<sourceDestDir>src/main/java</sourceDestDir>
<xdebug>true</xdebug>
<verbose>true</verbose>
<target>2.1</target>
<extension>true</extension>
<bindingFiles><bindingFile>${basedir}/src/main/resources/generateElementProperty.binding</bindingFile></bindingFiles>
<!-- <xauthFile>${basedir}/src/main/resources/authFile</xauthFile> -->
<wsdlUrls>
<wsdlUrl>
http://server.companyname.com:8001/projectcontext/1.0.0?wsdl
</wsdlUrl>
</wsdlUrls>
<packageName>
com.equinix.gse.serviceclient.usermanagement
</packageName>
</configuration>
</execution>
</executions>


<!-- if you want to use a specific version of JAX-WS, you can do so like this -->
<!--dependencies>
<dependency>
<groupId>com.sun.xml.ws</groupId>
<artifactId>jaxws-tools</artifactId>
<version>2.1.7</version>
</dependency>
</dependencies-->
</plugin>

</plugins>

</build>
</profile>
</profiles>

Tuesday, June 8, 2010

Transaction Management using Spring

Spring provides a comprehensive transaction support. And if you are using spring, you must be using transaction management that comes with it. It provides a good set of abstractions for transaction management.

You can implement transaction management with a few configurations in the application context file of spring and no additions or alterations to the java code.

Below is the configuration which is required for single Database transaction management.

<!-- ***** Transaction Manager ****** -->
<bean id="txManager1"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="projectDataSource" />
</bean>
<!-- ****** Transaction Definitions ***** -->
<!-- Default Isolation level is used - READ COMMITTED -->

<tx:advice id="txAdvice1" transaction-manager="txManager1">
<tx:attributes>
<tx:method name="*" propagation="REQUIRED" />
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id="allProcessOperations"
expression="execution(* com.company.proj.bo.process.*Process.*(..))" />
<aop:advisor advice-ref="txAdvice1"
pointcut-ref="allProcessOperations" />
</aop:config>

The projectDataSource is ofcource the datasource bean which you must define for your datasource.

The above configuration binds all the operations on the projectDataSource into one transaction.
The AOP pointcut "execution(* com.company.proj.bo.process.*Process.*(..))" indicates that all the methods under all the classes ending with "Process" under the package com.company.proj.bo.process will be considered in transaction management.

The TX and AOP schema locations are
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd

Any exception during the execution of a method which is bound under the above transaction will automatically rollback all changes. If the method completes without any exceptions, then the changes will be committed.

Distributed Transaction management
If you have distributed transactions in your method, then we can bind that method under JTA transaction

You may have a scenario where you are altering two data sources and also publishing into a JMS queue. All these operations can be bound under a JTA transaction. The configuration is as below.

<!-- ========== TX MANAGER ============= -->
<bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
<property name="transactionManagerName" value="javax.transaction.TransactionManager"/>
</bean>

<tx:advice id="txAdviceJTA" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="persistData*" propagation="REQUIRED" timeout="120000"/>
</tx:attributes>
</tx:advice>

<aop:config>
<aop:pointcut id="processOperations"
expression="execution(* com.company.proj.bo.process.MyProcess.*(..))" />
<aop:advisor advice-ref="txAdviceJTA"
pointcut-ref="processOperations" />
</aop:config>

Note that if a datasource or a JMS connection factory must be used in a JTA transaction, then they must be XA enabled. Otherwise they will not be involved in a JTA transaction.

Send Text Message To JMS Queue - Spring

Since I am working on Spring these days, I would post more on Spring as I have realised that Spring is the most comprehansive and more developer friendly framework among all the available frameworks in Java programming language.

Below is a class (the full code infact) that is useful to publish a text mesage into a JMS queue. Note that it use the Spring JmsTemplate. The configuration of which is given after the code snippet.


import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.Session;

import org.springframework.jms.core.JmsTemplate;
import org.springframework.jms.core.MessageCreator;

/**
* Class to send JMS through spring jms template
*
* @author Darel
*
*/
public class JMSSender {
private JmsTemplate jmsTemplate;

public JmsTemplate getJmsTemplate() {
return jmsTemplate;
}

public void setJmsTemplate(JmsTemplate jmsTemplate) {
this.jmsTemplate = jmsTemplate;
}

/**
* send JMS to JMS server
*
* @param queueName
* JMS queue name
* @param msg
* Queue object to be sent
*/

public void sendMesage(String queueName, final String msg) {
jmsTemplate.send(queueName, new MessageCreator() {
public Message createMessage(Session session) throws JMSException {

return session.createTextMessage(msg);

}
});
}

}


Since this now a JMS client, we need the configuration in the application context file of Spring. The configuration is as below.


<!-- ************* JMS Client configuration ************************* -->
<bean id="jmsSender" class="com.mycompany.proj.service.util.JMSSender">
<property name="jmsTemplate">
<ref bean="queueTemplate" />
</property>
</bean>
<bean id="queueTemplate"
class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory">
<ref bean="queueConnectionFactory" />
</property>
<property name="destinationResolver">
<ref bean="jmsDestinationResolver" />
</property>


</bean>
<bean id="queueConnectionFactory"
class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiTemplate">
<ref bean="permissionJndiTemplate" />
</property>
<property name="jndiName">
<value>${jms.connectionFactory}</value>
</property>
</bean>
<bean id="jmsDestinationResolver"
class="org.springframework.jms.support.destination.JndiDestinationResolver">
<property name="jndiTemplate">
<ref bean="permissionJndiTemplate" />
</property>
<property name="cache">
<value>true</value>
</property>
</bean>
<bean id="permissionJndiTemplate"
class="org.springframework.jndi.JndiTemplate">
<property name="environment">
<props>
<prop key="java.naming.factory.initial">
weblogic.jndi.WLInitialContextFactory
</prop>
<prop key="java.naming.provider.url">
${jms.provider.url}
</prop>
<prop key="java.naming.security.authentication">
${jms.authentication.type}
</prop>
<prop key="java.naming.security.principal">
${jms.security.principal}
</prop>
<prop key="java.naming.security.credentials">
${jms.security.credentials}
</prop>
</props>
</property>
</bean>


The values have $(...) which means that the value is got from the properties file. You can also hardcode the values if you do not have a properties file.

The above should be enough to publish a text message to the JMS queue. If you would need to publish a object. You can use the createObjectMessage method instead of createTextMessage.

You may also publidh a SOAP message into the JMS queue using this client. You will have to write the soap message object to a out stream and convert that to a String. The example is shown below.

//Here I am assuming that you have a method to create a SOAP message
SOAPMessage soapMessage = getSoapMessage();

ByteArrayOutputStream out = new ByteArrayOutputStream();

soapMessage.writeTo(out);

jmsSender.sendMesage(queueName, out.toString());

Extract Struct Object from pl/sql output - Spring

In most of our application where a procedure is written, most often than not we would have to extract the response of the oracle pl/sql call from its out parameters. Below is a small code snippet which can guide you to get that data which you need. There can be small changes depending on the jdbc framework you use. I have copied it from my project code which I had written using Spring JDBC and Oracle.

For Spring JDBC developers, the first 3 lines show how we can execute and extract the out object. The remaining lines of code is common for any framework.

Map outputMap = simpleJdbcCallObject.execute(map);

String result = (String) outputMap.get("O_RETURN_STATUS");

java.sql.Struct permissionStatus = (java.sql.Struct) outputMap
.get("P_RECORD_STATUS_OBJ");

Now that we have the Struct, let us see a scenario where we have a table object which contains a array of oracle objects. This table object is wrapped inside a wrapper object. (It is better to wrap the table inside a wrapper object which will be recieved as a Struct rather than getting the table object directly from the procedure call)

List recordStatusResult = new ArrayList();
try {
//Get the attributes from the wrapper object (Struct). We may have more than one table/elements inside the wrapper object. but in this case, we have only one table object
Object[] tableAttributeArray = permissionStatus.getAttributes();
//Make sure the the wrapper object is not null or empty
if (tableAttributeArray == null or tableAttributeArray.length < 1
or tableAttributeArray[0] == null) {

throw new Exception(
"No table data found in the response from the pl/sql procedure");
}
//Get the table object from the attributes, which is of type oracle.sql.ARRAY
ARRAY tableAttribute = (ARRAY) tableAttributeArray[0];
//Get the records from the table. Each record will be a object which is required for us.
Object[] structArray = (Object[]) tableAttribute.getArray();
//Make sure the table has atleast one record. You can skip this if not required to check
if (structArray == null or structArray.length < 1) {

throw new Exception(
"No Object data found in the response from the pl/sql procedure");
}
//Loop throw all the records to get the data.
Object struct;
for (int i = 0; i < structArray.length; i++) {
//Get the ith record from the table
struct = structArray[i];
//Each record will have one or more elements or properties
Object[] permissionData = ((Struct) struct).getAttributes();
//In my case, I store it in a list, you can extract the value like String s = (String)permissionData[0];
recordStatusResult.add(permissionData);
}
} catch (SQLException e) {
throw new Exception(
"Error while fetching the data from the pl/sql output.",
e);
}

The code above has comments which explain each step, so I believe no more explanation is required.
I need to return the data in a list, hence I am storing each object array record in the list.