Archive

Archive for the ‘EJB3’ Category

Seam,EJB3,Oracle Code Example .zip

January 5th, 2009

In my post JBoss Seam, JSF,Oracle and EJB3 Hello World  I gave a step by step example on how to set up a basic example using all of the aforementioned technologies,

I also provided code examples for each file you would need however over the Christmas holidays I discovered that the plug I use to display code did not correctly format XML files. I dont know why it just didnt. As I was on holiday I didnt have access to my machine which had my source code on it so it had to go uncorrected till today..

I have taken all the examples I give in the post zipped them up and uploaded them you can download the zip file at http://jdick.co.uk/blog/code/JSFExample.zip this is only the source code there are no supporting jars included in this you have to go find those yourself from the sources I mention in the post JBoss Seam, JSF,Oracle and EJB3 Hello World.

So download, use, learn, enjoy and please feel free to comment if you find I have screwed something up and Ill do my best to fix it

EJB3, JSF, Seam, Source, Tutorial , , ,

JBoss Seam, JSF,Oracle and EJB3 Hello World

December 8th, 2008

In this first post I shall show you how to setup a simple “Hello World” type application using JSF , JBoss Seam and EJB3, I shall also be persisting data to an Oracle 9i database.

This post is not a introduction to Seam post there are many sources out there which provide a far clearer introduction to Seam than I can provide, This article is simply meant as a guide to getting Seam up and running. I initially had problems getting the basic demos up and running and found myself attempting to tie together multiple forum posts, blogs and tutorials to get a complete end to end setup working.

If you do require a Introduction to Seam I suggest the JBoss Seam manual

Or Micheal Yuan and Thomas Heutes book JBoss Seam: Simplicity and Power Beyond Java EE

Environment Setup:

I am using IntelliJ 8 as my IDE
Java JDK 1.5.0_09
I am running JBoss version 4.2.3 GA JBoss download page
with Seam version 2.1.0 SP1 Seam download page
I am also running a Oracle 9i server and using TOAD as a schema browser.

1. Extract JBoss, my JBoss is located at C:\JBoss-4.2.3.GA
2. Create a new project, In your IDE of choice create a new project called JSFExample. C:\JSFExample

3. Create the following directory structure: ignore the various properties files just now we will come back to them.

4. Setup your classpath the following jar files are required to get this example to work, almost all of these are found in the Seam 2.1.0 SP1 lib directory, with the exception of javaee.jar which is part of IntelliJ and ojdbc14.jar which is required in order to connect to an Oracle database. This can be downloaded from the Oracle site at Oracle download page

5. For simplicity’s sake copy these files with the exception of javaee.jar to the lib directory of your JBoss C:\JBoss-4.2.3.GA\server\default\lib and to the supportingJars directory for our project C:\JSFExample\supportingJars.
6. Start the JBoss server and make sure it starts successfully.

Database setup

In this example we will be entering information for some users, persisting this data to the database and returning a list of all users on successful submit. So create the following table in your database:

CREATE TABLE USERS
(
ID INTEGER NOT NULL,
NAME VARCHAR2(256 BYTE) NOT NULL,
PHONENUMBER VARCHAR2(16 BYTE),
ADDRESS VARCHAR2(256 BYTE),
CITY VARCHAR2(256 BYTE),
EMAIL VARCHAR2(256 BYTE),
AGE VARCHAR2 (3 BYTE)
)

OK so its not the best table in the world it but it serves our purpose for now, we also need a sequence to use with our primary key ID,

CREATE SEQUENCE USERS_S
START WITH 1

Coding – Server,

 

[UPDATE]Due to problems with the plugin thing I use to show code XML files tend to get a bit messed up and well, broken. I have uploaded the source to  http://jdick.co.uk/blog/code/JSFExample.zip None of the supporting jars are in this zip for bandwidth reasons you still have to go and get them yourself[/UPDATE] 

 

Users.java

So now we are almost finished setup lets get some code down. Start by creating a entity bean called Users in beans.com.jsf


package com.jsf;

import static org.jboss.seam.ScopeType.SESSION;
import java.io.Serializable;
import javax.persistence.*;
import org.hibernate.validator.Length;
import org.jboss.seam.annotations.Name;
import org.jboss.seam.annotations.Scope;

@Entity
@Name("userdetails")
@Table(name = "USERS")
@Scope(SESSION)
@SequenceGenerator(name = "USER_SEQUENCE_GENERATOR", sequenceName = "USERS_S")
public class Users implements Serializable {
public Users() {
}

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "USER_SEQUENCE_GENERATOR")
public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

@Column(nullable = false)
@Length(min = 5, max = 25)
public String getAddress() {
return address;
}

public void setAddress(String address) {
this.address = address;
}

