Sunday, July 06, 2014

How to print documents using Java ? How to use PJL or Ghostscript with Java for Printing ?

In this article we will be discussing the below listed topics.
  • How to print documents using Java ?
  • How to use PJL (Print job language) commands to send instructions to printer ?
  • How to use Ghostscript commands to send instructions to printer ?
  • How to staple or duplex print documents using printer in Java ?
  • Print pdf's using java.
  • How to check the printer properties using java ?
  • How to select media tray using java on the printer ?
  • How to staple documents on a printer using java code ?
  • Print PDF using PrinterJob in java
  • Print pdf in network printer using java
  • java printing - printing a pdf 
  • Using Java to Print PDF Documents
  • Printing PDF files from Java
  • How to print PDF files using java print API ? 
  • Use Printing Service in Java.
  • Working with Print Services and Attributes.


I had to work on  printing pdf documents and had some special requirements where in few documents were supposed to use one type of paper 
compared to other set of documents. Basically we wanted to control Tray selection during printing.
The plain java api though has commands to set printer trays I guess the driver did not support or am not sure of the exact reason but I couldn't do it within java.
So had to use some PJL commands and Ghost script to get this done with rest of the stuff in JAVA


Here is some sample code Which Prints the media trays for Default printer or can read a different printer as input and prints its attributes. Then displays all tray available and will ask user the tray to select Then will print an empty page for testing targeting that Tray number..


package com.rama.print.test;

import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;

import javax.print.Doc;
import javax.print.DocFlavor;
import javax.print.DocPrintJob;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.SimpleDoc;
import javax.print.attribute.AttributeSet;
import javax.print.attribute.HashAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.Media;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.PrinterName;

/**
 * @author TWreddy
 *
 * Prints the media trays for Default printer or can read a different printer as input and prints its attributes. 
 * Then display all tray available and will ask user the tray to select 
 * Then will print an empty page for testing targeting that Tray number..
 */
public class TestMyPrinter   {
 public static void main(String args[])throws Exception {
  printAllPrinters();
  System.out.println(" -----------------------------------------------------------");
  System.out.println(" Above is the list of printers accessible from your machine.");
  System.out.println(" -----------------------------------------------------------");
  System.out.println(" ");
  System.out.println(" ");
  // get default printer
  PrintService defaultPrintService = PrintServiceLookup.lookupDefaultPrintService();

  // suggest the use of the default printer
  
  System.out.println("Enter the printer name or press enter for default printer which is: ["+ defaultPrintService.getName() + "]?" );
  System.out.println("");
  
  // read from the console the name of the printer
   BufferedReader bufferRead = new BufferedReader(new InputStreamReader(System.in));
   String printerName = bufferRead.readLine();

  
  // if there is no input, use the default printer
  if (printerName == null || printerName.equals("")) {
   printerName = defaultPrintService.getName();
  }

  // the printer is selected
  AttributeSet aset = new HashAttributeSet();
  aset.add(new PrinterName(printerName, null));
  // selection of all print services
  PrintService[] services =            PrintServiceLookup.lookupPrintServices(null,aset);
  Map<Integer, Media> trayMap = getAvailableTraysOnPrinter(services);

  
  System.out.println("Select tray target id : " +"\n");
  String mediaId = bufferRead.readLine();

  MediaTray selectedTray = (MediaTray) trayMap.get(Integer.valueOf(mediaId));
  System.out.println("Selected tray : " + selectedTray.toString() +"\n");

  System.out.println("Do you want to print a test page? [y/n] \n");
  
  String printPage = bufferRead.readLine();
  
  if (printPage.equalsIgnoreCase("Y")) {
   printDoc(services, selectedTray);
  }
  
  System.out.println(" Completed.");
 }

