Java

java

Executing EJB3 Using Glassfish 3 AppClient

On my last EJB3 tutorial, im still using the old fashioned way of EJB3. Still importing lots of jars, which is very dangerous due to the fact that sometimes i forgot which jar i need to include.

That’s why now im trying to use one of Glassfish’s feature application, appclient. It can bundle all the libraries and dependencies your EJB client needed, so it save your time from including various Glassfish’s jars to your project.

Lets start with a very simple ejb interface class,

package com.edw.facade;

public interface ConnectionFacadeRemote {
    String sayHello(String string);
    int sayAge(int age);
}

And a simple main class,

package com.edw.main;

import com.edw.facade.ConnectionFacadeRemote;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import org.apache.log4j.Logger;

public class Main {

    private Logger logger = Logger.getLogger(Main.class);
    
    private void connect() {
        try{
            Properties props = new Properties();
            props.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.enterprise.naming.SerialInitContextFactory");
            props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");
            props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");
            
            InitialContext ctx = new InitialContext();
            ConnectionFacadeRemote connectionFacadeRemote = (ConnectionFacadeRemote) ctx.lookup("com.edw.facade.ConnectionFacadeRemote");
            logger.debug(connectionFacadeRemote.sayHello("edwin ")); 
            logger.debug("my age is " + connectionFacadeRemote.sayAge(12) + " years");
        }catch(Exception ex){
            logger.error(ex,ex);
        }
    }

    public static void main(String[] args) {
        Main tejbc = new Main();
        tejbc.connect();
    }
}

After you create all classes needed, you have to build your application into .jar.
Next is to pull all the jar needed for this EJB client application to run smoothly. First go to your Server glassfish’s bin folder located in your Server glassfish installation folder, in my PC it would be (C:\Program Files\glassfish-3.0.1\glassfish\bin). And execute the package-appclient command.

C:\Program Files\glassfish-3.0.1\glassfish\bin>package-appclient
Creating C:\Program Files\glassfish-3.0.1\glassfish\lib\appclient.jar

It would create a jar file, appclient.jar, which located in your glassfish lib installation folder.

Next is copy your appclient.jar into your client computers. Extract it, and execute appclient command. The appclient format would be, appclient -jar .

C:\Users\edw\Documents\appclient\appclient\glassfish\bin>appclient -jar "C:\Users\edw\Documents\NetBeansProjects\TestEJBClient\dist\TestEJBClient.jar"
Apr 19, 2012 6:28:03 PM com.sun.enterprise.transaction.JavaEETransactionManagerSimplified initDelegates
INFO: Using com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate as the delegate
2012-04-19 18:28:10,067 [Main] DEBUG com.edw.main.Main:22 - hello edwin
2012-04-19 18:28:10,072 [Main] DEBUG com.edw.main.Main:23 - my age is 24 years

You can see the server side’s source code here. And here is my netbeans project structure

Not too hard right 😉

Beginning REST Using JBoss RESTEasy

On today’s demo im trying to use RESTEasy to handle multiple REST requests. According to Wikipedia, REST (Representational state transfer) is a style of software architecture for distributed hypermedia systems such as the World Wide Web. While RESTEasy is a JBoss project that provides various frameworks to help you build RESTful Web Services and RESTful Java applications. It is a fully certified and portable implementation of the JAX-RS specification. JAX-RS is a new JCP specification that provides a Java API for RESTful Web Services over the HTTP protocol.

On this project, im trying to create 2 different services. 1 service to get all objects, while another one for fetching a single objects. I create 2 different responses type for each service, JSON and XML. Okay, so lets try with 2 simple javabeans.

package com.edw.bean;

import java.util.List;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Student {

    private String name;
    private String address;
    private int age;

    @XmlElement(name="book")
    @XmlElementWrapper(name = "books")
    private List<Book> books;

    public Student() {
    }

    public Student(String name, String address, int age, List<Book> books) {
        this.name = name;
        this.address = address;
        this.age = age;
        this.books = books;
    }

	// other setter getter

    @Override
    public String toString() {
        return "Student{" + "name=" + name + ", address=" + address + ", age=" + age + ", books=" + books + '}';
    }
}
package com.edw.bean;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class Book {

    private String title;
    private double price;

    public Book() {
    }

    public Book(String title, double price) {
        this.title = title;
        this.price = price;
    }

	// other setter getter

    @Override
    public String toString() {
        return "Book{" + "title=" + title + ", price=" + price + '}';
    }
}

Now, you need to create a java class to handle all REST services,

package com.edw.rest;

import com.edw.bean.Book;
import com.edw.bean.Student;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/service/student")
public class StudentRest {

    @GET
    @Path("/json")
    @Produces(MediaType.APPLICATION_JSON)
    // path would be http://localhost:8080/YourProject/service/student/json
    public List<Student> getStudentsJSON() {
        return getStudents();
    }

    @GET
    @Path("/xml")
    @Produces(MediaType.APPLICATION_XML)
    // path would be http://localhost:8080/YourProject/service/student/xml
    public List<Student> getStudentsXML() {
        return getStudents();
    }

    @GET
    @Path("/json/{name}")
    @Produces(MediaType.APPLICATION_JSON)
    // path would be http://localhost:8080/YourProject/service/student/json/insertyournamehere
    public Student getStudentJSON(@PathParam("name") String name) {
        return new Student(name, name + " Address", 10, getBooks());
    }

    @GET
    @Path("/xml/{name}")
    @Produces(MediaType.APPLICATION_XML)
    // path would be http://localhost:8080/YourProject/service/student/xml/insertyournamehere
    public Student getStudentXML(@PathParam("name") String name) {
        return new Student(name, name + " Address", 10, getBooks());
    }

