Thursday, March 14, 2013

Jasper Reports tips and tricks

Jasper Reports basic steps:

1. Design report in iReport designer
2. Save the the template  - jrxml file
3. Compile the jrxml to jasper
4. Run from iReport or integrate it with a java program

Load the jasper report from .jasper file

//reportData is an instance of List
(JasperReport)jasperReport = JRLoader.loadObjectFromLocation(jasperReportName);

JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport,parameters,new JRBeanCollectionDataSource(reportData));


//Export into pdf format
byte[] pdfFile = JasperExportManager.exportReportToPdf(jasperPrint);


//Export into csv format
JRCsvExporter exporter = new JRCsvExporter();
StringBuffer buffer = new StringBuffer();
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STRING_BUFFER,buffer);
exporter.exportReport();

//Export into HTML format
JRHtmlExporter exporter=new JRHtmlExporter();
StringBuffer buffer = new StringBuffer();
  
exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint);
exporter.setParameter(JRExporterParameter.OUTPUT_STRING_BUFFER, buffer);
exporter.setParameter(JRHtmlExporterParameter.IS_USING_IMAGES_TO_ALIGN, false);
//following parameters are used to avoid the page breaks, empty spaces and display tabular data better in html compare to pdf
exporter.setParameter(JRHtmlExporterParameter.IGNORE_PAGE_MARGINS, true);
exporter.setParameter(JRHtmlExporterParameter.ZOOM_RATIO, 1.5F);
exporter.setParameter(JRHtmlExporterParameter.BETWEEN_PAGES_HTML, "");
exporter.setParameter(JRHtmlExporterParameter.FRAMES_AS_NESTED_TABLES,true);
exporter.setParameter(JRHtmlExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS, true);
exporter.exportReport();
   
iReport Designer tips n tricks:


Create paremeters, fields in the iReport designer and make sure the name match the exact names in the javabean if you plan to use java bean as datasource.

List is also very useful if you do not want to use a subreport.
To create a list, drag list component from the pallet and right-click select datasource :
new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{fieldname})
go to the dataset1 and create all necessary fields and drag and drop them to the area.


If you want to display certain area when some conditions are met, select the band properties for that particular group or section and modify "print when expression" to new Boolean($F{fieldname}>0) for e.g.

Wednesday, October 10, 2012

Tuning Weblogic - Case study of performance issue resolution

Case Study of how to analyze a slower performance or frequent out of memory exceptions of a web applications containing ejb deployed on oracle weblogic 

Enable jvm heap dump on app server

For e.g : export JAVA_OPTS=-verbose:gc -XX:+PrintClassHistogram -XX:+PrintGCDetails -Xloggc:/tmp/jvm_loggc.log -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp

Using gcviewer monitor the heap usage and note the trend of increasing memory consumption even after the garbage collection is executed.


Take several snapshots/heap dumps and identify where the bottle neck is using tools like Eclipse MAT or visualvm
the heap dump can be taken manually using following command, can be analyzed using EclipseMAT or visualVM :
jmap -dump:format=b,file=  

Sort by object size in Dominator Tree or in histogram in EclipseMAT. Look for the top class/object and drill down to the classe name that look more familiar. If the identified class belongs to an ejb then there is a possibility that the ejb is retained in the in memory cache of jvm. To confirm this, check the cached beans current count in weblogic console. (refer to the how to monitor ejb cache section below for details)

One possible solution to above problem is described below :

Configure max-beans-in-cache and idle-timeout-seconds appropriate according to your need in weblogic-ejb-jar.xml as below use stateful/stateless as per your ejb:

<weblogic-enterprise-bean>
   <ejb-name>BeanName</ejb-name>
      <stateful-session-descriptor>
 <stateful-session-cache>
   <max-beans-in-cache>200</max-beans-in-cache>
   <idle-timeout-seconds>1200</idle-timeout-seconds>
 </stateful-session-cache>
      </stateful-session-descriptor>
</weblogic-enterprise-bean>

For testing purpose you can set the max-beans to 3-5 and idle-timeout to 60 secs and do some testing and notice the changes in weblogic console, like the ejb passivation count is increasing that means the ejbs are cleared from the cache once they are used.
Another important parameter is cache-type. Refer to the references for detailed explanations.

How to monitor the ejb cache on weblogic console :

1. Go to your deployed application
2. Expand it and go the the ejbs
3. Select the Monitoring tab.
4. Click and navigate through the pages to view monitoring statistics for deployed stateless, stateful, entity, and message-driven EJBs.
5. If you don't see the activation count or passivation count, click on customize table and add these columns.

References

1. http://docs.oracle.com/cd/E13222_01/wls/docs81/perform/EJBTuning.html
2. http://middlewaremagic.com/weblogic/?p=5665

Tuesday, September 25, 2012

Debugging JSP

1. Keep the generated java files

IBM websphere :
change WEB-INF\ibm-web-ext.xml as following :

<jspAttributes xmi:id="JSPAttribute_1" name="keepgenerated" value="true"/> <jspAttributes xmi:id="JSPAttribute_2" name="scratchdir" value="C:\temp\ibm"/>