@Column(nullable = false)
@Length(min = 1, max = 3)
public String getAge() {
return age;
}

public void setAge(String age) {
this.age = age;
}

@Column(nullable = false)
@Length(min = 5, max = 15)
public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

@Column(nullable = false)
@Length(min = 5, max = 30)
public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

@Column(nullable = false)
@Length(min = 5, max = 30)
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Column(nullable = false)
@Length(min = 5, max = 13)
public String getPhoneNumber() {
return phoneNumber;
}

public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}

private int id;
private String name;
private String phoneNumber;
private String address;
private String city;
private String email;
private String age;
}

note the name of the bean is “userdetails” this will be important later.

UserControllerBean.java

Next we need a session bean to carry out our operations. This could be a normal backing bean but I use EJB3 so a session bean it is, in this case a stateless session bean.


package com.jsf;

import javax.ejb.*;
import javax.persistence.*;
import java.util.List;
import org.jboss.seam.annotations.*;
import org.jboss.seam.annotations.datamodel.DataModel;

@Stateless
@Name("userBean")
@Local(value = Controller.class)
public class UserControllerBean implements Controller {

@In
private Users userdetails;

@PersistenceContext
private EntityManager em;

@DataModel
private List items = null;

public void count(String count) {
}

public String count() {
em.merge(userdetails);
return "/registered.seam";
}

@Factory("items")
public void getItems() {
List list = em.createQuery(FIND_ALL).getResultList();
items = list;
}

public static final String FIND_ALL = "SELECT userreturn FROM Users userreturn";
}

Controller.java

The last class we need is the Controller Interface so we can call the session bean from our web client.


package com.jsf;

import javax.ejb.Local;

@Local
public interface Controller {
public String count();
public void count(String count);
public void getItems();
}

Coding – Front End

In the web/resources directory create the following files

index.html

<html>
<head>
<meta http-equiv="Refresh" content="0; URL=register.seam">
</meta></head>
</html>

register.xhtml

< ?xml version="1.0" encoding="utf-8"?>
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">

<head>
<title>Register New User</title>
</head>
<f :view>
<h :form>
<s :validateAll>
<h :panelGrid columns="2">
Name: <h :inputText value="#{userdetails.name}" required="true"/>
Address: <h :inputText value="#{userdetails.address}" required="true"/>
City: <h :inputText value="#{userdetails.city}" required="true"/>
Email: <h :inputText value="#{userdetails.email}" required="true"/>
Phone Number: <h :inputText value="#{userdetails.phoneNumber}" required="true"/>
Age <h :inputText value="#{userdetails.age}" required="true"/>
</h>
</s>
<h :messages/>
<h :commandButton value="Register" action="#{userBean.count}"/>
</h>
</f>
</html>

Note that the value of the inputs is referred to as #{userdetails.name} the “userdetails” is the name of our entity bean and it is important that these match, when I was attempting to learn Seam I found quite a few examples which used a generic “user” variable everywhere with out pointing out the importance of this naming. Yes it may Seam obvious now but I’ve never been very good at picking up the obvious.

registered.xhtml


< ?xml version="1.0" encoding="utf-8"?>
< !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:s="http://jboss.com/products/seam/taglib"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">

<head>
<title>Successfully Registered New User</title>
</head>
<body>
<h :dataTable var="userreturn" value="#{items}" rendered="#{items.rowCount>0}" id="ResultsTable" >
</h><h :column>
<f :facet name="header">
<h :o utputText value="Name"/>
</f>
<h :o utputText value="#{userreturn.name}"/>
</h>
<h :column>
<f :facet name="header">
<h :o utputText value="Address"/>
</f>
<h :o utputText value="#{userreturn.address}"/>
</h>
<h :column>
<f :facet name="header">
<h :o utputText value="Phone Number"/>
</f>
<h :o utputText value="#{userreturn.phoneNumber}"/>
</h>
<h :column>
<f :facet name="header">
<h :o utputText value="City"/>
</f>
<h :o utputText value="#{userreturn.city}"/>
</h>
<h :column>
<f :facet name="header">
<h :o utputText value="Email"/>
</f>
<h :o utputText value="#{userreturn.email}"/>
</h>
<h :column>
<f :facet name="header">
<h :o utputText value="Age"/>
</f>
<h :o utputText value="#{userreturn.age}"/>
</h>

</body>
</html>

Another thing to note is if you are calling a method on the entity bean you miss out the prefix get/set so you use, “userdetails.name” and not “userdetails.setName” however if you are calling a method on the session bean you use the full method name as it is in the interface.

Config

OK so thats the code written but we still need to put all the various config files in place to get everything talking.

beans/META-INF

create the following files:

ejb-jar.xml

