Programming

NullPointerException When Using JPA

I got this weird error while trying to select a data using Eclipselink JPA on my Glassfish AppServer

[#|2012-02-02T00:47:09.746+0700|SEVERE| glassfish3.0.1|javax.enterprise.system.std.com.sun. enterprise.v3. services.impl|_ThreadID=31;_ThreadName=http-thread-pool-8080-(1);| java.lang.NullPointerException
	at com.edw.xxx.dto.Account._persistence_set(Account.java)

here is the complete details of my error

[#|2012-02-02T00:47:09.746+0700|SEVERE|glassfish3.0.1|javax.enterprise.system.std.com.sun.enterprise.v3. services.impl|_ThreadID=31;_ThreadName=http-thread-pool-8080-(1);| java.lang.NullPointerException
	at com.edw.xxx.dto.Account._persistence_set(Account.java)
	at org.eclipse.persistence.internal.descriptors.PersistenceObjectAttributeAccessor. setAttributeValueInObject(PersistenceObjectAttributeAccessor.java:46)
	at org.eclipse.persistence.mappings.DatabaseMapping. setAttributeValueInObject(DatabaseMapping.java:1367)
	at org.eclipse.persistence.mappings.DatabaseMapping. readFromRowIntoObject(DatabaseMapping.java:1258)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder. buildAttributesIntoObject(ObjectBuilder.java:331)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder. buildObject(ObjectBuilder.java:660)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder. buildWorkingCopyCloneNormally(ObjectBuilder.java:582)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder. buildObjectInUnitOfWork(ObjectBuilder.java:551)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder. buildObject(ObjectBuilder.java:491)
	at org.eclipse.persistence.internal.descriptors.ObjectBuilder. buildObject(ObjectBuilder.java:443)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery. buildObject(ObjectLevelReadQuery.java:635)
	at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:838)
	at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:464)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:997)
	at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:675)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:958)
	at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:432)
	at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1021)
	at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2857)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1225)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1207)
	at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1181)
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:453)
	at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getSingleResult(EJBQueryImpl.java:714)

And here is the code for my Account.java

@Entity
@Table(name = "account")
@XmlRootElement
@NamedQueries({ 
    @NamedQuery(name = "Account.findAll", query = "SELECT a FROM Account a")
    })
public class Account implements Serializable {
    
    private static final long serialVersionUID = 1L;
	
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    @Column(name = "acc_no")
    private Long accNo;
	
    @Basic(optional = false)
    @Column(name = "name")
    private String name;
	
    @Basic(optional = false)
    @Column(name = "pwd")
    private String pwd;
	
    @Basic(optional = false)
    @Column(name = "gender")
    private char gender;	

    public Account() {
    }

    // other setters and getters   
}

Actually, the main suspect here is the attribute “gender”. It shows NullPointerException due to “gender” is a basic type ( char ) while the row “gender” in database is null.

(&) Weird isnt it?

A Simple Java RMI Tutorial

Java Remote Method Invocation (Java RMI) enables the programmer to create distributed Java technology-based to Java technology-based applications, in which the methods of remote Java objects can be invoked from other Java virtual machines, possibly on different hosts. RMI uses object serialization to marshal and unmarshal parameters and does not truncate types, supporting true object-oriented polymorphism.

Let’s just say RMI is the “older version” of ejb remote. Because in EJB, enterprise beans are made available for remote clients using RMI.

In this example, im trying to create 2 different project, one is the RMI Server and another one is RMI Client.

First is a simple interface, i will use this interface to create invocation methods and implementations. This interface will be on both Server’s and Client’s side.

package com.edw.rmi;

import java.rmi.Remote;
import java.rmi.RemoteException;

public interface Message extends Remote {
    void sayHello(String name) throws RemoteException;
}

and next is the implementation for my interface, it is exist only on the server’s side. It has to implements my interface and extends to UnicastRemoteObject class.

package com.edw.rmi;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;

