Saturday, August 31, 2013

Exceptions!!!!! Hornetq Exception solved


java.lang.RuntimeException: HornetQException[errorType=NOT_CONNECTED message=HQ119007: Cannot connect to server(s). Tried with all available servers.]
One of the exception I ran into while experimenting with HORNETQ REST INTERFACE. Hope this saves your time!!!!
This is caused because of not mentioning hornetq and netty dependencies in MANIFEST.MF file. Just add "Dependencies: org.hornetq, org.jboss.netty" in MANIFEST.MF in your WAR file or in your pom.xml.

    org.apache.maven.plugins
    maven-war-plugin
    
     
      
       org.hornetq,org.jboss.netty
      
     
    
   
Exception full stack trace
15:05:57,228 ERROR [org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/jms-rest-examples]] (ServerService Thread Pool -- 59) JBWEB000287: Exception sending context initialized event to listener instance of class org.hornetq.rest.integration.RestMessagingBootstrapListener: java.lang.RuntimeException: HornetQException[errorType=NOT_CONNECTED message=HQ119007: Cannot connect to server(s). Tried with all available servers.]
 at org.hornetq.rest.integration.RestMessagingBootstrapListener.contextInitialized(RestMessagingBootstrapListener.java:40) [hornetq-rest-2.3.5.Final.jar:]
 at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3339) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
 at org.apache.catalina.core.StandardContext.start(StandardContext.java:3777) [jbossweb-7.2.0.Final-redhat-1.jar:7.2.0.Final-redhat-1]
 at org.jboss.as.web.deployment.WebDeploymentService.doStart(WebDeploymentService.java:156) [jboss-as-web-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
 at org.jboss.as.web.deployment.WebDeploymentService.access$000(WebDeploymentService.java:60) [jboss-as-web-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
 at org.jboss.as.web.deployment.WebDeploymentService$1.run(WebDeploymentService.java:93) [jboss-as-web-7.2.0.Final-redhat-8.jar:7.2.0.Final-redhat-8]
 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0_25]
 at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) [rt.jar:1.7.0_25]
 at java.util.concurrent.FutureTask.run(FutureTask.java:166) [rt.jar:1.7.0_25]
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_25]
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_25]
 at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_25]
 at org.jboss.threads.JBossThread.run(JBossThread.java:122)
Caused by: HornetQException[errorType=NOT_CONNECTED message=HQ119007: Cannot connect to server(s). Tried with all available servers.]
 at org.hornetq.core.client.impl.ServerLocatorImpl.createSessionFactory(ServerLocatorImpl.java:863) [hornetq-core-client-2.3.5.Final.jar:]
 at org.hornetq.rest.MessageServiceManager.start(MessageServiceManager.java:157) [hornetq-rest-2.3.5.Final.jar:]
 at org.hornetq.rest.integration.RestMessagingBootstrapListener.contextInitialized(RestMessagingBootstrapListener.java:34) [hornetq-rest-2.3.5.Final.jar:]
 ... 12 more

15:05:57,290 ERROR [org.apache.catalina.core] (ServerService Thread Pool -- 59) JBWEB001103: Error detected during context /jms-rest-examples start, will stop it
15:05:57,311 ERROR [org.jboss.msc.service.fail] (ServerService Thread Pool -- 59) MSC000001: Failed to start service jboss.web.deployment.default-host./jms-rest-examples: org.jboss.msc.service.StartException in service jboss.web.deployment.default-host./jms-rest-examples: org.jboss.msc.service.StartException in anonymous service: JBAS018040: Failed to start context
 at org.jboss.as.web.deployment.WebDeploymentService$1.run(WebDeploymentService.java:96)
 at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:471) [rt.jar:1.7.0_25]
 at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) [rt.jar:1.7.0_25]
 at java.util.concurrent.FutureTask.run(FutureTask.java:166) [rt.jar:1.7.0_25]
 at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145) [rt.jar:1.7.0_25]
 at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615) [rt.jar:1.7.0_25]
 at java.lang.Thread.run(Thread.java:724) [rt.jar:1.7.0_25]
 at org.jboss.threads.JBossThread.run(JBossThread.java:122) [jboss-threads-2.1.0.Final-redhat-1.jar:2.1.0.Final-redhat-1]