<ejb -jar 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/ejb-jar_3_0.xsd"
version="3.0">

<interceptors>
<interceptor>
</interceptor><interceptor -class>org.jboss.seam.ejb.SeamInterceptor</interceptor>

</interceptors>

<assembly -descriptor>
<interceptor -binding>
<ejb -name>*</ejb>
</interceptor><interceptor -class>org.jboss.seam.ejb.SeamInterceptor</interceptor>

</assembly>

</ejb>

persistance.xml

<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
</persistence><persistence -unit name="jsf">
<provider>
org.hibernate.ejb.HibernatePersistence
</provider>
<jta -data-source>
java:/OracleDS
</jta>
<properties>
<property name="hibernate.dialect"
value="org.hibernate.dialect.Oracle9Dialect"/>
<property name="hibernate.hbm2ddl.auto"
value="none"/>
</properties>
</persistence>

This persistance.xml is one specifically for a use with a standalone Oracle it will not overwrite any existing tables nor will it create any tables which do not all ready exist

In the root of beans create a file called Seam.properties this file is empty and is only needed in order to let the application know Seam is being used.

JSFExample/META-INF

application.xml

< ?xml version="1.0" encoding="UTF-8"?>
<application 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/application_5.xsd"
version="5">
<display -name>MyApp</display>
<module id="EJB">
<ejb>jsf.jar</ejb>
</module>
<module id="Web">
<web>
</web><web -uri>jsf.war</web>
<context -root>web</context>

</module>
</application>

and ejb-jar.xml the is the same code as shown above

web/WEB_INF

components.xml

< ?xml version="1.0" encoding="UTF-8"?>
<components xmlns="http://jboss.com/products/seam/components"
xmlns:core="http://jboss.com/products/seam/core"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation=
"http://jboss.com/products/seam/core http://jboss.com/products/seam/core-2.1.xsd
http://jboss.com/products/seam/components http://jboss.com/products/seam/components-2.1.xsd">

<core :init jndi-pattern="jsf/#{ejbName}/local"/>

</components>

faces-config.xml

< ?xml version="1.0" encoding="UTF-8"?>
<faces -config version="1.2"
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">

<!-- Facelets support -->
<application>
<view -handler>com.sun.facelets.FaceletViewHandler</view>
</application>

</faces>

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">

<!-- Seam -->

<listener>
</listener><listener -class>org.jboss.seam.servlet.SeamListener</listener>

<context -param>
<param -name>javax.faces.DEFAULT_SUFFIX</param>
<param -value>.xhtml</param>
</context>

<servlet>
</servlet><servlet -name>Faces Servlet</servlet>
<servlet -class>javax.faces.webapp.FacesServlet</servlet>
<load -on-startup>1</load>

<servlet -mapping>
</servlet><servlet -name>Faces Servlet</servlet>
<url -pattern>*.seam</url>

<session -config>
</session><session -timeout>10</session>

</web>

Build script

The following is the build.xml and build.properties I have used for this example and It should work for you providing you have ANT installed and you have followed the same directory structure I have, with my project in C:\JSFExample and my JBoss in C:\JBoss-4.2.3.GA

build.xml

< ?xml version="1.0"?>
<project default="deployDevelopmentEar">

<property environment="env"/>
<property file="build.properties"/>

<path id="compile.classpath">
<pathelement location="${servlet.api.jar}"/>
<pathelement location="${jsp.api.jar}"/>
<pathelement location="${el.api.jar}"/>
<pathelement location="${jsf.api.jar}"/>
<pathelement location="${lib.dir}/jboss-seam.jar"/>
</path>

<target name="clean">
<delete dir="${dest.dir}"/>
<mkdir dir="${dest.dir}"/><code>
</code></target>

<target name="compileAll" depends="clean">
<javac compiler="modern" source="1.5" destdir="${dest.dir}">
<classpath refid="compile.classpath"/>
<src path="${web_module.src}"/>
<src path="${libs_modules.src}"/>
</javac>
</target>

<target name="createBeansJar" depends="clean">
<mkdir dir="${dest.dir}/beans"/>
<javac compiler="modern" source="1.5" destdir="${dest.dir}/beans">
<classpath location="${lib.dir}/jsf-api.jar"/>
<classpath location="${lib.dir}/jboss-seam.jar"/>
<classpath location="${lib.dir}/javaee.jar"/>
<classpath location="${lib.dir}/hibernate3.jar"/>
<classpath location="${lib.dir}/hibernate-annotations.jar"/>
<src path="${beans_module.src}"/>
</javac>
<copy file="${beans_module.src}/seam.properties" todir="${dest.dir}/beans"/>

