Monday, April 21, 2008

Memory Leak Detection in WAS

The below article found on developerworks explains how to detect and analyze memory leaks in Websphere Application Server using the Memory Dump Diagnostic for Java (MDD4J) tool.

Overview of memory leaks

Monday, March 24, 2008

Report Generation using Jasper

A Java develoer may often come across situations where the project demands reporting.
Thare are multiple solutions to this : You may make use of popular commercial products like BusinessObjects CrystalReports or Oracle Discoverer.

Another option is to choose Open Source Jasper Reports.

This post is all about developing reports using Jasper APIs for Java. We will also talk about the iReport, the free Jasper designer tool.


Acquiring the Jasper Engine

The latest version of Jasper Reports can be downloaded from here. And here is the direct link to download jasperreports-2.0.5 which I am using currently.

Unzip the file, and add all the jar files in the lib folder to your classpath or the Java Build Path in yor IDE inorder to work with Jasper.

Designing the Report XML (JRXML)

The Jasper engine, like any other report engine uses a report defenition file, containing the report parameter defenitions and formatting instructions, to generate the report at runtime. For Jasper, this design is an XML file, known as the JRXML.


A JRXML file is devided into different sections - title, pageheader, columnheader, detail, columnfooter, pagefooter and summary - generally used to display the title and header and footer informations. Each of these sections may have one or more bands, which are used for displaying the content. Bands contain textfields-formatting instructions and textfieldexpressions-for parameter expressions.

The parameters can be passed from the calling java class. They can also come from a resultset obtained as a result of executing a query when the report is loaded. This query and its parameter set needs to be defined in the JRXML. The database connection needs to be passed as a parameter to the Report engine. The defined parameters needs to be wrapped in a java.util.Map object and passes to the engine.

Given below, is a sample JRXML file, used to generate a small Sales Bill.


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE jasperReport PUBLIC "//JasperReports//DTD Report Design//EN" "http://jasperreports.sourceforge.net/dtds/jasperreport.dtd">
<jasperReport
name="BasicReport"
columnCount="1"
printOrder="Vertical"
orientation="Portrait"
pageWidth="595"
pageHeight="842"
columnWidth="555"
columnSpacing="0"
leftMargin="20"
rightMargin="20"
topMargin="30"
bottomMargin="30"
whenNoDataType="NoPages"
isTitleNewPage="false"
isSummaryNewPage="false"
isFloatColumnFooter="true">
<property name="ireport.scriptlethandling" value="0" />
<property name="ireport.encoding" value="UTF-8" />
<import value="java.util.*" />
<import value="net.sf.jasperreports.engine.*" />
<import value="net.sf.jasperreports.engine.data.*" />

<style
name="Arial_Normal"
isDefault="true"
fontName="Arial"
fontSize="12"
isBold="false"
isItalic="false"
isUnderline="false"
isStrikeThrough="false"
pdfFontName="Helvetica"
pdfEncoding="Cp1252"
isPdfEmbedded="false"
/>
<style
name="Arial_Bold"
isDefault="false"
fontName="Arial"
fontSize="12"
isBold="true"
isItalic="false"
isUnderline="false"
isStrikeThrough="false"
pdfFontName="Helvetica-Bold"
pdfEncoding="Cp1252"
isPdfEmbedded="false"
/>
<style
name="Arial_Italic"
isDefault="false"
fontName="Arial"
fontSize="12"
isBold="false"
isItalic="true"
isUnderline="false"
isStrikeThrough="false"
pdfFontName="Helvetica-Oblique"
pdfEncoding="Cp1252"
isPdfEmbedded="false"
/>

<parameter name="NetAmountText" isForPrompting="true" class="java.lang.String"/>
<parameter name="DiscountText" isForPrompting="true" class="java.lang.String"/>
<parameter name="TotalAmountText" isForPrompting="true" class="java.lang.String"/>
<parameter name="DateFieldText" isForPrompting="true" class="java.lang.String"/>
<parameter name="BuyerFieldText" isForPrompting="true" class="java.lang.String"/>
<parameter name="BillNumberFieldText" isForPrompting="true" class="java.lang.String"/>
<parameter name="ReportTitle" isForPrompting="true" class="java.lang.String"/>
<parameter name="MyBillNumber" isForPrompting="true" class="java.lang.String"/>
<parameter name="SOLDON" isForPrompting="true" class="java.lang.String"/>
<parameter name="SOLDBY" isForPrompting="true" class="java.lang.String"/>
<parameter name="BUYERNAME" isForPrompting="true" class="java.lang.String"/>
<parameter name="SALESTOTALS" isForPrompting="true" class="java.lang.Double"/>
<parameter name="DISCOUNT" isForPrompting="true" class="java.lang.Double"/>
<parameter name="NETAMOUNT" isForPrompting="true" class="java.lang.Double"/>
<parameter name="CASHAMTS" isForPrompting="true" class="java.lang.Double"/>
<parameter name="CHECKAMTS" isForPrompting="true" class="java.lang.Double"/>
<parameter name="CREDITAMTS" isForPrompting="true" class="java.lang.Double"/>
<queryString><![CDATA[select itemcode, quantitybox, salespricebox, quantitypiece, salespricepiece, salestotal from salesregister WHERE billnumber=$P{MyBillNumber}]]></queryString>