Caused by: org.jboss.msc.service.StartException in anonymous service: JBAS018040: Failed to start context
 at org.jboss.as.web.deployment.WebDeploymentService.doStart(WebDeploymentService.java:161)
 at org.jboss.as.web.deployment.WebDeploymentService.access$000(WebDeploymentService.java:60)
 at org.jboss.as.web.deployment.WebDeploymentService$1.run(WebDeploymentService.java:93)
 ... 7 more

Tuesday, August 27, 2013

Simple HornetQ JMS Tutorial


If you are interested to see the other REST tutorials I already blogged, please find them below
As part of series of REST tutorials, I am blogging this simple HorneQ JMS tutorial. HornetQ is the default meessaging system in JBOSS application server.
A detailed documentation about HornetQ is available @ here.Lets get started with the tutorial
Technologies used
  • HornetQ
  • JBOSS eap 6.1
  • JAVA 7
  • RESTEasy
  • CDI
  • Maven
 Now lets see what configuration we require before we start our coding. Before we start any configuration a basic understanding of JBOSS server is required. JBOSS server directory structure will look this

Different startup configurations are available in JBOSS server. To have the HORNETQ integrated and started with JBOSS AS one should use standalone-full.xml. For example we will start the server using this command
./standalone.sh --server-config=standalone-full.xml.
We will add the queues needed for our tutorial in standalone-full.xml. There are other ways too to declare the queues/topics which is out of scope of this post. I am gonna develop a order processing system which can receive a order which is a XML file and it will put the order in a queue which will be consumed by other consumers. Lets name that queue as "ticketOrderQueue". Here is how we declare in standalone-full.xml
                 
                    
                        
                        
                    
                    
                        
                        
                    
                
To connect to this queues we will use JNDI connection factories. By default JBOSS gives us couple of connection factories like "InvmConnectionFactory" and "RemoteConnectionFactory" which will use netty connector. Code snippet of these factories is below

                        
                            
                        
                        
                            
                        
                    
                    
                        
                            
                        
                        
                            
                        
                    

If our message producer or consumer is in same JAVA VM as HornetQ one should use "java:/ConnectionFactory" and if it is remote client consuming or producing messaging to JMS destinations one should use "RemoteConnectionFactory". Noteworthy about the contexts they use as shown in above snippet. For example, "RemoteConenctionFactory" uses "java:jboss/exported" context. Once this is done, we will define users for JBOSS application server as administrator and for HORNETQ. Use add-user utility to add application users. Note: I am using UBUNTU as my dev env. However for windows it should be the same process with bat files First let us add admin user. Please find the details in below screenshot

Now let us add some application users for HORNETQ. Please find the details below

Now start the server and we will add some security to our HORNETQ. start server

type in and enter the credentials you configured for admin as mentioned above and select JMS destination from left hand menu. You should now be able to see this view with the queues which we defined

To add some security to our HORNETQ lets go to profile view by clicking on profile link on top right side on admin view and select Messaging/destination/view and select security settings and add the role permissions as shown below

This should bring us to end of configuration section. Now lets start coding our producer which is a RESTFUL web service and receives a XML order and pushes it to a queue. OrderSrvc.java
package itsvenkis.blogspot.in.rest.services;

import javax.annotation.Resource;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.MessageProducer;
import javax.jms.Queue;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.log4j.Logger;

/**
 * @author itsvenkis
 *
 */
@Path("/postOrder")
public class OrderSrvc {
 
 private final Logger log = Logger.getLogger(OrderSrvc.class);
 /*
  * Map a JNDI connection factory name.As this service is going to be in same
  * JAVA VM as JMS use "java:/ConnectionFactory". You can find this entry in JBOSS server
  * standalone-full.xml configuration file. 
  */
 @Resource(mappedName = "java:/ConnectionFactory")
 private ConnectionFactory connectionFactory;
 