<jar destfile="${dest.dir}/jsf.jar" basedir="${dest.dir}/beans">
<metainf dir="${beans_module.src}/META-INF">
<include name="**/*.*"/>
</metainf>
</jar>
</target>

<target name="createDeployBeansJar">
<mkdir dir="${dest.dir}/beans"/>
<javac compiler="modern" source="1.5" destdir="${dest.dir}/beans">
<classpath location="${lib.dir}/javaee.jar"/>
<src path="${beans_module.src}"/>
</javac>
<jar destfile="${dest.dir}/jsf.jar" basedir="${dest.dir}/beans">
<metainf dir="${beans_module.src}/META-INF">
<include name="**/*.*"/>
</metainf>
</jar>
<copy file="${dest.dir}/jsf.jar" todir="${jboss.deploy.dir}"/>
</target>

<target name="createWebWar" depends="createBeansJar">
<mkdir dir="${dest.dir}/web"/>
<war destfile="${dest.dir}/jsf.war" webxml="${web_module.src}/../WEB-INF/web.xml">

<fileset dir="${web_module.src}/../resources"/>

<webinf dir="${web_module.src}/../WEB-INF">
<include name="**/*.*"/>
<exclude name="**/web.xml"/>
</webinf>
<metainf dir="${web_module.src}/../META-INF">
<include name="**/*.*"/>
</metainf>
<lib dir="${lib.dir}">
<include name="jboss-seam-ui.jar"/>
<include name="jsf-facelets.jar"/>
<include name="commons-beanutils.jar"/>
</lib>
</war>
</target>

<target name="createEar" depends="createWebWar">
<copy file="${lib.dir}/jboss-seam.jar" todir="${dest.dir}"/>
<copy file="${lib.dir}/jboss-el.jar" todir="${dest.dir}"/>
<ear destfile="${dest.dir}/jsf.ear" appxml="META-INF/application.xml">

<fileset dir="${dest.dir}" includes="*.jar, *.war"/>
</ear>
</target>

<target name="deployDevelopmentEar" depends="createEar">
<copy file="${dest.dir}/jsf.ear" todir="${jboss.deploy.dir}"/>
</target>

</project>

build.properties

web_module.src=web/src
beans_module.src=beans
libs_modules.src=libs/src

dest.dir=dest
results=results
lib.dir=C:/JSFExample/supportingJars

jboss.deploy.dir=C:/jboss-4.2.3.GA/server/default/deploy
jboss.lib.dir=C:/jboss-4.2.3.GA/server/default

servlet.api.jar=C:/jboss-4.2.3.GA/server/default/lib/servlet-api.jar
jsp.api.jar=C:/jboss-4.2.3.GA/server/default/lib/jsp-api.jar
el.api.jar=C:/jboss-4.2.3.GA/server/default/lib/el-api.jar
jsf.api.jar=${lib.dir}/jsf-api.jar

jsf.lib.dir=${jsf.dir}/lib
jstl.lib.dir=${tomcat.dir}/lib

jsf.libs=jsf-api.jar,jsf-impl.jar
jstl.libs=jstl.jar,standard.jar

Run the build script. It should run successfully and copy a file called jsf.ear to your JBoss deploy directory.

While In this directory we need to create a datasource so we can connect to the database.
Create the following file and call it Oracle-ds.xml

Oracle-ds.xml

< ?xml version="1.0" encoding="UTF-8"?>
<datasources>
<local -tx-datasource>
<jndi -name>OracleDS</jndi>
<connection -url>jdbc:oracle:thin:@[URL]</connection>

<driver -class>oracle.jdbc.driver.OracleDriver</driver>
<user -name>[USER]</user>
<password>[PASSWORD]</password>

<exception -sorter-class-name>org.jboss.resource.adapter.jdbc.vendor.OracleExceptionSorter
</exception>

<metadata>
<type -mapping>Oracle9i</type>
</metadata>
</local>

</datasources>

replace [USER] with the username for your database, [PASSWORD] with the password and [URL] with the correct database URL.

Testing

Once complete we are good to go.
Start the JBoss and navigate to http://localhost:8080/web

you should see

fill in the details and press the button and you will see the results table:

This concludes this example I hope it helps you. This is the first time I have attempted to write a tutorial like this so please let me know if it was helpful, constructive criticism’s is also welcome.

EJB3, Seam, Tutorial , , , , , , , , , , , , ,

Here we go again

December 3rd, 2008

Ok,  here I go with another blog another attempt to keep it upto date.

I have recently been playing about with JSF and Jboss Seam and was unable to find a good end to end tutorial, so some time soon Im planing a series of posts detailing how to set this up and hopefully include a few examples ranging from a “Hello World” to something a bit cooler with drag and drop and trees.

Will get something up over the weekend or later this week if i have some free time at work

EJB3, Seam, Tutorial