public class MessageImpl extends UnicastRemoteObject implements Message {

    public MessageImpl() throws RemoteException {        
    }
    
    @Override
    public void sayHello(String name) throws RemoteException {
        System.out.println("hello "+name);
    }
    
}

And next is creating my server side application. Im running on port 1099 for RMI port.

package com.edw.main;

import com.edw.rmi.MessageImpl;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;

public class Main {
    
    private void startServer(){
        try {
            // create on port 1099
            Registry registry = LocateRegistry.createRegistry(1099);
            
            // create a new service named myMessage
            registry.rebind("myMessage", new MessageImpl());
        } catch (Exception e) {
            e.printStackTrace();
        }      
        System.out.println("system is ready");
    }
    
    public static void main(String[] args) {
        Main main = new Main();
        main.startServer();
    }
}

And this is my client’s side application

package com.edw.main;

import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
import com.edw.rmi.Message;

public class Main {
    
    private void doTest(){
        try {
			// fire to localhost port 1099
            Registry myRegistry = LocateRegistry.getRegistry("127.0.0.1", 1099);
			
			// search for myMessage service
            Message impl = (Message) myRegistry.lookup("myMessage");
			
			// call server's method			
            impl.sayHello("edwin");
			
            System.out.println("Message Sent");
        } catch (Exception e) {
            e.printStackTrace();
        }        
    }
    
    public static void main(String[] args) {
        Main main = new Main();
        main.doTest();
    }
}

This is the screenshot of what happen on my netbeans’ console, for my RMI client’s side

and RMI’s server side

and this is my netbeans’ project

While this is what RMI messages looks like

Have fun with RMI 🙂

Weird Blank Report When Using JasperReport

Yesterday, ive found a very weird error when im trying to print my report to pdf using jasper report. Somehow it show a blank report when i’m printing my report and my log file shows no error at all despite there is nothing on my pdf file. I’m using a simple servlet and jasper report classes to generate my pdf files and show it on browser.

This is what my report looks like

And this is part of my sourcecode

   protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
		// set header as pdf
        response.setContentType("application/pdf");

        // set input and output stream
        ServletOutputStream servletOutputStream = response.getOutputStream();   
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        FileInputStream fis;
        BufferedInputStream bufferedInputStream;
        
        String nama = "";
        String alamat = "";

        try {        	
        	if(request.getParameter("nama")!=null)
            	nama = request.getParameter("nama");
			
			if(request.getParameter("alamat")!=null)
				alamat = request.getParameter("alamat");
        	
        	// get report location
            ServletContext context = getServletContext();
            String reportLocation = context.getRealPath("WEB-INF");
            
            // get report
            fis = new FileInputStream(reportLocation + "/report/LaporanSatu.jasper");
            bufferedInputStream = new BufferedInputStream(fis);
            
            // fill parameters
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("nama", "%"+nama+"%");
            map.put("alamat", alamat);
                                               	
            // export to pdf            
            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(bufferedInputStream);
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, map);
            JasperExportManager.exportReportToPdfStream(jasperPrint, baos);

            response.setContentLength(baos.size());
            baos.writeTo(servletOutputStream);

            // close it
            fis.close();
            bufferedInputStream.close();            
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			servletOutputStream.flush();
            servletOutputStream.close();
            baos.close();
		}        
	}