 /*
  * Map the queue. Note how the queue name is defined here. This should match the context
  * of JNDI defined which is "java" namespace followed by the entry name as given in
  * standalone-full.xml configuration file.
  */
 @Resource(mappedName = "java:/queue/ticketOrderQueue")
 private Queue orderQueue;
 
 @POST
 @Consumes(MediaType.APPLICATION_XML)
 public Response postOrder(String xmlStr) throws JMSException{
  log.debug("Started processing the order....");
  Connection con = null;
  try{
   //In real world you may want to do this only once
   con = connectionFactory.createConnection();
   Session session = con.createSession(false,
     Session.AUTO_ACKNOWLEDGE);
   MessageProducer producer = session.createProducer(orderQueue);
   log.debug("starting HornetQ-JMS connection");
   con.start();
   log.debug("started HornetQ-JMS connection");
   TextMessage txtMsg = session.createTextMessage();
   txtMsg.setText(xmlStr);
   producer.send(txtMsg);
   log.debug("Sent message HornetQ-JMS to QUEUE");
  }catch(JMSException e){
   log.error("Failed to push order to the queue ", e);
  }finally{
   if(con != null){
    try{
     con.close();
    }catch(JMSException e){
     log.error("Unexpected error while trying to close the connection", e);
    }
   }
  }
  return Response.status(200).entity("Received XML").build();
 }

}

In the above web service I used @Resource annotation which is nothing but through CDI. Inorder to make CDI work one should have a beans.xml defined under WEB-INF folder. This xml will tell JBOSS to enable CDI.Noteworthy that this xml can be empty. I will add tutorials specific to CDI in the near future. For now,please find the xml below





web.xml

 
  resteasy.resources
  itsvenkis.blogspot.in.rest.services.OrderSrvc
 
 
  resteasy.servlet.mapping.prefix
  /resteasy
 
 
  
   org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
 
 
  resteasy
  
   org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
 
 
  resteasy
  /resteasy/*
 


pom.xml

  4.0.0
  in.itsvenkis.blogspot
  JMS-flight-booking
  0.0.1-SNAPSHOT
  war
  
  jms-flight-booking
  
  Simple application to understand RESTEasy,Hornet Q
  
   
      jboss
      http://repository.jboss.org/maven2
   
   
   
   
    org.jboss.resteasy
    resteasy-jaxrs
    3.0.0.Final
   
   
 org.jboss.resteasy
 resteasy-jaxb-provider
 3.0.0.Final
 
 
 org.jboss.spec.javax.jms
 jboss-jms-api_1.1_spec
 1.0.1.Final
 
 
 log4j
 log4j
 1.2.17
 
  


Now build,deploy and start your server. We will restful mozilla plugin to post XML file to our URL

To check if the message has reached our "ticketOrderQueue" go to admin view in the JBOSS server and goto JMS view. You should be able to see messages in queue count as one

Now lets code a simple consumer class which will have a main method
package itsvenkis.blogspot.in.example.consumer;

import java.util.Properties;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.Destination;
import javax.jms.MessageConsumer;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.Context;
import javax.naming.InitialContext;

public class JMSConsumerExample {
 /*
  * for a remote client use RemoteConnectionFactory JNDI which will be defined in standalone-full.xml
  * configuration file
  */
 private static final String DEFAULT_CONNECTION_FACTORY = "jms/RemoteConnectionFactory";
 //Queue name as mentioned in standalone-full.xml under 
 private static final String DEFAULT_DESTINATION = "jms/queue/ticketOrderQueue";
 private static final String DEFAULT_USERNAME = "jmsadmin";
 private static final String DEFAULT_PASSWORD = "*****";
 private static final String INITIAL_CONTEXT_FACTORY = "org.jboss.naming.remote.client.InitialContextFactory";
 private static final String PROVIDER_URL = "remote://localhost:4447";

 public static void main(String[] args) throws Exception {
  ConnectionFactory connectionFactory = null;
  Connection connection = null;
  Session session = null;
  MessageConsumer consumer = null;
  Destination destination = null;
  TextMessage message = null;
  Context context = null;
  try {
   final Properties env = new Properties();
   env.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
   env.put(Context.PROVIDER_URL,
     System.getProperty(Context.PROVIDER_URL, PROVIDER_URL));
   env.put(Context.SECURITY_PRINCIPAL,
     System.getProperty("username", DEFAULT_USERNAME));
   env.put(Context.SECURITY_CREDENTIALS,
     System.getProperty("password", DEFAULT_PASSWORD));
   context = new InitialContext(env);
   String connectionFactoryString = System.getProperty(
     "connection.factory", DEFAULT_CONNECTION_FACTORY);
   connectionFactory = (ConnectionFactory) context
     .lookup(connectionFactoryString);
   String destinationString = System.getProperty("destination",
     DEFAULT_DESTINATION);
   destination = (Destination) context.lookup(destinationString);
   connection = connectionFactory.createConnection(
     System.getProperty("username", DEFAULT_USERNAME),
     System.getProperty("password", DEFAULT_PASSWORD));
   session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
   consumer = session.createConsumer(destination);
   connection.start();
   message = (TextMessage) consumer.receive(10000);
   System.out.println("Received message " + message.getText());
  } catch (Exception e) {
   System.out.println(e.getMessage());
   throw e;
  } finally {
   if (context != null) {
    context.close();
   }
   if (connection != null) {
    connection.close();
   }
  }
 }
}

