Archive for 2012

Configuring IBM MQ in JBoss


In today's post I will explain how to install the WebSphere MQ resource adapter on JBoss.

Installing WebSphere MQ resource adapter:
To install WebSphere MQ resource adapter, copy the file wmq.jmsra.rar (from installation directory) to the server's deploy directory, for example <install path>/server/default/deploy The resource adapter will be automatically picked up by the server.

Installing the WebSphere MQ Extended Transactional Client:
The WebSphere MQ Extended transactional client lets you use XA distributed transactions with CLIENT mode connections to a WebSphere MQ queue manager. To install it on JBoss, copy the file com.ibm.mqetclient.jar ( from installation directory ) to the server lib directory, for example <install path>/server/default/lib.

Configuring the resource adapter for your application:
The WebSphere MQ resource adapter lets you define a number of global properties. Resource definitions for outbound JCA flows are defined in a JBoss -ds.xml file named wmq.jmsra-ds.xml. The outline form of this file:

  
  
  
  



As can be seen above JCA connection factories are defined in the <tx-connection-factory> element and JMS queues and topics are defined as JCA administered object mbeans.

A complete example for our sample application defining two queues - inbound and outbound is given below:

    
        jms/MyAppConnectionFactory
        wmq.jmsra.rar
        true
        javax.jms.QueueConnectionFactory
        8
        36
        ${channel}
        ${hostName}
        1414
        ${queueManager}
        CLIENT
        munish
        JmsXARealm
        
    
    
  jms/IncomingQueue
  jboss.jca:name='wmq.jmsra.rar',service=RARDeployment
  javax.jms.Queue
  
   baseQueueManagerName=${queueManager}
   baseQueueName=MY.APP.INBOUND.QUEUE
    
    
    
        jms/OutgoingQueue
        jboss.jca:name='wmq.jmsra.rar',service=RARDeployment
        javax.jms.Queue
        
            baseQueueManagerName=${queueManager}
            baseQueueName=MY.APP.OUTBOUND.QUEUE
        
    



The place holder properties are defined in the JBoss start script as:
-Dchannel=MQTEST -DhostName=localhost -DqueueManager=TST_MGR

Configuring inbound message delivery:
Message delivery to a Message-Driven Enterprise JavaBean (MDB) is configured using a JBoss-specific file named jboss.xml, located in the MDB .ear file. The contents of this file will vary, but will be of the form:

jboss.xml:

 
  
   MyMessageBean
    
     
                     
                             DestinationType
                             javax.jms.Queue
                     
                     
                             destination
                             MY.APP.INBOUND.QUEUE
                     
                     
                             channel
                             ${channel}
                     
                     
                             hostName
                             ${hostName}
                     
                     
                             port
                             1414
                     
                     
                             queueManager
                             ${queueManager}
                     
                     
                             transportType
                             CLIENT
                     
                     
                             username
                             munish
                     
              
               
           wmq.jmsra.rar
     
 


The DestinationType and Name properties must be specified. Other properties are optional, and if omitted, take on their default values.

A simple MDB definition for the inbound message is shown below:
/**
 * This message driven bean is used to collect asynchronously received messages.
 *
 * @author Munish Gogna
 */
@MessageDriven(mappedName = "jms/IncomingQueue")
public final class MyMessageBean implements javax.jms.MessageListener {
  private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(MyMessageBean.class);
  public void onMessage(final javax.jms.Message message) {
    LOGGER.info("Received message: " + message);
    // TODO - do processing with the message here
  }
}


A plain java class to send message to the output queue is shown below.
/**
 * This class is used to send text messages to a queue.
 *
 * @author Munish Gogna
 */