 /**
  *  Prints an empty document based on Tray you selected.
  * or you can print a pdf 
  * or you can output the contents that was sent to printer to another file for debugging.
         *  Comment or uncomment the code below depending on whether you want to test prniting 
         *  empty document (useful to test printer and  you dont want to waste paper)
         *  or print a actual document or want to see what content is exactly being sent to printer.
  * @param services
  * @param selectedTray
  */
 private static void printDoc(PrintService[] services,MediaTray selectedTray) {
  // we have to add the MediaTray selected as attribute
  

  
  
  // we create the printer job, it print a specified document with a
  // set of job attributes
  //DocPrintJob printJob = filePrinter.getPrintService().createPrintJob();
  DocPrintJob job = services[0].createPrintJob();

  
  try {
   System.out.println("Trying to print an empty page (Or uncomment code to Print PDF) on Media Tray: "+ selectedTray.toString());
   
   System.out.println(" Media tray selection only works for documents thats created on the fly . See PrintableDemo class below.");
   System.out.println(" For documents like pdf, word, text files...etc... I had to use Ghostscript and to that document add @PJL commands.");
   
   
   
   // we print using the selected attributes which is paper tray.
   //SET PRINTER PROPERTIES
   /* This approach works only for CASE1 and CASE3  described below . */
   PrintRequestAttributeSet attributes = new HashPrintRequestAttributeSet();
   attributes.add(selectedTray);
   
   
   
 //CASE1: SIMPLE TEST where we try to print a document created on the fly with a simple String
 // we create a document that implements the printable interface . 
 // I just passed selectedTray so that if required print that on the paper for testing.
  Doc doc = new SimpleDoc(new PrintableDemo(selectedTray),DocFlavor.SERVICE_FORMATTED.PRINTABLE, null);
   
   
   
   
 //CASE2: TEST with actual documents . Here the tray selection doesnt work.
 /*  Somehow when I am using a PDF though I select tray 2 its sending to Tray1.
    But this same code when invoked with empty doc works ???
 NOTE: After quite testing I noticed that when we print a document the entire binary is sent 
   Directly to printer with no PCL commands for tray info or stapling etc... 
   In case of
 */
   
   //InputStream inputStream = new FileInputStream("C://coverPage.pdf");
   //InputStream inputStream = new FileInputStream("C://other.pdf");
   //InputStream inputStream = new FileInputStream("C://other.docx");
   //Doc doc = new SimpleDoc(inputStream, DocFlavor.INPUT_STREAM.AUTOSENSE ,null);
   
   
   
 //CASE3: Use ghost script and modify the pdf to ps file and to that add any PCL commands.
 //So that you can control tray selection , duplex printing, stapling and what not..
 //File psFile = modifyDocumentUsingGhostScriptAndPrint( new File("C://coverPage.pdf"));
 //InputStream inputStream = new FileInputStream(psFile);
 //Doc doc = new SimpleDoc(inputStream, DocFlavor.INPUT_STREAM.AUTOSENSE ,null);
 
   
  /** 
   * Want to see what you really sent to printer ??
   * 
   * PRINT TO FILE
   * You want to see what exactly is being sent to printer un comment this code
   * and it will write the entire Stream to a flie (which is want Printer would have received) 
  **/
   //File outputFile = new File("C://ContentSentToPrinter.txt");
   //attributes.add(new Destination(outputFile.toURI()));
   
   
   job.print(doc, attributes);
   
   System.out.println(" Done processing ......");
  } catch (Exception e) {
   e.printStackTrace();
  }
 }

/**
  *  Transforms the PDF file to Post script 
  *  and as a demo adds 
  *  - PJL commands to Print a particular tray
  *  - Adds PS commands to staple or duplex print.
  *  
  *   Bottom line you can add much more stuff... Just showing what all can be done..
  *   
  */
 public static File modifyDocumentUsingGhostScriptAndPrint(File pdfFile)throws Exception{
  File psFile = null;
  psFile = PostScriptConversion.convertToPS(pdfFile);
  PostScriptConversion.addAddtionalCommandsForPSFile(psFile);
  if(psFile == null){
   System.err.println(" Oops PS conversion didnt yeild us anything.");
   throw new RuntimeException(" Oops PS conversion didnt yeild us anything.");
  }
  return psFile; 
 } 
 
 
 
 
 private static Map<Integer, Media> getAvailableTraysOnPrinter(PrintService[] services) {
  // We store all the trays in a map
  Map<Integer, Media> trayMap = new HashMap<Integer, Media>(10);

  //We chose something compatible with the printable interface
  DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
  //

  for (PrintService service : services) {
   System.out.println(service);

   // we retrieve all the supported attributes of type Media
   // we can receive MediaTray, MediaSizeName, ...
   Object o = service.getSupportedAttributeValues(Media.class, flavor, null);
   if (o != null && o.getClass().isArray()) {
    for (Media media : (Media[]) o) {
     // we collect the MediaTray available
     if (media instanceof MediaTray) {
      System.out.println(" Use id number :"+ media.getValue() + "  For accessing: " + media + " - " + media.getClass().getName());
      trayMap.put(media.getValue(), media);
     }
    }
   }
  }
  return trayMap;
 }
 
 
 private static void printAllPrinters() {
  PrintRequestAttributeSet printRequestAttributes = new HashPrintRequestAttributeSet();
   //  printRequestAttributes.add(OrientationRequested.LANDSCAPE);
   //  printRequestAttributes.add(Sides.DUPLEX);
   //  printRequestAttributes.add(MediaSizeName.ISO_A4);
   //     printRequestAttributes.add(Finishings.STAPLE);
  PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, printRequestAttributes);
  for(PrintService printService :printServices){
   System.out.println(printService +" Name to use="+ printService.getName());
  }
 }
 
 
 private static void printPrinterProperties(String printName){
  AttributeSet aset = new HashAttributeSet();
  aset.add(new PrinterName(printName, null));
  PrintService[] services = PrintServiceLookup.lookupPrintServices(null, aset);
  for (int i = 0; i < services.length; i++) {
    PrintService service = services[i];
    System.out.println(service);
    //DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PAGEABLE;
    DocFlavor flavor = DocFlavor.SERVICE_FORMATTED.PRINTABLE;
    Object attributes = service.getSupportedAttributeValues(Media.class, flavor, null);
    if (attributes != null && attributes.getClass().isArray()) {
      for (Media media : (Media[]) attributes) {
        System.out.println(media + " ID: " + media.getValue() + "\t" + media.getClass().getName());
        /* if(media instanceof sun.print.Win32MediaTray){
         Win32MediaTray  win32Tray = (Win32MediaTray)media;
         System.out.println(win32Tray.winID);
        }*/
        
      }
    }
  }
  
 }
 
}
Here is the printable demo class that you can use to print empty document. This will be usefull when testing printer and tray selection within the printer that way you can you same sheet of paper again and again.