Weblogic :
Change weblogic.xml as following :
<jsp-descriptor>
    <keepgenerated>true</keepgenerated>
    <verbose>true</verbose>
    <working-dir>c:/temp/bea</working-dir>
</jsp-descriptor>

2. Restart the server in debug or normal mode

3. When an exception happens in a jsp, it will show and line number. Now, you can find the java file and trace the line number and go from there.

Friday, September 21, 2012

Unit Testing Java code using mock objects (mockito)

Let's start with an example. We have a Conversion class to convert temperature from Fahrenheit to Celcius.

Following is the Java code :
class Fahrenheit {
 float f=0;
 public Fahrenheit(float f)
 {
  this.f=f;
 }
 public float getFahrenheit()
 {
  return f;
 }
 public void setFahrenheit(float f)
 {
  this.f=f;
 }
}

class Celcius {
 float celcius=0;
 public Celcius(Float c)
 {
  System.out.println("Celcius="+c);
  celcius=c;
 }
 public Float getCelcius()
 {
  return celcius;
 }

 public void setCelcius(Float c)
 {
  System.out.println("Celcius="+c);
  celcius=c;
 }
}

public class Convert {
 
 private float convertToFahrenheit(Celcius c)
 {
  return (float) ((c.getCelcius()*1.8)+32);
 }
 private float converToCelcius(Fahrenheit f)
 {

  return ((f.getFahrenheit()-32)*5/9);
 }

 public float convert(Fahrenheit f, Celcius c)
 {
  if(f!=null)
   return converToCelcius(f);
  else
   return convertToFahrenheit(c);
 }

}

1.Create Mock Objects
Object obj=mock(SomeclassName.class)

2. Setup return values on this object
when(obj.somemethod(param)).thenReturn(100);

3. Call a method under test
obj.aMethod()

4. Verify if a particular method is called and returns a certain value
verify(obj).bMethod(abc,anyObject());

For our example above, the test code looks like below

 @Test
 public void test() {

  Convert conversion = mock(Convert.class);
  Celcius celcius=mock(Celcius.class);
  Fahrenheit fahrenheit=mock(Fahrenheit.class);
  when(celcius.getCelcius()).thenReturn((float) 20.0);


  float val=conversion.convert(fahrenheit,celcius);

  verify(conversion).convertToFahrenheit(celcius);
 }

Tuesday, September 14, 2010

Using Hibernate, Spring, Maven, oracle all together

This tutorial will give an overview how can you wire up spring and hibernate together. The spring framework comes with ability to inject dependencies through the spring configuration file, we can leverage that to create the hibernate SessionFactory. Some code samples are given below. Also, we'll use the java persistence api so that we don't need to specify the hibernate mapping files.

The User class :


Entity
@Table(name="My_USER")
public class User {

private Long id;
private String name;
private String password;


@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "user_id_seq")
@SequenceGenerator(name="user_id_seq", sequenceName = "MY_USER_SEQ")
@Column(name="USER_ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}

@Column(name="USER_NAME")
public String getName() {
return name;
}
}
Replace the GeneratedValue annotation with strategy=GenerationType.AUTO if you are using any other database and no need to have sequencegenerator.

The DAO interface and implementation :




public interface UserDAO {

public void saveUser(User user) ;
public List<User> listUser() ;
}

public class UserDAOImpl implements UserDAO {

private HibernateTemplate hibernateTemplate;

public void setSessionFactory(SessionFactory sessionFactory) {
this.hibernateTemplate = new HibernateTemplate(sessionFactory);
}

public void saveUser(User user) {
hibernateTemplate.saveOrUpdate(user);
}

@SuppressWarnings("unchecked")
public List<User> listUser() {
return hibernateTemplate.find("from User");
}

}
The main application class:




public class App
{
public static void main( String[] args )
{


BeanFactory factory = new XmlBeanFactory(
new ClassPathResource("application-context.xml"));

UserDAO dao = factory.getBean("myUserDAO");

User user=new User();
user.setName("ABc");
user.setPassword("password");


dao.saveUser(user);
....
Spring configuration file : application-context.xml




<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">

<bean id="myDataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:user/password@localhost:1521:XE"/>
</bean>

<bean id="mySessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="myDataSource" />
<property name="annotatedClasses">
<list>
<value>ca.co.fusionapp.domain.User</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect"> org.hibernate.dialect.OracleDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
</bean>

<bean id="myUserDAO" class="ca.co.fusionapp.dao.UserDAOImpl">
<property name="sessionFactory" ref="mySessionFactory"/>
</bean>
</beans>
The above configuration uses setter dependency injection (i.e, the UserDAO has a setSessionFactory method, which sets up the hibernate session factory).

Download the entire code from here, which contains the pom.xml and run the above example using following command : mvn clean compile exec:java -e

I've oracle express installed and set up a username/password which needs to be updated in application-context.xml file.

Tuesday, August 31, 2010

Introduction to JSF

Java Server Faces is View in MVC (Model, View, Controller).

Get started with JSF

1. Download jsf latest jar files (https://javaserverfaces.dev.java.net/servlets/ProjectDocumentList?folderID=10411)
2. Set up the
3. Set up your project by modifying web.xml
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>

4. Write the jsp files, java source code, faces-config.xml and deploy on a webserver
For e.g converter.jsp
<f:view>

<h:form>
<h:panelGrid border="1" columns="2">
<f:facet name="header">
<h:outputText value="Temperature Conversion"></h:outputText>
</f:facet>

<f:facet name="footer">
<h:commandButton value="Convert" action="#{conversion.convert}"></h:commandButton>


</f:facet>

<h:outputText value="Celcius"></h:outputText>
<h:inputText value="#{conversion.celcius}"><f:convertNumber type="number" maxFractionDigits="2"/></h:inputText>

<h:outputText value="Fahrenheit "></h:outputText>
<h:inputText value="#{conversion.fahrenheit}"><f:convertNumber type="number" maxFractionDigits="2"/></h:inputText>

</h:panelGrid>
</h:form>

</f:view>

the conversion data bean class:

package proj;

public class Conversion {
..

public Float getCelcius()
{
return celcius;
}

public void setCelcius(Float c)
{
System.out.println("Celcius="+c);
celcius=c;
}
public Float getFahrenheit()
{
return fahrenheit;
}

public void setFahrenheit(Float f)
{
System.out.println("Fahrenheit="+f);
fahrenheit=f;
}

public String convert()
{
//conversion logic
return "convert";
}

..
}
faces-config.xml
<faces-config
    xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
<managed-bean>
<managed-bean-name>
conversion</managed-bean-name>
<managed-bean-class>
proj.Conversion</managed-bean-class>
<managed-bean-scope>
session</managed-bean-scope>
</managed-bean>
<navigation-rule>
<from-view-id>/converter.jsp</from-view-id>
<navigation-case>
<from-outcome>convert</from-outcome>
<to-view-id>/result.jsp</to-view-id>
</navigation-case>
</navigation-rule>

</faces-config>

Download the full source code

Wednesday, May 12, 2010

UML Integration

There are several tools available which can generate class diagrams, but I found this one very useful, which can generate class diagrams when you build your java project using ant.

Download the UmlGraph from http://www.umlgraph.org/

and also download the Graphviz from http://www.graphviz.org/

Modify your build.xml and add following javadoc


<target name="javadocuml" depends="init, init-compile-classpath" description="generates javadoc and also UML Diagram">
<mkdir dir="${DIST_DIR}/report/javadoc">
   <javadoc sourcepath="${SRC_DIR}" packagenames="test.*" destdir="${DIST_DIR}/report/javadoc" classpathref="compile.classpath" private="true">
     <doclet name="org.umlgraph.doclet.UmlGraphDoc" path="${LIB_DIR}/UMLGraph-5.2.jar">
        <param name="-inferrel"/>
           <param name="-inferdep"/>
           <param name="-hide" value="java.*"/>
          <param name="-collpackages" value="java.util.*"/>
           <param name="-qualify"/>
           <param name="-postfixpackage"/>
           <param name="-nodefontsize" value="9"/>
           <param name="-nodefontpackagesize" value="7"/>
           <param name="-link" value="http://java.sun.com/j2se/1.5.0/docs/guide/javadoc/doclet/spec"/>
           <param name="-link" value="http://java.sun.com/j2se/1.5/docs/api"/>
       </doclet>
   </javadoc>
<apply executable="dot" dest="${DIST_DIR}/report" parallel="false">
    <arg value="-Tpng">
  <arg value="-o">
   <targetfile>
   <srcfile>
   <fileset dir="${DIST_DIR}/report" includes="*.dot">
   <mapper type="glob" from="*.dot" to="*.png">
   </mapper></fileset>
   </srcfile>
   </targetfile>
  </arg>
 </arg>
</apply>
</mkdir>
</target>


Run your build.xml with javadocuml ant-task and look for report dir. You can see some class diagrams in your javadoc. Refer to the umlgraph website for more information about things you can do with the class diagrams.


Maven configuration




<dependency>
   <groupId>gr.spinellis</groupId>
   <artifactId>UmlGraph</artifactId>
   <version>5.2</version>
</dependency>   


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-javadoc-plugin</artifactId>
  <version>2.7</version>
  <configuration>
  <doclet>org.umlgraph.doclet.UmlGraphDoc</doclet>

  <!-- <docletPath>/path/to/UmlGraph.jar</docletPath> -->
  <docletArtifact>
      <groupId>org.umlgraph</groupId>
      <artifactId>doclet</artifactId>
      <version>5.1</version>
  </docletArtifact>
  <additionalparam>-inferrel -inferdep -quiet -hide java.*
 -collpackages java.util.* -qualify
 -postfixpackage -nodefontsize 9
 -nodefontpackagesize 7 -outputencoding utf8
  </additionalparam>
  <useStandardDocletOptions>true</useStandardDocletOptions>
  </configuration>
</plugin>