Well the workaround is actually very easy, i only need to add a new empty datasource (JREmptyDataSource) in JasperFillManager parameters

   protected void doPost(HttpServletRequest request, HttpServletResponse response) 
        throws ServletException, IOException {
		// set header as pdf
        response.setContentType("application/pdf");

        // set input and output stream
        ServletOutputStream servletOutputStream = response.getOutputStream();   
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        
        FileInputStream fis;
        BufferedInputStream bufferedInputStream;
        
        String nama = "";
        String alamat = "";

        try {        	
        	if(request.getParameter("nama")!=null)
            	nama = request.getParameter("nama");
			
			if(request.getParameter("alamat")!=null)
				alamat = request.getParameter("alamat");
        	
        	// get report location
            ServletContext context = getServletContext();
            String reportLocation = context.getRealPath("WEB-INF");
            
            // get report
            fis = new FileInputStream(reportLocation + "/report/LaporanSatu.jasper");
            bufferedInputStream = new BufferedInputStream(fis);
            
            // fill parameters
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("nama", "%"+nama+"%");
            map.put("alamat", alamat);
                       
                        	
            // export to pdf            
            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(bufferedInputStream);
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, 
              map, new JREmptyDataSource());
            JasperExportManager.exportReportToPdfStream(jasperPrint, baos);

            response.setContentLength(baos.size());
            baos.writeTo(servletOutputStream);

            // close it
            fis.close();
            bufferedInputStream.close();
            
		} catch (Exception e) {
			e.printStackTrace();
		} finally{
			servletOutputStream.flush();
            servletOutputStream.close();
            baos.close();
		}        
	}

This is the screenshot for my successful report.

Error “java.lang.ClassNotFoundException: com.ibm.icu.text.SimpleDateFormat” When Deploying GWT Application

Today i’ve met a very weird error when trying to deploy my GWT application to my tomcat 7,

SEVERE: Exception while dispatching incoming RPC call
com.google.gwt.user.server.rpc.UnexpectedException: Service method 'public abstract java.util.List id.net.baculsoft.app.client.service. LoginService.getUtilDao(java.lang.String,java.util.Map)' 
threw an unexpected exception: java.lang.NoClassDefFoundError: com/ibm/icu/text/SimpleDateFormat
	at com.google.gwt.user.server.rpc.RPC. encodeResponseForFailure(RPC.java:385)
	at com.google.gwt.user.server.rpc.RPC. invokeAndEncodeResponse(RPC.java:588)
	at com.google.gwt.user.server.rpc.RPC. invokeAndEncodeResponse(RPC.java:551)
	at org.gwtrpcspring.RemoteServiceDispatcher. invokeAndEncodeResponse(RemoteServiceDispatcher.java:57)
	at org.gwtrpcspring.RemoteServiceDispatcher. processCall(RemoteServiceDispatcher.java:38)
	at com.google.gwt.user.server.rpc. RemoteServiceServlet.processPost(RemoteServiceServlet.java:248)
	at com.google.gwt.user.server.rpc. AbstractRemoteServiceServlet.doPost(AbstractRemoteServiceServlet.java:62)

which somehow, never happen on my development mode. After searching and trying various workarounds for several hours, i finally make it work by adding icu4j.jar. Well despite icu4j.jar’s size is more than 3mb, at least i’ve make my application running well. Thank God 😉

Creating a Pretty URL With Struts Framework and URLRewrite

On this tutorial im trying to create a pretty URL using one of java’s most famous framework, Struts Framework. I want to change a usual struts URL from news.do?id=newsID into a pretty URL such as news/newsID/newsTitle. The main benefits are your links get easily indexed by search engines and make them easy-to-read and easy-to-remember.

Im using urlrewrite library for url rewriting. As for this example, im using old version of struts 1.3.8 and iBatis ORM version 2.3.4.

First as always, a simple MySQL table

CREATE TABLE news
    (
        id bigint NOT NULL AUTO_INCREMENT,
        title VARCHAR(100) NOT NULL,
        content text NOT NULL,
        createddate DATETIME NOT NULL,
        PRIMARY KEY (id)
    )
	
insert into news 
        (id, title, content, createddate) 
        values (1, 'A Tale of Two More Earths?', 'Example of Content', '2011-12-26 19:00:00');
insert into news 
        (id, title, content, createddate) 
        values (2, 'India: Boat Capsizes; 11 Missing', 'Example of Content number 2', '2011-12-27 19:00:00');

and a javabean and xml for database mapping. And please be aware, im injecting Slugify class to getUrl method so i could get a clean url property inside this bean.

package com.edw.bean;