package com.rama.print.test;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.print.PageFormat;
import java.awt.print.Printable;

import javax.print.attribute.standard.MediaTray;
/**
 * 
 * To print a page just on the fly without reading physical document.
 * good for testing 
 * @author TWreddy
 *
 */
public class PrintableDemo implements Printable {
 
 MediaTray selectedTray = null;
 public PrintableDemo(MediaTray trayToUse){
  selectedTray = trayToUse;
 }
 
 
 @Override
 public int print(Graphics pg, PageFormat pf, int pageNum) {
  
  //The printing system will call the Printable.print()  until we return NO_SUCH_PAGE
  if (pageNum > 0){
   //First time pageNum = 0...
   System.out.println("PrintableDemo.print pageNum="+ pageNum);
   return Printable.NO_SUCH_PAGE;
  }
  
  
  //User (0,0) is typically outside the imageable area, so we must translate
     // by the X and Y values in the PageFormat  to avoid clipping.
     Graphics2D g2d = (Graphics2D)pg;
     g2d.translate(pf.getImageableX(), pf.getImageableY());

     
     //For testing SAVE paper by setting messagOnDoc=""; that way only empty paper will get pulled from Tray with nothing being printed.   
     String messagOnDoc = "Hello  Your tray number was="+ this.selectedTray.getName() +" : "+this.selectedTray.getValue();
     // Now we perform our rendering
     pg.drawString(messagOnDoc, 100, 100);

     // tell the caller that this page is part
     // of the printed document
     return PAGE_EXISTS;
     
 }
}

Here is the code for Converting a PDF document to PostScript.
And in addition we can additional post script commands and also PJL commands
eg: for Duplex printing, Stapling of documents if printer supports.
The assumption is you Ghost script installed on your local.

package com.rama.print.test;

import java.io.BufferedReader;
import java.io.EOFException;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.io.PrintWriter;

import org.apache.commons.io.FileUtils;

/**
 * @author TWreddy
 * Convert a PDF document to PostScript.
 * And in addtion we can additional post script commands and also PJL commands 
  * eg: for Duplex printing, Stapling of documents if printer supports.
 */
class PostScriptConversion extends Thread {
 
 //NOTE: To see how PJL looks print a document (withou ot java code)  and while doing 
 //Say print to file (its that check box on the print properties window). 
 // Which means you are exporting the entire document with all PJL commands 
 // that would have been sent to printer otherwise. 
 
 //ESC%-12345X@PJL is start of print job language.
 private static String PJL_START = String.valueOf((char) 27) + "%-12345X@PJL";
 private static String PJL_END = String.valueOf((char) 27) + "%-12345X";
 private static String PJL_POSTSCRIPT = "@PJL ENTER LANGUAGE = POSTSCRIPT";
 private static String PJL_COMMAND_TO_SELECT_PRINT_TRAY = "@PJL SET MEDIASOURCE = TRAY2";
 
 private static String POST_SCRIPT_COMMAND_FOR_DUPLEX_PRINTING = "<< /Duplex true >> setpagedevice";
  
 
 boolean isRunning;
 String command = null;
 Process process = null;
 int exitVal = -1;
 boolean processingComplete;
 
 public PostScriptConversion( String command) {
  this.command = command;
 }