    private List<Book> getBooks() {
        List<Book> books = new ArrayList<Book>();
        books.add(new Book("Harry Potter", 100d));
        books.add(new Book("Lord of the Ring", 120d));
        books.add(new Book("Chicken Soup", 20d));
        books.add(new Book("Doraemon", 190d));
        books.add(new Book("Laskar Pelangi", 200d));
        return books;
    }

    private List<Student> getStudents() {
        List<Student> students = new ArrayList<Student>();
        students.add(new Student("Edwin", "Jakarta", 25, getBooks()));
        students.add(new Student("Kamplenk", "Ciledug", 29, getBooks()));
        students.add(new Student("Tebek", "Pamulang", 38, getBooks()));
        students.add(new Student("Syamsu", "Bandung", 60, getBooks()));
        return students;
    }
}

And dont forget to register your service class

package com.edw.config;

import com.edw.rest.StudentRest;
import java.util.Set;
import java.util.HashSet;
import javax.ws.rs.core.Application;

public class ApplicationConfig extends Application {

    private Set<Object> singletons = new HashSet<Object>();
    private Set<Class<?>> empty = new HashSet<Class<?>>();

    public ApplicationConfig() {
        singletons.add(new StudentRest());
    }

    @Override
    public Set<Class<?>> getClasses() {
        return empty;
    }

    @Override
    public Set<Object> getSingletons() {
        return singletons;
    }
}

And last, register all in your web.xml file

<?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">
    <servlet>
        <servlet-name>Resteasy</servlet-name>
        <servlet-class>
            org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
        </servlet-class>
        <init-param>
            <param-name>javax.ws.rs.Application</param-name>
            <param-value>com.edw.config.ApplicationConfig</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>Resteasy</servlet-name>
        <url-pattern>/service/*</url-pattern>
    </servlet-mapping>

    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
    </welcome-file-list>
</web-app>

Here are some screenshots,

Have fun with RESTEasy 😉

A Simple Java Desktop JasperReport Example

Hi, im currently testing the latest version of iReport, iReport 4.5.1. For the test, im trying to create a very simple reporting, consist of 2 column and without database connection. Im using a simple Array of Maps to fill my jasper report’s data using the JRMapCollectionDataSource class.

Here is my report example,

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="report" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20">
	<property name="ireport.zoom" value="1.0"/>
	<property name="ireport.x" value="0"/>
	<property name="ireport.y" value="0"/>
	<field name="name" class="java.lang.String"/>
	<field name="address" class="java.lang.String"/>
	<background>
		<band splitType="Stretch"/>
	</background>
	<title>
		<band height="31" splitType="Stretch">
			<staticText>
				<reportElement x="235" y="0" width="100" height="31"/>
				<textElement>
					<font size="24"/>
				</textElement>
				<text><![CDATA[Judul Saya]]></text>
			</staticText>
		</band>
	</title>
	<pageHeader>
		<band height="35" splitType="Stretch"/>
	</pageHeader>
	<columnHeader>
		<band height="22" splitType="Stretch">
			<staticText>
				<reportElement x="0" y="2" width="100" height="20"/>
				<textElement/>
				<text><![CDATA[name]]></text>
			</staticText>
			<staticText>
				<reportElement x="200" y="2" width="100" height="20"/>
				<textElement/>
				<text><![CDATA[address]]></text>
			</staticText>
		</band>
	</columnHeader>
	<detail>
		<band height="20" splitType="Stretch">
			<textField>
				<reportElement x="0" y="0" width="200" height="20"/>
				<textElement/>
				<textFieldExpression><![CDATA[$F{name}]]></textFieldExpression>
			</textField>
			<textField>
				<reportElement x="200" y="0" width="221" height="20"/>
				<textElement/>
				<textFieldExpression><![CDATA[$F{address}]]></textFieldExpression>
			</textField>
		</band>
	</detail>
	<columnFooter>
		<band height="13" splitType="Stretch"/>
	</columnFooter>
	<pageFooter>
		<band height="14" splitType="Stretch"/>
	</pageFooter>
	<summary>
		<band height="8" splitType="Stretch"/>
	</summary>
</jasperReport>

Dont forget to compile it, and this is my java code to call my report. It call for .jasper file instead of .jrxml files.

package com.edw.main;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.util.ArrayList;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRMapCollectionDataSource;
import net.sf.jasperreports.engine.util.JRLoader;
import net.sf.jasperreports.view.JasperViewer;
import org.apache.log4j.Logger;

public class Main {

    private Logger logger = Logger.getLogger(Main.class);

    public Main() {
    }

    private void start() {
        try {                                            
            // load report location
            FileInputStream fis = new FileInputStream("report.jasper");
            BufferedInputStream bufferedInputStream = new BufferedInputStream(fis);

            // fill report
            List<Map<String,?>> maps = new ArrayList<Map<String, ?>> (); 
            for (int i = 0; i < 10; i++) {
                Map<String,Object> map = new HashMap<String, Object>();
                map.put("name", getRandomString());
                map.put("address", getRandomString());
                maps.add(map);
            }            
            JRMapCollectionDataSource dataSource = new JRMapCollectionDataSource(maps);
            
            // compile report
            JasperReport jasperReport = (JasperReport) JRLoader.loadObject(bufferedInputStream);
            JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, new HashMap(), dataSource);

            // view report to UI
            JasperViewer.viewReport(jasperPrint, false);

        } catch (Exception e) {
            logger.error(e, e);
        }
    }
    
    private String getRandomString(){
        return UUID.randomUUID().toString();
    }

    public static void main(String[] args) {
        Main main = new Main();
        main.start();
    }
}

And some screenshots from my project,

Have fun with Jasper Report 😉

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 🙂