public final class MessageSender {
  private static final org.apache.log4j.Logger LOGGER = org.apache.log4j.Logger.getLogger(MessageSender.class);
  /**
   * A coarse-grained method, nothing fancy. In actual applications please re factor the code and
   * handle the exceptions properly.
   *
   * @throws Exception
   */
  public void send(final String message) throws Exception {
    if (message == null) {
      throw new IllegalArgumentException("Parameter message cannot be null");
    }
    javax.jms.QueueConnection connection = null;
    javax.jms.Session session = null;
    try {
      javax.naming.Context fContext = new javax.naming.InitialContext();
      javax.jms.QueueConnectionFactory fConnectionFactory = (javax.jms.QueueConnectionFactory) fContext
          .lookup("java:jms/MyAppConnectionFactory");
      connection = fConnectionFactory.createQueueConnection();
      session = connection.createSession(false, javax.jms.Session.AUTO_ACKNOWLEDGE);
      final javax.naming.Context jndiContext = new javax.naming.InitialContext();
      final javax.jms.Destination destination = (javax.jms.Destination) jndiContext.lookup("jms/OutgoingQueue");
      final javax.jms.MessageProducer messageProducer = session.createProducer(destination);
      final javax.jms.TextMessage textMessage = session.createTextMessage(message);
      messageProducer.send(textMessage);
      messageProducer.close();
    } catch (Exception nex) {
      throw nex;
    } finally {
      if (session != null) {
        try {
          session.close();
        } catch (JMSException e) {
          LOGGER.error("Failed to close JMS session", e);
        }
      }
      if (connection != null) {
        try {
          connection.close();
        } catch (JMSException e) {
          LOGGER.error("Failed to close JMS connection", e);
        }
      }
    }
  }
}
A utilty called RFHUTILC.EXE can be used to connect to remote queues.

That's all.
Monday, June 4, 2012
Posted by Munish Gogna

Saving development time with local EntityManager in JPA

In almost all real world projects (non Spring + We are not considering Arquillian or any similar framework) where you are using JPA (Hibernate implementation), the data source binding happens by JNDI and the services are provided by EJBs, which means to test your entities for any CRUD operation you have to deploy the bundle (ear, ejb or war) into the application server which adds time to your development efforts each time you make any change. So in this post we will see how we can temporarily inject entity manager into your business class so that you can test all the operations you want to perform on entities without deploying the application or restarting server quite often.

persistence.xml: The configuration for entity managers both inside an application server and in a standalone application reside in a persistence archive. In the next section we focus on standalone configuration.

 
  org.hibernate.ejb.HibernatePersistence
  com.gognamunish.test.Entity
  
   
   
   
   
   
  
 

Please Note:
  • The database dialect we have chosen is MySQL for obvious reasons.
  • Persistence unit has name test_unit and the type is RESOURCE_LOCAL and not JTA.
  • com.gognamunish.test.Entity is the entity which we want to test later.
  • As we are running without a JNDI available datasource, we must specify JDBC connections with Hibernate specific properties
Next in your business class you can get reference to the entity manager as follow:
EntityManagerFactory factory ;
factory = Persistence.createEntityManagerFactory("test_unit");
EntityManager manager = factory.createEntityManager();
That's all you need , after obtaining the reference focus only on your entity and the operation you want to perform on it.
Let's try one sample example:
/* Sample Entity class */
@javax.persistence.Entity
@Table(name = "Entity")
public class Entity {
 @Id
 private Long id;
 @Column
 private String value;
}
package com.gognamunish.test;

import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
 * Sample Test - nothing fancy.
 * 
 * @author Munish Gogna
 * 
 */
public class LocalEntityManager {
 static EntityManager manager;
 static {
  EntityManagerFactory factory = Persistence
    .createEntityManagerFactory("test_unit");
  manager = factory.createEntityManager();
 }

 public static void main(String[] args) {

  System.out.println("Before Entities: " + getEntities());

  manager.getTransaction().begin();
  Entity entity = new Entity();
  entity.setId(1l);
  entity.setValue("my first value");
  saveOrUpdate(entity);
  manager.getTransaction().commit();

  System.out.println("After Entities: " + getEntities());

 }

 private static Entity saveOrUpdate(Entity entity) {
  return manager.merge(entity);
 }

 @SuppressWarnings("unchecked")
 private static List<Entity> getEntities() {
  return manager.createQuery("from Entity").getResultList();
 }
}

LOGS:
Hibernate: select entity0_.id as id0_, entity0_.value as value0_ from Entity entity0_
Before Entities: []
Hibernate: select entity0_.id as id0_0_, entity0_.value as value0_0_ from Entity entity0_ where entity0_.id=?
Hibernate: insert into Entity (value, id) values (?, ?)
Hibernate: select entity0_.id as id0_, entity0_.value as value0_ from Entity entity0_
After Entities: [Id:1, Value:my first value]
Sunday, April 29, 2012
Posted by Munish Gogna

Reverse a String in Java