import com.edw.util.Slugify;
import java.util.Date;

public class News {

    private Long id;
    private String title;
    private Date createddate;
    private String content;
    
    // added for pretty URL
    private String url;

    // other getter and setter

    // do title formatting for a clean url
    public String getUrl() {
        return Slugify.slugify(getTitle());
    }

    public void setUrl(String url) {
        this.url = url;
    }
}

And this is my xml queries

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd" >
<sqlMap namespace="news" >
    
  <resultMap id="newsBean" class="com.edw.bean.News" >    
    <result column="id" property="id" jdbcType="BIGINT" />
    <result column="title" property="title" jdbcType="VARCHAR" />
    <result column="content" property="content" jdbcType="LONGVARCHAR" />
    <result column="createddate" property="createddate" jdbcType="TIMESTAMP" />
  </resultMap>  
  
  <select id="select" resultMap="newsBean" >    
    select id, title, createddate, content
    from news    
  </select> 
  
  <select id="selectWithId" resultMap="newsBean" parameterClass="java.lang.Integer" >    
    select id, title, createddate, content
    from news    
    where id = #id#
  </select> 
  
</sqlMap>

This is my utility java class, its main purpose is to encode and clean news titles so they can fit into URLs.

package com.edw.util;

import java.net.URLEncoder;
import java.text.Normalizer;
import org.apache.log4j.Logger;

public class Slugify {

    private static final Logger logger = Logger.getLogger(Slugify.class);
    
    /**
     * 
     * modified version of Jozef Ševcík's slugify
     * 
     * @link http://maddemcode.com/java/seo-friendly-urls-using-slugify-in-java/
     * @param input
     * @return formatted URL
     */
    public static String slugify(String input) {
        if (input == null || input.length() == 0) {
            return "";
        }
        
        try {
            String toReturn = normalize(input);            
            toReturn = toReturn.replaceAll("[^\\w\\s\\-]", "");
            toReturn = toReturn.replace(" ", "-");
            toReturn = toReturn.toLowerCase();
            toReturn = URLEncoder.encode(toReturn, "UTF-8");
            return toReturn;
        } catch (Exception e) {
            logger.error(e, e);
        }
        return "";

    }

    private static String normalize(String input) {
        if (input == null || input.length() == 0) {
            return "";
        }
        return Normalizer.normalize(input, Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "");
    }
}

And an xml file to load all my xml queries

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">

<sqlMapConfig>
    <settings
        useStatementNamespaces="true"
        lazyLoadingEnabled="true"
        enhancementEnabled="true"
        maxSessions="20"
        />

    <transactionManager type="JDBC" commitRequired="false">
        <dataSource type="SIMPLE">

            <property name="SetAutoCommitAllowed" value="false"/>
            <property name="DefaultAutoCommit" value="false"/>
            
            <property name="JDBC.Driver" value="com.mysql.jdbc.Driver"/>
            <!-- my database name = pepe -->
            <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/pepe"/>
            <property name="JDBC.Username" value="root"/>
            <property name="JDBC.Password" value="xxx"/>
   
        </dataSource>
    </transactionManager>

    <sqlMap resource="com/edw/sqlmap/news.xml"/>
    
</sqlMapConfig>

A java class to load my xml configuration

package com.edw.sqlmap.config;

import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import java.io.Reader;


public class SqlMapConfig {

    protected static final SqlMapClient sqlMap;

    static {
        try {
            Reader reader = Resources.getResourceAsReader("com/edw/sqlmap/sqlmapconfig.xml");
            sqlMap = SqlMapClientBuilder.buildSqlMapClient(reader);       
        } catch (Exception e){
            throw new RuntimeException("Fatal Error.  Cause: " + e, e);
        }
    }

    public static SqlMapClient getSqlMap() {
        return sqlMap;
    }
}

Next is im creating a Struts Action class

package com.edw.action;

import com.edw.bean.News;
import com.edw.sqlmap.config.SqlMapConfig;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