<field name="ITEMCODE" class="java.lang.String"/>
<field name="QUANTITYBOX" class="java.lang.Long"/>
<field name="SALESPRICEBOX" class="java.lang.Double"/>
<field name="QUANTITYPIECE" class="java.lang.Long"/>
<field name="SALESPRICEPIECE" class="java.lang.Double"/>
<field name="SALESTOTAL" class="java.lang.Double"/>

<background>
<band height="0" isSplitAllowed="true" >
</band>
</background>
<title>
<band height="140" isSplitAllowed="true" >
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
style="Arial_Bold"
x="20"
y="0"
width="508"
height="30"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font size="15"/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{ReportTitle}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="20"
y="40"
width="150"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Left">
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{DateFieldText}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" pattern="EEE, MMMMM dd yyyy, h:mm:ss a" isBlankWhenNull="false" evaluationTime="Report" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="200"
y="40"
width="300"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<textFieldExpression class="java.util.Date"><![CDATA[new java.util.Date()]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="20"
y="70"
width="150"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Left">
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{BuyerFieldText}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="200"
y="70"
width="300"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{BUYERNAME}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="20"
y="100"
width="150"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Left">
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{BillNumberFieldText}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="200"
y="100"
width="300"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{MyBillNumber}]]></textFieldExpression>
</textField>
</band>
</title>
<pageHeader>
<band height="0" isSplitAllowed="true" >
</band>
</pageHeader>
<columnHeader>
<band height="20" isSplitAllowed="true" >
<staticText>
<reportElement
x="25"
y="0"
width="100"
height="20"
key="staticText"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font isUnderline="true"/>
</textElement>
<text><![CDATA[Item Code]]></text>
</staticText>
<staticText>
<reportElement
x="125"
y="0"
width="100"
height="20"
key="staticText"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font isUnderline="true"/>
</textElement>
<text><![CDATA[Boxes]]></text>
</staticText>
<staticText>
<reportElement
x="225"
y="0"
width="67"
height="20"
key="staticText"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font isUnderline="true"/>
</textElement>
<text><![CDATA[Rs./Box]]></text>
</staticText>
<staticText>
<reportElement
x="292"
y="0"
width="72"
height="20"
key="staticText"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font isUnderline="true"/>
</textElement>
<text><![CDATA[Pieces]]></text>
</staticText>
<staticText>
<reportElement
x="364"
y="0"
width="61"
height="20"
key="staticText"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font isUnderline="true"/>
</textElement>
<text><![CDATA[Rs./Piece]]></text>
</staticText>
<staticText>
<reportElement
x="425"
y="0"
width="85"
height="20"
key="staticText"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font isUnderline="true"/>
</textElement>
<text><![CDATA[Item Total]]></text>
</staticText>
</band>
</columnHeader>
<detail>
<band height="20" isSplitAllowed="true" >
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="25"
y="0"
width="100"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Left">
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$F{ITEMCODE}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" pattern="0" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="125"
y="0"
width="100"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font/>
</textElement>
<textFieldExpression class="java.lang.Long"><![CDATA[$F{QUANTITYBOX}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" pattern="0.00" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="225"
y="0"
width="67"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font/>
</textElement>
<textFieldExpression class="java.lang.Double"><![CDATA[$F{SALESPRICEBOX}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" pattern="0" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="292"
y="0"
width="72"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font/>
</textElement>
<textFieldExpression class="java.lang.Long"><![CDATA[$F{QUANTITYPIECE}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" pattern="0.00" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="364"
y="0"
width="61"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Right">
<font/>
</textElement>
<textFieldExpression class="java.lang.Double"><![CDATA[$F{SALESPRICEPIECE}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" pattern="0.00" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="425"
y="0"
width="85"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Right">
<font/>
</textElement>
<textFieldExpression class="java.lang.Double"><![CDATA[$F{SALESTOTAL}]]></textFieldExpression>
</textField>
</band>
</detail>
<columnFooter>
<band height="100" isSplitAllowed="true" >
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="292"
y="20"
width="133"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{TotalAmountText}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" pattern="0.00" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="425"
y="20"
width="85"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Right">
<font/>
</textElement>
<textFieldExpression class="java.lang.Double"><![CDATA[$P{SALESTOTALS}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="292"
y="50"
width="133"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{DiscountText}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" pattern="0.00" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="425"
y="50"
width="85"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Right">
<font/>
</textElement>
<textFieldExpression class="java.lang.Double"><![CDATA[$P{DISCOUNT}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="292"
y="80"
width="133"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font/>
</textElement>
<textFieldExpression class="java.lang.String"><![CDATA[$P{NetAmountText}]]></textFieldExpression>
</textField>
<textField isStretchWithOverflow="false" pattern="0.00" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="425"
y="80"
width="85"
height="20"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Right">
<font/>
</textElement>
<textFieldExpression class="java.lang.Double"><![CDATA[$P{NETAMOUNT}]]></textFieldExpression>
</textField>
</band>
</columnFooter>
<pageFooter>
<band height="15" isSplitAllowed="true" >
<staticText>
<reportElement
x="0"
y="0"
width="40"
height="15"
key="staticText"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement>
<font/>
</textElement>
<text><![CDATA[Page:]]></text>
</staticText>
<textField isStretchWithOverflow="false" isBlankWhenNull="false" evaluationTime="Now" hyperlinkType="None" hyperlinkTarget="Self" >
<reportElement
x="40"
y="0"
width="100"
height="15"
key="textField"/>
<box topBorder="None" topBorderColor="#000000" leftBorder="None" leftBorderColor="#000000" rightBorder="None" rightBorderColor="#000000" bottomBorder="None" bottomBorderColor="#000000"/>
<textElement textAlignment="Center">
<font/>
</textElement>
<textFieldExpression class="java.lang.Integer"><![CDATA[$V{PAGE_NUMBER}]]></textFieldExpression>
</textField>
</band>
</pageFooter>
<summary>
<band height="0" isSplitAllowed="true" >
</band>
</summary>
</jasperReport>


The XML might look huge. It is. And it's not so easy to write this XML. In fact, I generated this using another freeware called iReport, which is a designer tool for generating Jasper XML. You can drag and drop fields and change the alignments and formatting of fields and sections using this tool. The corresponding XML code gets generated dynamically. Here is a screenshot of a JRXML file in design using iReports.



I downloaded iReport version 2.0.5 from here.More about iReport and information on new releases can be found here.

Running the Report

Now you have the JRXML file at hand, which contain instructions for the Jasper engine to generate the report. How will you make Jasper engine read this XML and return you the report? This requires a bit of Java coding.

Here is the code snippet that does the job for you.


JasperDesign jasperDesign = JasperManager.loadXmlDesign(Thread.currentThread ().getContextClassLoader ().getResourceAsStream("SalesBill.JRXML"));
JasperPrint jasperPrint = JasperManager.fillReport(jasperReport,parameters, conn);
JasperExportManager.exportReportToPdfFile(jasperPrint,"SalesBill.pdf");


This report is generated as a PDF file. You may opt to generate the report in HTML, PDF, Excel or RTF formats. You may even view the report in JasperViewer, which is a Java based Report Viewer tool from Jasper.

Here is a complete listing of a struts action class that processes a sales order and generates a PDF Sales Bill.


package com.dj.sales.action;


import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperPrintManager;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.JasperRunManager;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.view.JasperViewer;

import org.apache.struts.action.*;
import javax.servlet.http.*;
import javax.servlet.*;

import java.sql.Connection;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import com.classic.account.db.*;
import com.classic.account.util.*;
import com.classic.addr.forms.*;
import com.classic.account.constants.*;
import com.classic.purch.forms.PurchBillForm;
import com.classic.sales.forms.SalesForm;
import com.classic.sales.util.BilledItem;
import com.classic.sales.util.SaleItem;

public class AddSales extends Action
{
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws Exception
{

SalesForm lForm = (SalesForm)form;
String txtDate = lForm.getTxtDate();
String billnumber = lForm.getBillnumber();
String soldby = lForm.getSoldby();
String salestype= lForm.getSalestype();
String oldbuyer= lForm.getOldbuyer();
String newbuyer= lForm.getNewbuyer();
double checkamt= lForm.getCheckamt();
String checkdetails= lForm.getCheckdetails();
double cashamt= lForm.getCashamt();
double creditamt= lForm.getCreditamt();
double discount = lForm.getDiscount();
double netsaleamount = lForm.getNetsaleamount();
String buyername = "";
double initcheckamt=checkamt;
double initcashamt=cashamt;
String initcheckdetails=checkdetails;
if(checkdetails==null)
checkdetails="";
if(oldbuyer==null)
oldbuyer="";
if(newbuyer==null)
newbuyer="";
if(oldbuyer.equals("Select Buyer") || oldbuyer.equals("") )
buyername = newbuyer;
else
buyername = oldbuyer;
User user = (User)request.getSession().getAttribute("AuthUser");
request.getSession().setAttribute("SalesReportGenerated","");
String userId = user.getUserId();
SaleItem item=null;
try
{
HashMap itemMap = request.getSession().getAttribute("ItemsAdded")==null? null : (HashMap)request.getSession().getAttribute("ItemsAdded");
if(itemMap != null)
{
Iterator itkeys = itemMap.keySet().iterator();
int cnt=0;
int primary = 1;
while(itkeys.hasNext())
{
//Insert Each Item into itemRegister
item=(SaleItem)itemMap.get(itkeys.next());
AccountDAO.getDAO().insertSales(AccUtil.formatYyyyMmDd(txtDate),soldby,billnumber,item.getItemcode(),item.getQuantitybox(),item.getSalespricebox(),item.getUnitpricebox(),item.getQuantitypiece(),item.getSalespricepiece(),item.getUnitpricepiece(),item.getNetamount(),item.getNetprofit(),salestype,buyername,checkamt,checkdetails,cashamt,creditamt,AccUtil.formatYyyyMmDd(new Date()),userId,primary,discount,netsaleamount);
cnt++;
if(cnt > 0)
{
checkamt=0;
cashamt=0;
creditamt=0;
discount =0;
netsaleamount =0;
checkdetails="";
primary=0;
}
}
}
//Insert Payment Details to PaymentHistory
AccountDAO.getDAO().addToPaymentHistory(billnumber, "Sales Bill", initcheckamt, initcashamt, "CR", initcheckdetails);
}
catch(Exception e)
{
lForm.reset(mapping,request);
ActionErrors actionErrors = new ActionErrors();
actionErrors.add("GlblSalesErrMsg", new ActionError("global.sales.exception.message"));
saveErrors(request,actionErrors);
return mapping.findForward("failure");
}
// First, load JasperDesign from XML and compile it into JasperReport
try
{
response.setContentType("application/pdf");
Map parameters = new HashMap();
JasperDesign jasperDesign = JasperManager.loadXmlDesign(Thread.currentThread ().getContextClassLoader ().getResourceAsStream("SalesBill.JRXML"));
//ClassLoader.getSystemClassLoader());
JasperReport jasperReport = JasperManager.compileReport(jasperDesign);
// Now, create a map of parameters to pass to the report.
parameters.put("ReportTitle", "Classic Ceramics - Sales Bill");
parameters.put("MyBillNumber", billnumber);
parameters.put("TotalAmountText", "Total Amt (Rs)");
parameters.put("DiscountText", "Discount (Rs)");
parameters.put("NetAmountText", "Net Amt (Rs)");
parameters.put("BuyerFieldText", "To M/s. ");
parameters.put("DateFieldText", "Date : ");
parameters.put("BillNumberFieldText", "Bill Number ");

//
BilledItem billedItem = AccountDAO.getDAO().getBilledEntry(billnumber);
parameters.put("SOLDON", billedItem.getSoldon());
parameters.put("SOLDBY", billedItem.getSoldby());
parameters.put("BUYERNAME", billedItem.getBuyername());
parameters.put("SALESTOTALS", new Double(billedItem.getItemtotals()));
parameters.put("DISCOUNT", new Double(billedItem.getDiscount()));
parameters.put("NETAMOUNT", new Double(billedItem.getSalestotal()));
parameters.put("CASHAMTS", new Double(billedItem.getCashamt()));
parameters.put("CHECKAMTS", new Double(billedItem.getCheckamt()));
parameters.put("CREDITAMTS", new Double(billedItem.getCreditamt()));
// Get a database connection
Connection conn = AccountDAO.getDAO().getConnection();
// Create JasperPrint using fillReport() method
JasperPrint jasperPrint = JasperManager.fillReport(jasperReport,
parameters, conn);
// Generate the PDF using JasperPrint
JasperExportManager.exportReportToPdfFile(jasperPrint,this.getServlet().getServletContext().getRealPath("/")+"/SalesBill.pdf");
request.getSession().setAttribute("SalesReportGenerated","YES");
request.getSession().setAttribute("EstimateReportGenerated","");

// Or View the report in the JasperViewer
// JasperViewer.viewReport(jasperPrint);
}
catch(Exception e){
e.printStackTrace();
}
lForm.reset(mapping,request);
request.getSession().setAttribute("ItemsAdded",null);
request.getSession().setAttribute("SessionTotal",null);
ActionErrors actionErrors = new ActionErrors();
actionErrors.add("GlblSalesErrMsg", new ActionError("global.sales.success.message"));
saveErrors(request,actionErrors);
return mapping.findForward("success");
//return null;
}

public AddSales()
{
super();
}
}


And finally, here is a screenshot of the generated report.

Monday, March 17, 2008

Resolving ClassNotFoundExceptions

Ever got stuck at a ClassNotFoundException or NoClassDefFoundError exception, and you really didn't know, which jar file you should add in the classpath to resolve this?
Ever came across a situation when you added a new library in the classpath, but your application is failing to pick it up, just because there exists another jar in the classpath which contains an older version of your library, and got loaded before your new one?

In these situations, you will need to identify that jar/zip, which contains a particular class/package structure, and probably add or remove it from the classpath.

There are many ways to do this.

1. You could open each jar/zip in your machine and search for your class/package.
2. Get assistance from search engines like JARHOO or JAVACIO.US to list all the known jars and applications that contains this class, and search for them in your machine.
3. Make use of this small tool to do the job for you.

About ClassFinder

ClassFinder is a small Java application to help developers search for an archive that contains a particular class or a package structure in 3 easy steps.



1. Select the root directory where you want ClassFinder to search for the archive. The application will search all the files and directories under this.


2. Specify if you wish to search a particular class name (Eg: JButton), or a fully qualified class name(Eg: javax.swing.JButton). Type in the classname or the fully qualified class name as per your selection.



3. Specify what type of archive you wish to search in (Eg: jar, war, zip). Currently, you can search only one type of archive at one shot. Click on the Search Button.



4. If there is a match, it will get listed in the list box at the bottom. Same file name listed multiple shows that this archive has multiple classes with the same name(This will happen only of you have opted to search for class name, not a fully qualified class name)



Licence, Download and Installation

ClassFinder is a freeware. ClassFinder can be downloaded here. This is an executable jar file. You need to have Java installed on your PC to run ClassFinder. Double clicking the jar should run it.

Let me know if you come across any issues.

Thursday, March 6, 2008

EJB Primer with WSAD - Part 6


Click on the images to view them full size!


Step 14 - Packaging the Application

To deploy an EJB application in any application server, we must package it as an .ear file. An .ear file contains the enterprise bean modules, the deployment descriptors, mapping information, any container specific descriptor files, and dependent wars and jars. In our case, WSAD has already created the Websphere specific descriptor fies for us.

We can either manually create an .ear fie by assembling these files using java jarring, or choose Apache Ant to do the task for us. using the Ant commands, we can automate the whole compiling, deployment code generation and archiving process to a one click job. Ant can do a lot more like, checking out a project from the repository(like CVS) and do real deployment on the server. Let's start by creating an Simple Project in WSAD. Name it EmployeeBuild.



Now, create a new file and name it build.xml. Copy the following ant script to it.



<project name="EmployeeTest Ant" default="Total" basedir=".">

<!-- Set global properties -->
<property name="workspace.dir" value="D:/IBM/WebSphere Studio/Application Developer/WS" />
<property name="project.ear" value="EmployeeEAR" />
<property name="project.ejb" value="EmployeeEJB" />
<property name="project.war" value="EmployeeWeb" />

<property name="type" value="incremental" />
<property name="debug" value="true" />
<property name="source" value="false" />
<property name="meta" value="false" />
<property name="noValidate" value="false" />
<property name="dist" value="${workspace.dir}/EmployeeDistDir" />

<target name="init">
<!-- Create the time stamp -->
<tstamp />
<!-- Create the dist directory where the archive files will be placed -->
<mkdir dir="${dist}" />
<echo message="Directory Created " />
</target>


<!-- START ProjectEjb -->
<target name="getProjectDataEjb">
<getProjectData Basedir="${workspace.dir}/${project.ejb}" />
<echo>grtProjectData ${workspace.dir}/${project.ejb}</echo>
</target>
<target name="deployEjb" depends="getProjectDataEjb">
<!-- Generates deployed code for the EJBs -->
<ejbDeploy EJBProject="${project.ejb}" NoValidate="${noValidate}" />
</target>

<target name="buildEjb">
<!-- Builds the EJB project -->
<projectBuild ProjectName="${project.ejb}" BuildType="${type}" DebugCompilation="${debug}" />
</target>
<!-- END -->
<!-- START ProjectWeb_1 -->
<target name="getProjectDataWeb">
<getProjectData Basedir="${workspace.dir}/${project.war}" />
<echo>grtProjectData ${workspace.dir}/${project.war}</echo>
</target>
<target name="buildWar" depends="getProjectDataWeb">
<!-- Builds the WAR project -->
<projectBuild ProjectName="${project.war}" BuildType="${type}" DebugCompilation="${debug}" />
</target>
<!-- END -->

<!-- START ProjectEar -->
<target name="getProjectDataEar">
<getProjectData Basedir="${workspace.dir}/${project.ear}" />
<echo>grtProjectData ${workspace.dir}/${project.ear}</echo>
</target>
<target name="buildEar" depends="getProjectDataEar">
<!-- Builds the EAR project -->
<projectBuild ProjectName="${project.ear}" BuildType="${type}" DebugCompilation="${debug}" />
</target>
<!-- END -->

<target name="exportEjb" depends="init">
<!-- Exports the EJB JAR -->
<echo>Test Message --- Jim</echo>
<ejbExport EJBProjectName="${project.ejb}" EJBExportFile="${dist}/${project.ejb}.jar" ExportSource="${source}" overwrite="true" />
</target>

<target name="exportWar1" depends="init">
<!-- Exports the WAR file -->
<warExport WARProjectName="${project.war}" WARExportFile="${dist}/${project.war}.war" ExportSource="${source}" overwrite="true" />
</target>


<target name="exportEar" depends="init">
<!-- Exports the EAR file -->
<earExport EARProjectName="${project.ear}" EARExportFile="${dist}/${project.ear}.ear" ExportSource="${source}" IncludeProjectMetaFiles="${meta}" overwrite="true" />
<echo message="Exported EAR" />
</target>
<!--Here importProjects, as first param -->
<target name="buildAll" depends="deployEjb,buildEjb,buildWar,buildEar">
<!-- Builds all projects -->
<echo message="Built all projects" />
</target>

<target name="exportAll" depends="exportEjb,exportWar1,exportEar">
<!-- Exports all files -->
<echo message="Exported all files" />
</target>

<target name="Total" depends="buildAll,exportAll">
<!-- Buidl all projects and exports all files -->
<echo message="Total finished" />
</target>

<target name="clean">
<!-- Delete the output files -->
<delete file="${dist}/${project.ejb}.jar" failOnError="false" />
<delete file="${dist}/${project.war}.war" failOnError="false" />
<delete file="${dist}/${project.ear}.ear" failOnError="false" />
</target>

</project>


The code is self-explanatory. 'Total" is our default target here. It depends on 2 tasks. 'BuildAll' and 'ExportAll'. 'BuildAll' invokes tasks for deployment code generation for EJB and builds all the projects. 'ExportAll' exports the built projects to wars jars and ears.

Make sure to change the 'workspace.dir' property to match your enviornment.

WSAD comes with Ant library, so yuo wont have to download and copy the Ant jar file to your classpath to run an Ant Script. To run our build.xml Ant in WSAD, right-click the file in Project Explorer and select 'Run Ant..'. This will show us the available ant tasks to run. Our default task 'Total' will be selected by default.



Here you may change the order or opt to execute a different task. In our case, just click the Run button, and you will see the messages scrolling up in the console. When finished, you will see a confirmation message at the bottom of the console.



That's it. If the build process was successful, our .ear and other files would be created in the destination Directoriy.




Step 15 - Deployment Process

This section assumes that you have access to the Admin Console of a WebSphere Application Server or Integrated Solutions Console or Network Deployment Manager.

Remember we configured a JAAS entry (Step 5) and a Datasource (Step 6) on the TestServer. The same needs to be performed as an enviornment setup on the Application Server as well.

The JAAS entry con be configured in the Security Tab. Select Secure Administration, applications and infrastructure.



Under the Authentication section, and configure the entry under Java Authentication and Autherization Service->J2C Authentication Data.




The Datasource can be configured under Resources->DataSources->JDBC



Make sure to save the configuration changes each time you make a new entry.

Click on the Save link that appears on the page, each time after you make a change to Save the changes.




That's all about the configurations. Now we need to do the actual deployment of our .ear on the Application Server. Click on Applications->Install New Application.



Selct EmployeeEAR.ear from the EmployeeDistDir, where the ear was created by our Ant script. Click Next. Accept all defaults in the installation options page and Click Next. In the Map modules to servers page, select the servers on which you would like to install the application (In a clustered enviornment, you might have to choose multiple nodes and servers) and select both EmployeeEJB and EmployeeWeb to deploy.



Click Next. Click Finish in the Summary page. This will take a while to install the application. When done, the page displays a Successful message and asks you to save the configuration changes. Click on the Save link to do so, and we are done with the deployment.



Now the application got deployed, but it's not started yet. To start the application, go to Applications->Enterprise Applications. Select EmployeeEAR and click the start button.
Please note that, if you are deploying the application in a clustered enviornment, you will have to start the cluster/application servers under Servers menu before starting up the application.



Now, we need to verify that our application really works. As we did with the test server, we will try to invoke the Entity bean through our servlet, for which we created the EmployeeWeb Project. Now, to access the index.html page of our web application, you must know the port on which the server is listening for HTTP requests. You must have noted it when performing the Application Server installation. If you don't have this information, go to Application servers > server1 > Ports > WC_defaulthost to get the Port for the Default Host.

Once you are ready, type in http://<yourserver>:<yourport>/EmployeeWeb/ (http://localhost:9080/EmployeeWeb/ in my case). Hopefully, you get the below page.



Type in the Employee ID of Aishwarya Rai and check if your Entity bean brings in the result.




If you encounter a problem, look for the Websphere SystemOut and SystemErr logs to find the cause and search in Google to find a solution. Do let me know if you cant resolve it. I will also try to search it out for you.


The workspace of an improved version of these projects is available here.
And the .ear is here.

Go to : Part 1Part 2Part 3Part 4Part 5Part 6

Monday, March 3, 2008

EJB Primer with WSAD - Part 5


Click on the images to view them full size!


Step 13 - Developing a Web Client to use the EJB

Now, for the users to access the bean, we need to develop a client application, which will be a simple web application. We will create a web project as part of the EmployeeEAR project. Right Click on EmployeeEAR project and in the pop-up, click New->Project. In the New Project Wizard select Web->Dynamic Web Project. Type in the name as EmployeeWeb and click Finish



We must add the EmployeeEJB project to the Java build path of our web project. To do this, right click EmployeeWeb project and select Properties->Java Build Path. Select EmployeeEJB and click OK.



Now, we will create a Java bean to transport the employee details. Right click on the EmployeeWeb project and select New->Class. Give the package name as 'employee.web' and the class name as 'EmployeeData'. click Finish.



Add the fields as below and generate the getters and setters for these fields.


id int
firstName String
lastName String

Here is the complete listing of the bean class:


package employee.web;
public class EmployeeData {

private int id = 0;
private String firstName = null;
private String lastName = null;


public String getFirstName() {
return firstName;
}

public int getId() {
return id;
}

public String getLastName() {
return lastName;
}

public void setFirstName(String string) {
firstName = string;
}

public void setId(int i) {
id = i;
}

public void setLastName(String string) {
lastName = string;
}
}


Now, we will create a servlet, which talks to the beans. To do this, right click EmployeeWeb Project and select New->Servlet. Type in the package name as 'employee.web.servlets' and the Servlet name as 'EmployeeServlet'. Click Finish.



Our code to access the bean comes inside the doPost() method, as we will be posting the request from a client form. Here is the complete listing of the EmployeeServlet class. Copy and paste the code from here to your newly created servlet class.


package employee.web.servlets;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import javax.naming.*;
import java.util.*;
import javax.rmi.*;
import employee.web.*;
import employee.ejb.*;

public class EmployeeServlet extends HttpServlet {

String firstName = null;
String lastName = null ;
int id = 0;
EmployeeData employeeData = new EmployeeData();

String JNDIName = "ejb/employee/ejb/EmployeeSessionHome";

public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {

EmployeeSessionHome employeeSessionHome = null;
EmployeeSession employeeSession = null;

InitialContext initContext = null;


id = Integer.parseInt(request.getParameter("id"));

firstName = request.getParameter("firstName") == null ? "" : request.getParameter("firstName") ;


lastName = request.getParameter("lastName") == null ? "" : request.getParameter("lastName") ;


// Get the initial context
try
{
initContext = new InitialContext();
Object obj = initContext.lookup(JNDIName);
employeeSessionHome = (EmployeeSessionHome) PortableRemoteObject.narrow(obj,EmployeeSessionHome.class);
}
catch (javax.naming.NamingException e)
{
e.printStackTrace();
}
// Create a new EmployeeSession
try
{
employeeSession = employeeSessionHome.create();


// talk to the CMP Entity bean
String firsNamefromEJB = employeeSession.getFirstName(id);
String lastNamefromEJB = employeeSession.getLastName(id);

// set the values returned into the JavaBean
employeeData.setId(id);
employeeData.setFirstName(firsNamefromEJB);
employeeData.setLastName(lastNamefromEJB);
}
catch (java.rmi.RemoteException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
// Place the bean in the session to pass to JSP
HttpSession session = request.getSession(true);
session.setAttribute("employeedetails",employeeData);

// Now, forward the response to the Results.jsp page
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("results.jsp");
dispatcher.forward(request, response);
}
}


Moving on to the last part of our project, let's create the HTML form page to submit our request to the servlet and the JSP page to display the response.


Right Click EmployeeWeb Project in Poject Navigator and select New->HTML/XHTML File. Type in the file name as 'index.html' and select markup language to be HTML.



Copy and paste the below code to your HTML file.


<HTML>
<HEAD>
<TITLE>Sample EJB Client Application</TITLE>
</HEAD>
<BODY>
<form name=test method="POST" action="servlet/employee.web.servlets.EmployeeServlet">
Employee ID <INPUT name="id" size="3" type="text">
<input type="Submit" value="View Emplyee Details">
</form>
</BODY>
</HTML>


Similarly, create a JSP page and name it results.jsp and copy paste the below code.




<HTML>
<HEAD>
<TITLE>Results Page</TITLE>
</HEAD>
<BODY>
<jsp:useBean id="employeedetails" class="employee.web.EmployeeData" scope="session"/>
<FONT color="#0000ff" face="Arial" size="+2"><b> Employee Details</FONT>
<HR>
<BR>
ID Number: <jsp:getProperty name="employeedetails" property="id"/> <BR>
<BR>
First Name: <jsp:getProperty name="employeedetails" property="firstName"/>
<br>
<BR>
Last Name: <jsp:getProperty name="employeedetails" property="lastName"/>
</BODY>
</HTML>


Save all the changes now. Select EmployeeWeb and click on 'Rebuild Project' in the Project menu to build the Project.

Now, start TestServer. Right-click index.html in the Project Navigator and click 'Run on Server'. Select TestServer in the server list(if not selected by default) and click Finish.



This will open up index.html page in Universal Test Client Browser. Enter a valid Employee ID and click 'View Details' button.



Now, here is the list of processes involved in fetching you the Employee's Details.

1. The HTML form posts the data to the EmployeeServlet
2. EmployeeServlet looks up the JNDI registry to locate the EmployeeSessionHome.
3. EmployeeServlet invokes the create method on EmployeeSessionHome which return the EmployeeSession remote Object.
4. EmployeeServlet then invokes the getter methods on the EmployeeSession remote object.
5. These methods, in turn calls the getEmployeeEntity() method of EmployeeSessionBean which looks up the JNDI registry to find the EmployeeEntityHome, and invokes the findByPrimaryKey() method on it.
6. The Container looks for the EJB-RDB mapping to find out the DataSource and the Table/Schema kj defenitions.
7. The container now locates the entity in the backend tables and fetches it.Also, it
takes out one of the Entity Beans from the pool and loads it with the data fetched from the backend.
8. The findByPrimaryKey() method of EmployeeEntityHome returns a reference to the fetched EmployeeEntityBean's remote object.
9. The getter methods on the remote object gets called which returns the field values
10. The EmployeeServlet instantiates the EmployeeData bean and sets it's field values with the fetched values, and adds this bean to the session, and forwards the response to results.jsp
11. The results.jsp page gets loaded and displays the fields of the bean contained in the session.

If all of these steps work well, we will see the result as below:



Upto now, we have been using the WSAD built in Test enviornment to test our project. In the next steps,we will see how to package the whole projec to an enterprise archive (.ear) and deploy it in a Standalone Application Server.

Go to : Part 1Part 2Part 3Part 4Part 5Part 6

Saturday, March 1, 2008

EJB Primer with WSAD - Part 4


Click on the images to view them full size!


Step 11 - Add Projects and Start Server

In the Server Perspective, right click TestServer and select 'Add and Remove Projects'. From the Available Projects list, select and shuttle EmployeeEAR to the Configured Projects list and click Finish.





If everything goes fine, you will see messages of this kind in the Server console.



Step 12 - Test your EJB with the WSAD TestClient

WSAD is integrated with an Universal Test Client. we may opt use this facility to test the EJB, we just created. To do this, right click TestServer in the Server Configuration Pane, and select Run Universal Test Client in th pop-up menu.



This will open up the Test Client browser screen.



Click on JNDI explorer->ejb->employee->ejb. This will list the Beans under the employee.ejb package under the JNDI namespace ejb.



Click on EmployeeSessionHome to work with the EmployeeSession bean. You will see only one method - create - under the visible methods.



Click on this method, and click on the 'Invoke' button. This will create an instance of the EmployeeSessionBean. Now, Click on the 'Work With Object' to further work with the EmployeeSessionBean.



Now, you will see all the available methods listed under Method Visibility.



Click on String getFirstName(int) and enter a valid employeeid in the parameter input text box and click on the Invoke button. If everything goes well, you will see the result as below.



If you encounter an error, look for the stacktrace in the Server Console try to identify any possible causes from the error log.

Go to : Part 1Part 2Part 3Part 4Part 5Part 6