One of the frequently asked questions in interviews, let's try few ways available in JDK to reverse a string:





import java.util.Stack;
public class StringReverse {

 public static String reverse1(String s) {
  int length = s.length();
  if (length <= 1)
   return s;
  String left = s.substring(0, length / 2);
  String right = s.substring(length / 2, length);
  return reverse1(right) + reverse1(left);
 }

 public static String reverse2(String s) {
  int length = s.length();
  String reverse = "";
  for (int i = 0; i < length; i++)
   reverse = s.charAt(i) + reverse;
  return reverse;
 }

 public static String reverse3(String s) {
  char[] array = s.toCharArray();
  String reverse = "";
  for (int i = array.length - 1; i >= 0; i--)
   reverse += array[i];

  return reverse;
 }

 public static String reverse4(String s) {
  return new StringBuffer(s).reverse().toString();
 }

 public static String reverse5(String orig) {
  char[] s = orig.toCharArray();
  int n = s.length - 1;
  int halfLength = n / 2;
  for (int i = 0; i <= halfLength; i++) {
   char temp = s[i];
   s[i] = s[n - i];
   s[n - i] = temp;
  }
  return new String(s);
 }

 public static String reverse6(String s) {

  char[] str = s.toCharArray();

  int begin = 0;
  int end = s.length() - 1;

  while (begin < end) {
   str[begin] = (char) (str[begin] ^ str[end]);
   str[end] = (char) (str[begin] ^ str[end]);
   str[begin] = (char) (str[end] ^ str[begin]);
   begin++;
   end--;
  }

  return new String(str);
 }

 public static String reverse7(String s) {
  char[] str = s.toCharArray();
  Stack<Character> stack = new Stack<Character>();
  for (int i = 0; i < str.length; i++)
   stack.push(str[i]);

  String reversed = "";
  for (int i = 0; i < str.length; i++)
   reversed += stack.pop();

  return reversed;
 }

}


Feel free to suggest other ways if you have.
Sunday, March 4, 2012
Posted by Munish Gogna

Merging PDFs while retaining the fill able forms inside them

My previous post was about merging the PDF files into single file using PDFBox, the limitation of that approach was if you had fill able form inside any PDF file it was lost, to over come that issue here is an updated version of the same post using iText library.







import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.PdfCopyFields;
import com.lowagie.text.pdf.PdfReader;

/**
 * Merges the PDF files while retaining the fillable forms within them. It also
 * renames form field (to avoid conflicts) which can have an impact if form is
 * submitted to server but for printing purpose should be OK.
 * 
 * @author Munish Gogna
 * 
 */
public class PDFMerge {
 private static int counter = 0;

 public static void merge(List<InputStream> sourcePDFs,
   OutputStream targetPDF) throws Exception {
  if (sourcePDFs != null && targetPDF != null) {
   PdfCopyFields copy = new PdfCopyFields(targetPDF);

   for (InputStream stream : sourcePDFs) {
    PdfReader pdfReader = new PdfReader(stream);
    renameFields(pdfReader.getAcroFields());
    copy.addDocument(pdfReader);
    stream.close();
   }
   copy.close();
  }
 }

 private static void renameFields(AcroFields fields) {
  Set<String> fieldNames = fields.getFields().keySet();
  String prepend = String.format("_%d.", counter++);

  for (String fieldName : fieldNames) {
   fields.renameField(fieldName, prepend + fieldName);
  }
 }

 public static void main(String[] args) {
  try {
   List<InputStream> pdfs = new ArrayList<InputStream>();
   pdfs
     .add(new URL(
       "http://thewebjockeys.com/TheWebJockeys/Fillable_PDF_Sample_from_TheWebJockeys_vC5.pdf")
       .openStream());
   pdfs
     .add(new URL(
       "http://help.adobe.com/en_US/Acrobat/9.0/Samples/interactiveform_enabled.pdf")
       .openStream());
   OutputStream output = new FileOutputStream("merged.pdf");

   merge(pdfs, output);

  } catch (Exception e) {
   e.printStackTrace();
  }
 }

}

The iText jar can be downloaded here

Thanks.
Sunday, January 15, 2012
Posted by Munish Gogna

Popular Post

Labels

enums (1) java (2) JAX-RS (1) JPA (1) mysql (1) request 2 (1) RESTful (1) sphinx (1) tomcat (1) web service (2) ws (2)