 public void run() {
  try {
   System.out.println("executing: " + command);
   process = Runtime.getRuntime().exec(command);

   // Spawn thread to read output of spawned program  --  
   new Thread() {
    public void run() {
     this.setName("Process-InputStream");
     // hook into output from spawned program
     final InputStream is = process.getInputStream();
     final InputStreamReader isr = new InputStreamReader(is);
     final BufferedReader br = new BufferedReader(isr, 100);
     String line;
     try {
      try {
       while ((line = br.readLine()) != null) {
        System.out.println(line);
       }
      } catch (EOFException e) {
      }
      br.close();
     } catch (IOException e) {
      System.err.println("problem reading spawn output" + e.getMessage());
     }
     // returning from run kills the thread.
    }
   }.start();

   // Spawn thread to read output of spawned program -- Error Stream
   new Thread() {
    public void run() {
     this.setName("Process-ErrorStream");
     // hook into output from spawned program
     final InputStream is = process.getErrorStream();
     final InputStreamReader isr = new InputStreamReader(is);
     final BufferedReader br = new BufferedReader(isr, 100);
     String line;
     try {
      try {
       while ((line = br.readLine()) != null) {
        System.out.println(line);
       }
      } catch (EOFException e) {
      }
      br.close();
     } catch (IOException e) {
      System.err.println("problem reading spawn output" + e.getMessage());
     }
     // returning from run kills the thread.
    }
   }.start();

   // Wait for Ghost Script to complete.
   System.out.println("waiting for command to finish ....");
   exitVal = process.waitFor();
   System.out.println("exitValue: " + exitVal);

   processingComplete = true;
   process = null;
   System.out.println("PostConversion.run(): Done converting ");
   
  } catch (Exception e) {
   System.err.println("incomplete:"+ e);
  }
 }
 
 
 
 public static File convertToPS(File pdfFile) {
  String pdfFilePath = pdfFile.getAbsolutePath();
  String pdfFileName = pdfFile.getName();
  String psFileName = pdfFileName.substring(0, pdfFileName.indexOf(".pdf")) + ".ps";
  String psFilePath = "C:\\Temp\\"+ "\\" + psFileName;

  StringBuffer command = new StringBuffer("C:/Progra~1/gs/gs8.61/bin/gswin32c.exe");
  command.append(" -q -sOutputFile#");
  command.append("\"");
  command.append(psFilePath);
  command.append("\"");
  command.append(" -dNOPAUSE -dBATCH -dSAFER -sDEVICE=pswrite ");

  command.append("\"");
  command.append(pdfFilePath);
  command.append("\"");
  
  try {

   PostScriptConversion conversionThread = new PostScriptConversion(command.toString());
   conversionThread.setName("PostConversion");
   conversionThread.start();
   try {
    //Set timeout for PS conversion. Best is to externalize.. for testing read directly.
    Thread.sleep(100000);
   } catch (Exception ex) {
    ex.printStackTrace();
   }

   if (!conversionThread.processingComplete) {
    if (conversionThread.process != null) {
     File psFile = new File(psFilePath);
     if (psFile.exists()) {
      conversionThread.process.destroy();
      conversionThread.process = null;
      System.err.println("Killed process.");
     }
    }
   }

   System.out.println(" Return value from PS conversion " + conversionThread.exitVal);

   if (conversionThread.exitVal != 0) {
    return null;
   }

   return new File(psFilePath);
  } catch (Exception e) {
   System.err.println("Error converting to PS: " + psFilePath +" ExP:"+ e);
  }
  return null;
 }
 
 
 
 
 /**
  * 
  * This method adds Printer Job Language (PJL) as well as postscript commands to achieve desired finishing on the final output.
  * 
  * PJL commands will follow the structure
  * 
  * 1. PJL directive to indicate this is a PJL command stream 
  * 2. Any number of PJL commands there after  
  * 3. PJL command to set language to postscript eg: @PJL ENTER LANGUAGE = POSTSCRIPT or  @PJL ENTER LANGUAGE = PCLXL 
  * 4. the actual postscript with any additional  modifications 
  * 5. PJL directive to indicate the end of the PJL job
  * 
  * so basically we are adding PJL commands on top and embedding the postscrip output which is the 
  * original pdf  wrapped between PJL start and end Commands.
  * 
  * @param psFile
  * @throws IOException
  */
 public static void addAddtionalCommandsForPSFile(File psFile) throws IOException {

  File tempPSFile = new File(psFile.getPath() + "_upd");
  PrintWriter pw = null;
  FileReader fr = null;
  try {
   pw = new PrintWriter(tempPSFile);
   fr = new FileReader(psFile);

   // Begin the PJL job
   pw.println(PJL_START);
   //ANY PJL commands will go here 
   pw.println(PJL_COMMAND_TO_SELECT_PRINT_TRAY);
   //pw.println();  More PJL commands.
   //pw.println();  More PJL commands.
   //set the language back to postscript
   pw.println(PJL_POSTSCRIPT);
   
   //Now read inout Post script file to modify any commands on the fly as we read.
   LineNumberReader lnr = new LineNumberReader(fr);
   String line = lnr.readLine();
   pw.println(line); //copy  the first line from PS file...
   pw.println(POST_SCRIPT_COMMAND_FOR_DUPLEX_PRINTING); //Add Post Script command for duplex prining
   //pw.println(); //More PS commands (NOT PJL)
   
   line = lnr.readLine();
   int endPageFindCount = 0;
   int scaleFindCount = 0;
   while (line != null) {
    if (line.equalsIgnoreCase("%%EndPageSetup")) { //Count each page if you want...
     endPageFindCount++;
     pw.println("0 100 translate"); 
     pw.println(line);
    } else if (line.equalsIgnoreCase("0.1 0.1 scale")) {
     scaleFindCount++;
     pw.println("0.1 0.099 scale"); //Adjust scaling in Post script if you want. 
    } else {
     pw.println(line); //else just copy to the other file.
    }
    line = lnr.readLine();
   }

   // end the PJL job
   pw.println(PJL_END);

   System.out.println("Processing PS results: endPageFindCount: " + endPageFindCount + "  scaleFindCount: " + scaleFindCount);

  } catch (Exception e) {
   // TODO: handle exception
   System.err.println(e.getMessage()+":" +e);
  } finally {
   if (pw != null) {
    pw.close();
   }
   if (fr != null) {
    fr.close();
   }
  }

  FileUtils.forceDelete(psFile);
  FileUtils.copyFile(tempPSFile, psFile);
  FileUtils.forceDelete(tempPSFile);

 }
}