Run the application and you should be able to see this output now

Project directory structure

Project dependencies
This brings us to the end of this tutorial!!!!
Dear Readers, kindly like us on facebook

Friday, August 23, 2013

RESTEasy XML marshalling and unmarshalling examples


Many enterprise applications use Marshalling and unmarshalling i.e. XML to POJO and POJO to XML. This tutorial will try show how to do Marshalling and unmarshalling using JAXB and RESTEasy.
Technologies used
  1. JAVA
  2. RESTEasy
  3. JAXB
  4. JBOSS eap 6.1
  5. Maven
As an example let us try to convert XML to Java object and Java object to XML. This is how our simple order.xml looks like
 

Mumbai

300

f238
OR908765


Now let us declare our domain objects to represent this XML
order.java
 
package itsvenkis.blogspot.in.domain;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

/**
 * @author itsvenkis
 *
 */
@XmlRootElement(name ="order")
public class Order {
 
 private String flightNumber;
 private String orderId;
 private String source;
 private String destination;
 private Flight flight;
 
 public Flight getFlight() {
  return flight;
 }
 
 @XmlElement
 public void setFlight(Flight flight) {
  this.flight = flight;
 }

 public String getFlightNumber() {
  return flightNumber;
 }
 
 @XmlElement
 public void setFlightNumber(String flightNumber) {
  this.flightNumber = flightNumber;
 }
 public String getOrderId() {
  return orderId;
 }
 @XmlElement
 public void setOrderId(String orderId) {
  this.orderId = orderId;
 }
 public String getSource() {
  return source;
 }
 @XmlElement
 public void setSource(String source) {
  this.source = source;
 }
 public String getDestination() {
  return destination;
 }
 @XmlElement
 public void setDestination(String destination) {
  this.destination = destination;
 }
}
Flight.java
package itsvenkis.blogspot.in.domain;

import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;

/**
 * @author itsvenkis
 *
 */
public class Flight {
 
 private String flightMaker;
 private String flightType;
 private int flightAge;
 
 public int getFlightAge() {
  return flightAge;
 }
 
 @XmlElement
 public void setFlightAge(int flightAge) {
  this.flightAge = flightAge;
 }
 @XmlAttribute
 public String getFlightMaker() {
  return flightMaker;
 }
 public void setFlightMaker(String flightMaker) {
  this.flightMaker = flightMaker;
 }
 