public class NewsAction extends org.apache.struts.action.Action {

    private static final String SUCCESS = "success";
    
    @Override
    public ActionForward execute(ActionMapping mapping, ActionForm form,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        
        List<News> newses = null;
        if(request.getParameter("id") != null)
            newses = SqlMapConfig.getSqlMap().queryForList("news.selectWithId", Integer.parseInt(request.getParameter("id")));       
        else
            newses = SqlMapConfig.getSqlMap().queryForList("news.select");       
        request.setAttribute("newses", newses);
        
        return mapping.findForward(SUCCESS);
    }        
}

dont forget to register NewsAction to strutsconfig.xml

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_3.dtd">

<struts-config>
    <form-beans></form-beans>
    
    <global-exceptions></global-exceptions>

    <global-forwards>
        <forward name="welcome"  path="/Welcome.do"/>
    </global-forwards>

    <action-mappings>
        <action path="/news" type="com.edw.action.NewsAction">
            <forward name="success" path="/WEB-INF/pages/news.jsp" />
        </action>
        <action path="/Welcome" forward="/welcomeStruts.jsp"/>
    </action-mappings>        

    <message-resources parameter="com/edw/res/ApplicationResource"/>    
    
</struts-config>

Next is my presentation layer. Im using a plain JSP and Struts tags, and put my JSP file under WEB-INF folder, so it cant be accessed directly.

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<!DOCTYPE html>

<%@taglib uri="http://struts.apache.org/tags-bean" prefix="bean"%>
<%@taglib uri="http://struts.apache.org/tags-logic" prefix="logic"%>

<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>News Page</title>
    </head>
    <body>
        <h1>News</h1>

        <logic:iterate name="newses" id="news">            
            <bean:write name="news" property="id"/> , 
            <bean:write name="news" property="title"/>, 
            <bean:write name="news" property="createddate"/>, 
            <bean:write name="news" property="content"/>            
            <br />
            <a href="${pageContext.request.contextPath}/news/<bean:write name="news" property="id"/>/<bean:write name="news" property="url"/>">link</a>
            <br />
            <br />
            <br />
            
        </logic:iterate>

    </body>
</html>

Next is where the magic of urlrewrite starts, first i register urlrewrite filter to my web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" 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-app_2_5.xsd">
    
    <filter>
        <filter-name>UrlRewriteFilter</filter-name>
        <filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>   
    </filter>
    <filter-mapping>
        <filter-name>UrlRewriteFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
        
    
    <servlet>
        <servlet-name>action</servlet-name>
        <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
        <init-param>
            <param-name>config</param-name>
            <param-value>/WEB-INF/struts-config.xml</param-value>
        </init-param>
        <init-param>
            <param-name>debug</param-name>
            <param-value>2</param-value>
        </init-param>
        <init-param>
            <param-name>detail</param-name>
            <param-value>2</param-value>
        </init-param>
        <load-on-startup>2</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>action</servlet-name>
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>
    
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
    
</web-app>

and create a urlrewrite xml under WEB-INF

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite PUBLIC "-//tuckey.org//DTD UrlRewrite 3.2//EN"
        "http://tuckey.org/res/dtds/urlrewrite3.2.dtd">

<urlrewrite>       
    
    <rule>
        <note>for news with parameters</note>
        <from>^/news/([0-9]+)/(.*)</from>
        <to>/news.do?id=$1</to>
    </rule> 
    
    <rule>
        <note>display all news</note>
        <from>^/news$</from>
        <to>/news.do</to>
    </rule> 

</urlrewrite>

The final result is my url path will be changed from

http://localhost:8084/StrutsPrettyURL/news.do
and
http://localhost:8084/StrutsPrettyURL/news.do?id=1

to

http://localhost:8084/StrutsPrettyURL/news
and
http://localhost:8084/StrutsPrettyURL/news/1/a-tale-of-two-more-earths

This are my netbeans project structure and libraries.

Have Fun (&)