This above code should provide you enough  java code to print all print services on any given machine, modify a document to add any ghost script commands or PJL commands to control printer in a way at times we may not be able to do using Pure java code.





Using an MDB (Message-Driven Bean) - JBoss EAP 6.0 or JBOSS 7


The following topic are covered in this article.
  • MDBs are slowly dying in JBoss EAP
  • MDB in JBoss EAP will not reconnect to remote JMS provider after restarting  the message server
  • How to configure MDB's in JBOSS EAP 6 ?
  • How to deploy MDBS in Jboss EAP 6 ?
  • Configuring Message-Driven Beans
  • JBoss MDB 3.0 - EJB 3 - JBoss application server tutorial
  • Working MDB example in JBoss 7.0.1
  • Helloword Using an MDB (Message-Driven Bean) - JBoss EAP 6.0 or JBOSS 7
  • Java code to send messages to MDB or Sending messages to an MDB


Here is some some sample MDB's that I created to  tests on EAP 6  or JBOSS 7 
During the testing process we noticed that sometime MDBS would loose connection with message server and would never reconnect again.
Also whenever we re start message server all mdb's would loose communication with message server and would never re-establish connection..
To fix we need to add few additional properties as shown below and there is brief description as why we need each of that property.


@ActivationConfigProperty(propertyName = "clientFailureCheckPeriod", propertyValue = "600000"),
@ActivationConfigProperty(propertyName = "connectionTTL", propertyValue = "-1")

  Inspect the network for any issues that might cause clients to become disconnected from the server. 
   Consider adjusting the <connection-ttl> (default is 60000ms) and <check-period> (default is 30000ms) 
   on the appropriate JMS connection factory. If network latency is the problem then increasing 
   these values will help mitigate this issue.

   To be clear, the "clientFailureCheckPeriod" can be any number > 0. 
   The value "600000" equates to 10 minutes which seems reasonable (the default is 30 seconds).
   The connection-ttl determines how long the server will keep a connection alive in the 
       absence of any data arriving from the client. The client will automatically send "ping" 
        packets periodically to prevent the server from closing it down. If the server doesn't receive 
any packets on a connection for the connection TTL time,
then it will automatically close all the sessions on the server that relate to that connection.


@ActivationConfigProperty(propertyName="reconnectAttempts", propertyValue="-1"),
@ActivationConfigProperty(propertyName="reconnectInterval", propertyValue="-1")

Please note that one can also adjust the "reconnectInterval" which  controls how long to wait 
between reconnection attempts (the value is in  seconds and is 10 by default).
The "reconnectAttempts" and "reconnectInterval" can also be set through the MDB's 
ejb-jar.xml or globally for all MDBs through ejb3-interceptors-aop.xml 
as demonstrated with the "maxSession" property in Configure maximum JMS sessions for EJB3 MDB in JBoss EAP

Lets show this with an example. The assumption here is you have a queue manager configured in your jboss stand-alone.xml and you have queue named 
"RAMA.TEST.QUEUE".

So lets call your queue manager name as "LOCAL_QUEUE_MANAGER"


NOTE: see this link for more on jms configuration using hornet queue as provider for JBOSS eap 6. 
http://www.mastertheboss.com/jboss-jms/jboss-jms-configuration. 
So lets get into how we can create an MDB and will use a sample test client.

So basically this queue manager will have an entry in your stand-alone.xml something similar to this 


Connection Factory looks like :
==============================
NOTE: Here netty-remote is pointing to one of our remote message servers.

 <jms-connection-factories>
 ....
 .....
    <pooled-connection-factory name="LOCAL_QUEUE_MANAGER">