 @XmlAttribute
 public String getFlightType() {
  return flightType;
 }
 public void setFlightType(String flightType) {
  this.flightType = flightType;
 }
}

Now this is how our RESTEasy service class will look like OrderSrvc.java
package itsvenkis.blogspot.in.rest.services;

import itsvenkis.blogspot.in.domain.Flight;
import itsvenkis.blogspot.in.domain.Order;

import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("/getOrder")
public class OrderSrvc {
 
 @GET
 @Produces("application/xml")
 public Order getOrder(){
  Order order = new Order();
  order.setDestination("Mumbai");
  order.setFlightNumber("f238");
  order.setOrderId("OR908765");
  Flight flight = new Flight();
  flight.setFlightMaker("BOEING");
  flight.setFlightType("COMMERCIAL");
  flight.setFlightAge(300);
  order.setFlight(flight);
  return order;
 }
 
 @POST
 @Consumes(MediaType.APPLICATION_XML)
 public Response postOrder(Order order){
                //Its crime to use System.out.println . Use loggers instead
  System.out.println(order.getDestination());
  return Response.status(200).entity("Received XML").build();
 }

}
Now lets go ahead and define our web.xml and pom.xml
web.xml

 
  resteasy.resources
  itsvenkis.blogspot.in.rest.services.OrderSrvc
 
 
  resteasy.servlet.mapping.prefix
  /resteasy
 
 
  
   org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
 
 
  resteasy
  
   org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
 
 
  resteasy
  /resteasy/*
 


pom.xml

  4.0.0
  in.itsvenkis.blogspot
  flight-booking
  0.0.1-SNAPSHOT
  war
  JBOSS-EXAMPLES
  Simple application to understand RESTEasy,Hornet Q
  
   
      jboss
      http://repository.jboss.org/maven2
   
   
   
   flightbooking
   
   
   
    org.jboss.resteasy
    resteasy-jaxrs
    3.0.0.Final
   
   
 org.jboss.resteasy
 resteasy-jaxb-provider
 3.0.0.Final
 
  


Now biuld, deploy and start the server

After starting the server, try this URL

Now lets try to convert XML to Java object. I used REST client firefox plugin to post XML. Do remember to add request header for content type before posting XML

This brings us to the end of the tutorial. I will post more examples on RestEasy, HornetQ, and JBOSS in the future. If you want any specific tutorial let me know in the comments section.
Dear Readers, kindly like us on facebook to see whats happening on this blog

Friday, August 16, 2013

RESTful WEB SERVICES and RESTFul JAVA with RESTEasy


A simple RESTEasy Helloworld example
Technologies used
  1. Maven
  2. JBOSS AS
  3. RESTEasy
First let us take a look at the pom.xml

  4.0.0
  in.itsvenkis.blogspot
  resteasy-examples
  0.0.1-SNAPSHOT
  war
  jboss-resteasy
  Rest easy tutorials
  
  resteasyTutorials
  
  
   
      jboss
      http://repository.jboss.org/maven2
   
  
      
          org.jboss.resteasy
          resteasy-jaxrs
          3.0.0.Final

web.xml
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
    version="3.0">
    
        resteasy.resources
        itsvenkis.blogspot.in.resteasy.examples.HelloWorldService
    
    
        resteasy.servlet.mapping.prefix
        /resteasy
    
    
        
            org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
    
    
        resteasy
        
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
    
    
        resteasy
        /resteasy/*
    
Service class
package itsvenkis.blogspot.in.resteasy.examples;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;

@Path("/helloworld")
public class HelloWorldService {

    @GET
    @Path("/{param}")
    public Response greetUser(@PathParam("param") String name) {
        return Response.status(200).entity("Hello World " + name).build();
    }
}
 
Now build and deploy the war file and start your server and try this url http://localhost:8080/resteasyTutorials/resteasy/helloworld/nandu
I will post more tutorials on RESTEasy, Hornet Q, JBOSS,CDI..... in the future
Dear Readers, kindly like us on facebook to see whats happening on this blog