<user>rama</user>
<password>tests123</password>
<transaction mode="xa"/>
<connectors>
   <connector-ref connector-name="netty-remote"/>
</connectors>
<entries>
   <entry name="java:/LOCAL_QUEUE_MANAGER"/>
</entries>
    </pooled-connection-factory>
 </jms-connection-factories>

Queue config looks like  below in your stand-alone.xml or domain.xml:
==================================================================

<jms-destinations>
    <jms-queue name="RAMA.TEST.QUEUE">
<entry name="java:jboss/exported/jms/queue/RAMA.TEST.QUEUE"/>
<entry name="jms/queue/RAMA.TEST.QUEUE"/>
<durable>true</durable>
    </jms-queue>
......
.......
 </jms-destinations>

Now create and EJB project in your eclipse or Intellij and use the below code.

/**
 *  My test mdb
 */
package com.rama.tst.mdb;
import java.util.Date;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.MessageDriven;
import javax.ejb.TransactionManagement;
import javax.ejb.TransactionManagementType;
import javax.jms.Message;
import javax.jms.MessageListener;
import org.jboss.ejb3.annotation.ResourceAdapter;
@TransactionManagement(TransactionManagementType.CONTAINER)
@ResourceAdapter("LOCAL_QUEUE_MANAGER")
@MessageDriven(messageListenerInterface = MessageListener.class, activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "RAMA.TEST.QUEUE"),
@ActivationConfigProperty(propertyName = "clientFailureCheckPeriod", propertyValue = "600000"),
@ActivationConfigProperty(propertyName = "connectionTTL", propertyValue = "-1"),
//************************* RECONNECT PARAMETERS  **************************@ActivationConfigProperty(propertyName="reconnectAttempts", propertyValue="-1"),
@ActivationConfigProperty(propertyName="reconnectInterval", propertyValue="-1")})
public class TestMDB extends TestAbstractMDB {
private static final long serialVersionUID = 1231L;
public TestMDB(){
System.out.println(" ******************** New MDB obj was created at "+ new Date());
System.out.println(" ********************  New MDB obj "+ this.toString());
}
public void consumeMessage(Message message) {
String messageStr = "";
try {
messageStr = JMSUtil.getMessageAsString(message);
System.out.println("====== We received your message at "+ new Date() + " ======" );


} catch (Throwable t) {
t.printStackTrace();
} finally {
}
}
}
where TestAbstractMDB is the super class which has some basic methods.

package com.rama.tst.mdb;
import javax.ejb.EJBException;
import javax.ejb.MessageDrivenBean;
import javax.ejb.MessageDrivenContext;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
/** * * @author twreddy Parent with some common methods dumped here. * */ public abstract class AbstractMDB implements MessageDrivenBean,MessageListener { private static final Logger logger = LogManager.getLogger(AbstractMDB.class); public static final long serialVersionUID = 123; private MessageDrivenContext context; /** * @return the context */ public MessageDrivenContext getContext() { return this.context; } /** * @param context * the context */ public void setContext(MessageDrivenContext context) { this.context = context; } public void ejbCreate() { } public void setMessageDrivenContext(MessageDrivenContext newContext) throws EJBException { this.context = newContext; }
public void onMessage(Message message) { this.logMessageProperties(message); try { this.consumeMessage(message); } catch (Exception e) { } } /** * Logs JMS Properties extracted from the JMS Message * @param message the JMS message */ protected final void logMessageProperties(Message message) { try { this.logger.debug("Received Message:"); this.logger.debug("JMSMessageID :" + message.getJMSMessageID()); this.logger.debug("JMSXDeliveryCount:" + message.getIntProperty("JMSXDeliveryCount"));//Optional property this.logger.debug("CorrelationID :" + message.getJMSCorrelationID()); this.logger.debug("JMSDeliveryMode :" + message.getJMSDeliveryMode()); this.logger.debug("JMSDestination :" + message.getJMSDestination()); this.logger.debug("JMSExpiration :" + message.getJMSExpiration()); this.logger.debug("JMSPriority :" + message.getJMSPriority()); this.logger.debug("JMSRedelivered :" + message.getJMSRedelivered()); this.logger.debug("JMSReplyTo :" + message.getJMSReplyTo()); this.logger.debug("JMSTimestamp :" + message.getJMSTimestamp()); this.logger.debug("JMSType :" + message.getJMSType()); } catch(JMSException e){ this.logger.info("An error occurred while extracting JMS Properties from the message", e); } } /** * ejbRemove */ public void ejbRemove() { logger.debug("AbstractMDB: inside MDB ejbRemove" + this); } public abstract void consumeMessage(Message message); /** * Reads correlattion from jms message if null checks for message id * * @param message * @return * @throws JMSException */ public String getCorrelationId(Message message) throws JMSException { String correlationId = message.getJMSCorrelationID(); logger.debug("correlationId =" + correlationId); if ((correlationId == null) || (correlationId.trim().length() == 0)) { logger.debug("correlationId is null. Stamping incoming message id as correlation id.="+ correlationId); correlationId = message.getJMSMessageID(); } logger.debug("correlationId =" + correlationId); return correlationId; } }
And here is the Util class to extract messages as String

//And here is the Util class to extract messages as String package com.rama.tst.mdb; //Java SE dependencies import java.io.ByteArrayOutputStream; import javax.jms.BytesMessage; import javax.jms.JMSException; import javax.jms.Message; import javax.jms.StreamMessage; import javax.jms.TextMessage; /** * Provides Utility methods for JMS Messages. */ public class JMSUtil { private static final int BYTE_BUFFER_SIZE = 512; /** * Given a JMS <tt>BytesMessage</tt>, it reads the data and returns it * as a String. * @param bytesMsg the bytes message * @return the message as <code>String</code> */ public static String getBytesMessageAsString(BytesMessage bytesMsg) throws JMSException{ ByteArrayOutputStream bos = new ByteArrayOutputStream(); byte[] byteBuffer = new byte[JMSUtil.BYTE_BUFFER_SIZE]; // Read in the bytes int bytesRead = 0; while ( (bytesRead = bytesMsg.readBytes(byteBuffer)) != -1){ bos.write(byteBuffer, 0, bytesRead); //Reset byteBuffer for(int i=0; i<bytesRead; i++){ byteBuffer[i] = 0; } } return bos.toString(); } /** * Given a JMS <tt>Message</tt>, it extracts the message and returns it as String. * * @param message the jms message * @return the jms message as String * * @throws IllegalArgumentException if an invalid argument is passed * @throws Exception if an error occurs while processing */ public static String getMessageAsString(Message message)throws Exception{ if (message == null){ throw new IllegalArgumentException("Message cannot be null"); } String msgStr = null; if (message instanceof StreamMessage) { StreamMessage streamMsg = (StreamMessage) message; msgStr = streamMsg.readString(); } else if (message instanceof TextMessage) { TextMessage textMsg = (TextMessage) message; msgStr = textMsg.getText(); } else if (message instanceof BytesMessage) { BytesMessage bytesMsg = (BytesMessage) message; msgStr = JMSUtil.getBytesMessageAsString(bytesMsg); } else { throw new Exception("Unsupported message type :"+ message.getClass().getName()); } return msgStr; } }

Client to send messages to Hornet Queue or Send messages to JMS Queue or Send messages to MDB.


package com.rama.test.message; import java.io.File; import java.util.Date; import java.util.Properties; import javax.jms.Message; import javax.jms.Queue; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; import javax.jms.QueueReceiver; import javax.jms.QueueSender; import javax.jms.QueueSession; import javax.jms.TextMessage; import javax.naming.Context; import javax.naming.InitialContext; import org.apache.commons.io.FileUtils; import com.rama.tst.mdb.JMSUtil; /* A simple test client to send, delete or read messages. */ public class TestMDB { String fileName="C:/temp/message.txt"; public static String queueName = "jms/queue/RAMA.TEST.QUEUE"; public static String deleteFromQueueName = "jms/queue/RAMA.TEST.QUEUE"; public static String readFromQueueName = "jms/queue/RAMA.TEST.QUEUE"; public static String sendQueueName = "jms/queue/RAMA.TEST.QUEUE"; public static String connectionFactoryName = "jms/RemoteConnectionFactory"; public static String messageQueueUserId="rama"; public static String messageQueuePassword="tests123!"; private static final int timeout = 10000; public static void main(String[] args) throws Exception{ String message = getMessage(); //deleteAllMessagesOnQueues(); for(int i=0;i <= 1; i++){ sendMessgToMdb(message); Thread.sleep(100L); } //readMessgFromQueue(); //readAllMessgFromQueue(); //sendBulkMessages(); //System.out.println("=======Finished========"); } public static InitialContext getInitialContext()throws Exception{ Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory"); props.put(Context.PROVIDER_URL, "remote://rama-remote-desktop:4447"); props.put(Context.SECURITY_PRINCIPAL,messageQueueUserId); props.put(Context.SECURITY_CREDENTIALS,messageQueuePassword); InitialContext ic = new InitialContext(props); return ic; } public static void sendBulkMessages() throws Exception { QueueSession session = null; QueueConnection connection = null; QueueConnectionFactory queueConnFactory = null; InitialContext ic = null; try{ ic = getInitialContext(); System.out.println(ic.getEnvironment()); queueConnFactory =(QueueConnectionFactory) ic.lookup(connectionFactoryName); Queue queue = (Queue) ic.lookup(sendQueueName); System.out.println(queueConnFactory); connection = queueConnFactory.createQueueConnection(messageQueueUserId, messageQueuePassword); session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); File files[] = (new File("C:/Temp/")).listFiles(); int count=0; for(File fileName:files){ String fileStr = FileUtils.readFileToString(fileName); count++; TextMessage message = session.createTextMessage(); message.setText(fileStr); QueueSender sender = session.createSender(queue);; sender.send(message); System.out.println("Processing File:"+ fileName.getAbsolutePath()); } System.out.println("Total="+ count); }catch(Exception e){ e.printStackTrace(); } finally { session.close(); connection.close(); ic.close(); } System.out.println("Sent message"); } public static void sendMessgToMdb(String text) throws Exception { QueueSession session = null; QueueConnection connection = null; QueueConnectionFactory queueConnFactory = null; InitialContext ic = null; try{ ic = getInitialContext(); System.out.println(ic.getEnvironment()); queueConnFactory =(QueueConnectionFactory) ic.lookup(connectionFactoryName); Queue queue = (Queue) ic.lookup(sendQueueName); //We added same password for both local and Dev. System.out.println(queueConnFactory); System.out.println(queue); connection = queueConnFactory.createQueueConnection(messageQueueUserId, messageQueuePassword); session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); TextMessage message = session.createTextMessage(); message.setText(text); final QueueSender sender = session.createSender(queue); sender.send(message); }catch(Exception e){ e.printStackTrace(); } finally { session.close(); connection.close(); ic.close(); } System.out.println("Sent message"); } /* Read multiple messagea and dump it to a file. */ public static void readAllMessgFromQueue() throws Exception { Queue queue = (Queue) getInitialContext().lookup(readFromQueueName); QueueConnectionFactory factory =(QueueConnectionFactory) getInitialContext().lookup(connectionFactoryName); QueueConnection connection = factory.createQueueConnection(messageQueueUserId, messageQueuePassword); QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); QueueReceiver receiver = session.createReceiver(queue); connection.start(); while(true){ Message message = receiver.receive(timeout); if(message==null){ //throw new Exception("Timeout, no mesages returned on response queue."); break; } String payLoad = JMSUtil.getMessageAsString(message); logMessageProperties(message); System.out.println("CorrelationId:"+message.getJMSCorrelationID()); System.out.println("MessageId:"+message.getJMSMessageID()); System.out.println("Recieved message : " + payLoad); String fileName = message.getJMSMessageID().replace("ID:","")+".xml"; try{ String fullFileName = "C:/Temp/"+fileName; FileUtils.writeStringToFile(new File(fullFileName),payLoad); System.out.println(" File written to :"+ fullFileName); }catch(Exception e){ e.printStackTrace(); } } session.close(); connection.close(); System.out.println("=== Done ===="); } public static String readMessgFromQueue() throws Exception { Queue queue = (Queue) getInitialContext().lookup(readFromQueueName); QueueConnectionFactory factory =(QueueConnectionFactory) getInitialContext().lookup(connectionFactoryName); QueueConnection connection = factory.createQueueConnection(messageQueueUserId, messageQueuePassword); QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); QueueReceiver receiver = session.createReceiver(queue); connection.start(); Message message = receiver.receive(timeout); if(message==null){ throw new Exception("Timeout, no mesages returned on response queue."); } logMessageProperties(message); session.close(); connection.close(); System.out.println("CorrelationId:"+message.getJMSCorrelationID()); System.out.println("MessageId:"+message.getJMSMessageID()); System.out.println("Recieved message : " + JMSUtil.getMessageAsString(message)); return JMSUtil.getMessageAsString(message); } private static void deleteAllMessagesOnQueues() throws Exception { QueueConnectionFactory factory =(QueueConnectionFactory) getInitialContext().lookup(connectionFactoryName); QueueConnection connection = factory.createQueueConnection(messageQueueUserId, messageQueuePassword); QueueSession session = connection.createQueueSession(false, QueueSession.AUTO_ACKNOWLEDGE); //Queue queue = (Queue) getInitialContext().lookup(respQueueName); Queue queue = session.createQueue(deleteFromQueueName); QueueReceiver receiver = session.createReceiver(queue); connection.start(); int i = 0; while(true){ Message message = receiver.receive(timeout); if(message == null){ break; }else{ //System.out.println("Deleting message:"+ JMSUtil.getMessageAsString(message)); System.out.println("Deleting message:"+ i); } i++; } System.out.println(i + " messages deleted from:"+ deleteFromQueueName); session.close(); connection.close(); } public static String getMessage() throws RuntimeException{ try { return FileUtils.readFileToString(new File(fileName)); }catch(Exception e){ e.printStackTrace(); throw new RuntimeException(e); } } }

Hope this above sample code helps to setup an MDB and test with the client.