Monday, December 28, 2009

AOP in Spring Example

package aop;

/**
* Created by IntelliJ IDEA.
* User: Gayan-Laptop
* Date: Dec 22, 2009
* Time: 1:49:12 AM
* To change this template use File | Settings | File Templates.
*/

public interface Adder {

public int add(int a, int b);


}



=====================================================

package aop;

/**
* Created by IntelliJ IDEA.
* User: Gayan-Laptop
* Date: Dec 22, 2009
* Time: 1:51:13 AM
* To change this template use File | Settings | File Templates.
*/


public class AdderImpl implements Adder {

public int add(int a, int b) {
return a + b;
}

}

===============================================================

package aop;/**
* Created by IntelliJ IDEA.
* User: Gayan-Laptop
* Date: Dec 22, 2009
* Time: 1:53:20 AM
* To change this template use File | Settings | File Templates.
*/

import org.springframework.aop.AfterReturningAdvice;

import java.lang.reflect.Method;

public class LogAfterReturningAdvice implements AfterReturningAdvice {

public void afterReturning(Object returnValue, Method method, Object[] args,
Object target) throws Throwable {

System.out.println("After Normal Return from Method (here you can remove attribute in session )");
}

}
=============================================================
package aop;/**
* Created by IntelliJ IDEA.
* User: Gayan-Laptop
* Date: Dec 22, 2009
* Time: 1:53:53 AM
* To change this template use File | Settings | File Templates.
*/

import org.springframework.aop.ThrowsAdvice;

import java.lang.reflect.Method;

public class LogAfterThrowsAdvice implements ThrowsAdvice {

public void afterThrowing(Method method, Object[] args, Object target,
Exception exception) {

System.out.println("Exception is thrown on method " + method.getName());
}

}
======================================================
package aop;/**
* Created by IntelliJ IDEA.
* User: Gayan-Laptop
* Date: Dec 22, 2009
* Time: 1:54:23 AM
* To change this template use File | Settings | File Templates.
*/

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class LogAroundAdvice implements MethodInterceptor {

public Object invoke(MethodInvocation methodInvocation) throws Throwable {
System.out.println("LogAroundAdvice invoke method (here you can check method Arguments validation) ");
Object arguments[] = methodInvocation.getArguments();
int number1 = ((Integer) arguments[0]).intValue();
int number2 = ((Integer) arguments[1]).intValue();

if (number1 == 0 && number2 == 0) {
throw new Exception("Dont know how to add 0 and 0!!!");
}

if(number2==0){
throw new Exception("Dont know how to divide by 0 !!!");
}

return methodInvocation.proceed();
}
}

==========================================================
package aop;/**
* Created by IntelliJ IDEA.
* User: Gayan-Laptop
* Date: Dec 22, 2009
* Time: 1:52:11 AM
* To change this template use File | Settings | File Templates.
*/

import org.springframework.aop.MethodBeforeAdvice;

import java.lang.reflect.Method;

public class LogBeforeCallAdvice implements MethodBeforeAdvice {

public void before(Method method, Object[] args, Object target) {
System.out.println("Before Calling the Method (here you can check user sessions) ");
}

}
=======================================================
package aop;

/**
* Created by IntelliJ IDEA.
* User: Gayan-Laptop
* Date: Dec 22, 2009
* Time: 2:18:15 AM
* To change this template use File | Settings | File Templates.
*/

import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;

public class AdderTest {

public static void main(String args[]) {
try {
Resource resource = new FileSystemResource("./aop-test.xml");
BeanFactory factory = new XmlBeanFactory(resource);

try{
Adder adder = (Adder) factory.getBean("adder");
System.out.println("------------- TEST CASE 1 ---------------");
int result = adder.add(10, 10);
System.out.println("Result = " + result);
System.out.println("------------- TEST CASE 2 ---------------");
result = adder.add(100, 10);
System.out.println("Result = " + result);
System.out.println("------------- TEST CASE 3 ---------------");
result = adder.add(101, 110);
System.out.println("Result = " + result);
System.out.println("------------- TEST CASE 4 ---------------");
result = adder.add(0, 0);
System.out.println("Result = " + result);
}catch(Exception e){
e.printStackTrace();
}

try{
Divider divider = (Divider) factory.getBean("divider");

System.out.println("------------- TEST CASE 5 ---------------");
int result2 = divider.divide(6,3);
System.out.println("Result = " + result2);
System.out.println("------------- TEST CASE 6 ---------------");
result2 = divider.divide(12,3);
System.out.println("Result = " + result2);
System.out.println("------------- TEST CASE 7 ---------------");
result2 = divider.divide(16,3);
System.out.println("Result = " + result2);
System.out.println("------------- TEST CASE 9 ---------------");
result2 = divider.divide(6,0);
System.out.println("Result = " + result2);


}catch(Exception e){
e.printStackTrace();
}



} catch (Exception e) {
e.printStackTrace();
}
}
}


================================================================

aop-test.xml file


<beans xmlns="http://www.springframework.org/schema/beans"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">





<!-- Advices -->

<bean id="beforeCall" class="aop.LogBeforeCallAdvice"/>

<bean id="afterCall" class="aop.LogAfterReturningAdvice"/>

<bean id="throwCall" class="aop.LogAfterThrowsAdvice"/>

<bean id="aroundCall" class="aop.LogAroundAdvice"/>



<!-- Implementation Class -->

<bean id="adderImpl" class="aop.AdderImpl"/>

<bean id="dividerImpl" class="aop.DividerImpl"/>



<!-- Proxy Implementation Class -->

<bean id="adder" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="proxyInterfaces">

<value>aop.Adder</value>

</property>

<property name="interceptorNames">

<list>

<value>beforeCall</value>

<value>afterCall</value>

<value>throwCall</value>

<value>aroundCall</value>

</list>

</property>

<property name="target">

<ref bean="adderImpl"/>

</property>

</bean>



<bean id="divider" class="org.springframework.aop.framework.ProxyFactoryBean">

<property name="proxyInterfaces">

<value>aop.Divider</value>

</property>

<property name="interceptorNames">

<list>

<value>beforeCall</value>

<value>afterCall</value>

<value>throwCall</value>

<value>aroundCall</value>

</list>

</property>

<property name="target">

<ref bean="dividerImpl"/>

</property>

</bean>



</beans>

Monday, December 21, 2009

jdom Example

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

<database>

<main id="jdbcconnecter">

<driver id="jdbc">oracle.jdbc.driver.OracleDriver</driver>

<url id="java mysql">jdbc:oracle:thin:@XXXXXXXX:XXX</url>

<username uname="defult">XXXX</username>

<password password="defult">XXX</password>

</main>

</database>

 








public void setConnectionData(){

try{
String filename ="dataconnect.xml";
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(new File(filename));
Element root = doc.getRootElement();
List servlets = root.getChildren("main");
Iterator i = servlets.iterator();
while (i.hasNext()) {
Element servlet = (Element) i.next();
driver= servlet.getChild("driver").getTextTrim();
url=servlet.getChild("url").getTextTrim();
username=servlet.getChild("username").getTextTrim();
password=servlet.getChild("password").getTextTrim();

}//end while


}catch(Exception e){
e.printStackTrace();
}


}

Wednesday, December 16, 2009

Ant Script to compile,deploy,test EJB Appication

<project name="jblog" default="ear">

<property environment="env"/>

<property name="jboss.home" value="${env.JBOSS_HOME}"/>

<property name="jboss.server.dir" value="${jboss.home}/server/default"/>

<property name="jboss.deploy.dir" value="${jboss.server.dir}/deploy"/>

<property name="source.dir" value="src"/>

<property name="classes.dir" value="classes"/>

<property name="docs.dir" value="docs"/>

<property name="docs.test.dir" value="${docs.dir}/test"/>

<property name="docs.api.dir" value="${docs.dir}/api"/>

<property name="app.ear" value="${ant.project.name}.ear"/>

<property name="app.war" value="${ant.project.name}.war"/>

<property name="app.ejb.jar" value="${ant.project.name}-ejb.jar"/>

<property name="app.client.jar" value="${ant.project.name}-client.jar"/>

<property name="app.test.jar" value="${ant.project.name}-test.jar"/>

<property name="test.args" value=""/>

<property name="test.include" value="**/*Test.class"/>

<property name="test.exclude" value=""/>

<property name="db.url" value="jdbc:oracle:thin:@xxx.xxx.xxx.xxx:1111:sid"/>

<property name="db.user" value="ehosbk"/>

<property name="db.password" value="ehosbk"/>

<property name="db.driver" value="oracle.jdbc.driver.OracleDriver"/>



<!-- compile classpath -->

<path id="compile.class.path">

<pathelement location="${env.J2EE_HOME}/lib/j2ee.jar"/>

<pathelement location="${env.JUNIT_HOME}/junit-4.4.jar"/>

</path>



<!-- test classpath -->

<path id="test.class.path">

<pathelement location="."/>

<pathelement location="${app.test.jar}"/>

<pathelement location="${app.client.jar}"/>

<pathelement location="${jboss.home}/client/jbossall-client.jar"/>

<pathelement location="${jboss.home}/server/default/lib/classes12.jar"/>

<path refid="compile.class.path"/>

</path>



<!-- all -->

<target name="all" depends="clean,ear,deploy,test"/>



<!-- compile -->

<target name="compile">

<mkdir dir="${classes.dir}"/>



<javac srcdir="${source.dir}" destdir="${classes.dir}"

classpathref="compile.class.path" debug="yes"/>



<copy todir="${classes.dir}">

<fileset dir="${source.dir}">

<include name="META-INF/**"/>

</fileset>

</copy>

</target>



<!-- jar -->

<target name="jar" depends="compile">

<jar jarfile="${app.ejb.jar}">

<fileset dir="${classes.dir}">

<include name="META-INF/ejb-jar.xml"/>

<include name="META-INF/jboss.xml"/>

<include name="META-INF/jbosscmp-jdbc.xml"/>

<include name="**/*.class"/>

<exclude name="**/test/**"/>

</fileset>

</jar>

<jar jarfile="${app.client.jar}">

<fileset dir="${classes.dir}">

<include name="**/Author.class"/>

<include name="**/Story.class"/>

<include name="**/Blog.class"/>

<include name="**/*Home.class"/>

</fileset>

</jar>

<jar jarfile="${app.test.jar}">

<fileset dir="${classes.dir}">

<include name="**/test/**"/>

</fileset>

</jar>

</target>



<!-- war -->

<target name="war">

<jar jarfile="${app.war}">

<fileset dir="${source.dir}">

<include name="WEB-INF/web.xml"/>

<include name="*.jsp"/>

</fileset>

</jar>

</target>



<!-- ear -->

<target name="ear" depends="jar,war">

<jar jarfile="${app.ear}">

<fileset dir="${classes.dir}">

<include name="META-INF/application.xml"/>

<include name="${app.ejb.jar}"/>

</fileset>

<fileset dir=".">

<include name="${app.ejb.jar}"/>

<include name="${app.war}"/>

</fileset>

</jar>

</target>



<!-- deploy -->

<target name="deploy">

<copy file="${app.ear}" todir="${jboss.deploy.dir}"/>

</target>



<!-- undeploy -->

<target name="undeploy">

<delete file="${jboss.deploy.dir}/${app.ear}" quiet="true"/>

</target>



<!-- test -->

<target name="test">

<!-- Make docs. dir. -->

<mkdir dir="${docs.test.dir}"/>



<!-- Run test. -->

<junit fork="true" printsummary="on" showoutput="true"

failureproperty="test.failures" errorproperty="test.errors">

<sysproperty key="db.url" value="${db.url}"/>

<sysproperty key="db.user" value="${db.user}"/>

<sysproperty key="db.password" value="${db.password}"/>

<sysproperty key="db.driver" value="${db.driver}"/>



<jvmarg line="${test.args}"/>



<classpath refid="test.class.path"/>



<formatter type="xml"/>



<batchtest todir="${docs.test.dir}">

<fileset dir="${classes.dir}">

<include name="${test.include}"/>

<exclude name="${test.exclude}"/>

</fileset>

</batchtest>

</junit>



<!-- Run report. -->

<junitreport todir="${docs.test.dir}">

<fileset dir="${docs.test.dir}">

<include name="TEST-*.xml"/>

</fileset>

<report format="frames" todir="${docs.test.dir}"/>

</junitreport>



<!-- Fail if failures or errors. -->

<fail if="test.failures">Test failures.</fail>

<fail if="test.errors">Test errors.</fail>

</target>



<!-- clean -->

<target name="clean">

<delete includeEmptyDirs="true" quiet="true">

<fileset dir=".">

<include name="*.jar"/>

<include name="*.war"/>

<include name="*.ear"/>

<include name="junit*.properties"/>

</fileset>

<fileset dir="${classes.dir}"/>

<fileset dir="${docs.dir}"/>

</delete>

</target>

</project>

Tuesday, November 10, 2009

do bulk insert in oracle - example

insert into appointments_backup (select * from appointments s
where s.TXN_DATE between to_date('01/01/2008','dd/mm/yyyy')
and to_date('01/06/2008','dd/mm/yyyy')
)

Wednesday, October 14, 2009

Simple Ajax Example




function init() {
target = document.getElementById("complete-field");
}

function initRequest() {
try { // Firefox, Opera 8.0+, Safari

req1 = new XMLHttpRequest();
} catch (e) { // Internet Explorer
try {
req1 = new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e) {
req1 = new ActiveXObject("Microsoft.XMLHTTP");
}
}
}

function doCompletion() {
init();
var url = "AjaxGetCompanyDetails.jsp?action=CreditCompanyReport&id=" + escape(target.value);//getting XML data
initRequest();
req1.onreadystatechange = processRequest;
try{
Ext.MessageBox.show({ title: 'Please wait...', msg: 'Loading......', width:240, progress:false, closable:false });
}catch(k){}
req1.open("GET", url, true);
req1.send(null);

}

function processRequest() {
if (req1.readyState == 4) {
if (req1.status == 200) {
parseMessages();
} else if (req1.status == 204){

}else{
}
}
}

function parseMessages() {
var companies = req1.responseXML.documentElement.getElementsByTagName("companies")[0];
for (loop = 0; loop < companies.childNodes.length; loop++) {
var company= companies.childNodes[loop];
var name = company.getElementsByTagName("name")[0];
var address = company.getElementsByTagName("address")[0];
var tele = company.getElementsByTagName("tele")[0];
var fax = company.getElementsByTagName("fax")[0];
addRowToTable(name.childNodes[0].nodeValue,address.childNodes[0].nodeValue,tele.childNodes[0].nodeValue,fax.childNodes[0].nodeValue);
}
Ext.MessageBox.hide();
}


======================= Data Generated JSP ==============================





<!-- //================================================================

//

// Document : AjaxGetCompanyDetails.jsp

//

// Create date : 11-10-2009

//

// Author : Gayan Dissanayake

//

//=====================================================================



-->

<%@ page import="java.util.HashMap" %>

<%@ page import="AjaxController" %>

<%@ page import="java.io.IOException" %>

<%@ page import="java.util.Iterator" %>

<%@ page import="java.io.PrintWriter" %>







<%!

public void jspInit() {

}



public void jspDestroy() {

}

%>

<%@ page contentType="text/xml" %>

<%

try {

String action = request.getParameter("action");

String targetId = request.getParameter("id");

String data[][] = (String[][]) AjaxController.getCompanyDetails(targetId);
//return 2D array

StringBuffer sb = new StringBuffer();

boolean namesAdded = false;

if ("CreditCompanyReport".equals(action)) {

for (int i = 0; i < data.length; i++) {

sb.append("<company>");

sb.append("<name>" + (String) data[i][0].replace('&', '-').replace('/', '-') +
"</name>");

sb.append("<address>" + (String) data[i][1].replace('&', '-').replace('/', '-')
+ "</address>");

sb.append("<tele>" + (String) data[i][2].replace('&', '-').replace('/', '-') +
"</tele>");

sb.append("<fax>" + (String) data[i][3].replace('&', '-').replace('/', '-') +
"</fax>");

sb.append("</company>");



namesAdded = true;

}

if (namesAdded) {

StringBuffer dataXml = new StringBuffer();

dataXml.append("<xml version=\"1.0\" encoding=\"UTF-8\" ><companies>");

dataXml.append(sb);

dataXml.append("</companies></xml>");



response.setContentType("text/xml");

response.setHeader("Cache-Control", "no-cache");

response.getWriter().write(dataXml.toString().trim());

data = null;

} else {

response.setStatus(HttpServletResponse.SC_NO_CONTENT);

}

}

} catch (Exception e) {

e.printStackTrace();

}

%>

 

Remove table rows dynamically using javascript

function removeRowsFromTable()
{
var tb2 = document.getElementById('ServicesTable');//table id
var lastRow = tb2.rows.length;
while (lastRow > 1) {
try{
lastRow--;
tb2.deleteRow(lastRow);

}catch(e){
}
}
}

Create Dynamic HTML table using JavaScript

JAVASCRIPT CODE

<script type="text/javascript">

function addRowToTable(name,address,tele,fax){

try {

 var w = name;

var x = address;

var y = tele;

var z= fax;

var tbl = document.getElementById('ServicesTable');

var lastRow = tbl.rows.length;

var iteration = lastRow;

var row = tbl.insertRow(lastRow);

if(lastRow % 2 ==0)

row.className="rowgrey";

else

row.className="buttons";

row.height=25;

var secondCell = row.insertCell(0);

var textNode2 = document.createTextNode(w);

secondCell.appendChild(textNode2);

 

var thirdCell = row.insertCell(1);

var textNode3 = document.createTextNode(x);

thirdCell.appendChild(textNode3);

 

var fourthCell = row.insertCell(2);

var textNode4 = document.createTextNode(y);

fourthCell.appendChild(textNode4);

 

 

var fifthCell = row.insertCell(3);

var textNode5 = document.createTextNode(z);

fifthCell.appendChild(textNode5);

} catch (e) {

}

 

}

</script>

 

HTML CODE

 

<table width="100%" border="0" cellpadding="0" cellspacing="0" class="bodyTable" height="35"  id="ServicesTable" >

<tr>

<td width="30%" height="31" align="left" class="tableTitle"><span class="style1">Company Name </span></td>

<td width="40%" height="31" align="left" class="tableTitle"><span class="style1">Address</span></td>

<td width="15%" height="31" align="left" class="tableTitle"><span class="style1">Tele. No. </span></td>

<td width="15%" height="31" align="left" class="tableTitle"><span class="style1">Fax No.</span></td>

</tr>

</table>

Monday, September 21, 2009

Lazy initilasation in Hibernate

Hibernate supports the feature of lazy initilasation for both entities and collections. What this actually means is, the Hibernate engine loads only those objects that we are querying for and doesnt try to fetch other entities(that are associated with the entity we are querying) or collections.

An attribute 'lazy' can be used to let Hibernate know if the associated entity or collection has to be lazily loaded or prefetched.


This causes the collection to be eagerly fetched rather than doing a lazy fetch. If on the other hand , the attribute value of lazy is set to true, then hibernate will not make an attempt to fire the query for fetching the collection object until the request is made by the user.

Wednesday, September 2, 2009

delete user from LDAP

public boolean deleteUser(LDAPConnection ld, String ou, String username) throws LDAPException {
String dn = String.valueOf(String.valueOf((new StringBuffer("uid=")).append(username).append(", ou=").append(ou).append(", o=").append(organization)));
ld.delete(dn);
System.out.println("Entry deleted");
return true;
}

Tuesday, September 1, 2009

Send sms using Gammu 1.18

1.install gammu
2.setup configuration file
3.add system path to gammu bin directory
4.open command prompt and type below code

c:\>gammu identify

then your phone details should be display otherwise gammu not configured

after that you can send massage using this

c:\>echo Test_Massage_body | gammu nothing --sendsms TEXT +94777123456

Gammu 1.18 Configuration file

[gammu]
port = com8:
;model = 6110
connection = irdaphonet
name=
model=
;synchronizetime = yes
;logfile = gammulog
;logformat = textall
;use_locking = yes
;gammuloc = locfile
;startinfo = yes
;gammucoding = utf8
;usephonedb = yes


I have working example for gammu 1.8 if you having any problem using gammu please contact me somehow I can help you

Java Mail

public boolean sendEMail(String from, String to, String cc, String bcc, String subject, String mail) {
boolean sucess = false;
Properties props = new Properties();
props.put("mail.smtp.host", "XXX.XXX.XXX.XXX");//SMTP Host
Session sessions = Session.getInstance(props, null);
sessions.setDebug(false);
Message msg = new MimeMessage(sessions);
try {
msg.setFrom(new InternetAddress(from));
msg.setRecipients(javax.mail.Message.RecipientType.TO, InternetAddress.parse(to, false));
msg.setRecipients(javax.mail.Message.RecipientType.CC, InternetAddress.parse(cc, false));
msg.setRecipients(javax.mail.Message.RecipientType.BCC, InternetAddress.parse(bcc, false));
msg.setSubject(subject);
MimeMultipart mp = new MimeMultipart();
mp.setSubType("related");
MimeBodyPart mbp1 = new MimeBodyPart();
mbp1.setContent(mail, "text/html");
mbp1.setHeader("X-Mailer", "Details");
MimeBodyPart mbp2 = new MimeBodyPart();
MimeBodyPart mbp3 = new MimeBodyPart();
mp.addBodyPart(mbp1);
msg.setContent(mp);
msg.setSentDate(new Date());
sucess = true;
}
catch (MessagingException e) {
e.printStackTrace();
sucess = false;
}
try {
Transport.send(msg);
sucess = true;
}
catch (MessagingException e) {
e.printStackTrace();
sucess = false;
}
return sucess;
}

Thursday, August 20, 2009

Difference between hibernate's save,update and saveOrUpdate() methods

save - save method stores an object into the database. That means it insert an entry if the identifier doesn't exist, else it will throw error. If the primary key already present in the table, it cannot be inserted.

update - update method in the hibernate is used for updating the object using identifier. If the identifier is missing or doesn't exist, it will throw exception.

saveOrUpdate - This method calls save() or update() based on the operation. If the identifier exists, it will call update method else the save method will be called.

Note:

  if you use "unsaved-value="null" " property in .hbm xml this
SaveOrUpdate will not work


EX: <id name="accountID" column="ACCOUNT_ID" type="java.lang.String"
unsaved-value="null">

 

Sunday, August 16, 2009

Sending Email Using Apache Log4J

I mentioned that I was interested in using Log4j's SMTPAppender to e-mail me messages when errors occured in my webapp. I discovered how easy it is. Here's how to configure it.

Add the following configuration settings to Log4j.XML


<appender name="mail" class="org.apache.log4j.net.SMTPAppender">

<param name="SMTPHost" value="YourSMTPHostIP" />

<param name="From" value="FromEmailAddress" />

<param name="To" value="ToEmailAdressSeperatedByComma" />

<param name="Subject" value="Subject" />

<param name="BufferSize" value="1" />

<param name="threshold" value="error" />

<layout class="org.apache.log4j.PatternLayout">

<param name="ConversionPattern"

value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n" />

</layout>

</appender>

Auto close database connection

Auto close database connection setting in Hibernate XML

 <property name="hibernate.transaction.auto_close_session">true</property>

Wednesday, August 12, 2009

Native SQL in Hibernate

public class NativeQueryExample {
public static void main(String[] args) {
Session session = null;
try{
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
session =sessionFactory.openSession();

String sql =" select a.name as name, "+
" sum(a.amount) as total "+
" from Account a";
Query query = session.createSQLQuery(sql)
.addScalar("name",Hibernate.String)
.addScalar("total",Hibernate.DOUBLE);
Object [] data = (Object [])query.uniqueResult();
System.out.println("name : " + data[0]);
System.out.println("amount : " + data[1]);

session.close();

}catch(Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}

}
}
POJO Application Frameworks: Spring Vs. EJB 3.0

Albert Einstein once said, "Everything should be made as simple as possible, but not simpler." Indeed, the pursuit of scientific truth has been all about simplifying a theory's underlying assumptions so that we can deal with the issues that really matter. The same can be said for enterprise software development.

A key to simplifying enterprise software development is to provide an application framework that hides complexities (such as transaction, security, and persistence) away from the developers. A well-designed framework promotes code reuse, enhances developer productivity, and results in better software quality. However, the current EJB 2.1 framework in J2EE 1.4 is widely considered poorly designed and over-complicated. Unsatisfied with the EJB 2.1 framework, Java developers have experimented with a variety of other approaches for middleware services delivery. Most noticeably, the following two frameworks have generated a lot of developer interest and positive feedback. They are posed to become the frameworks of choice for future enterprise Java applications.

1). The Spring framework is a popular but non-standard open source framework. It is primarily developed by and controlled by Interface21 Inc. The architecture of the Spring framework is based upon the Dependency Injection (DI) design pattern. Spring can work standalone or with existing application servers and makes heavy use of XML configuration files. 

2).The EJB 3.0 framework is a standard framework defined by the Java Community Process (JCP) and supported by all major J2EE vendors. Open source and commercial implementations of pre-release EJB 3.0 specifications are already available from JBoss and Oracle. EJB 3.0 makes heavy use of Java annotations. 

Related Reading

These two frameworks share a common core design philosophy: they both aim to deliver middleware services to loosely coupled plain old Java objects (POJOs). The framework "wires" application services to the POJOs by intercepting the execution context or injecting service objects to the POJO at runtime. The POJOs themselves are not concerned about the "wiring" and have little dependency upon the framework. As a result, developers can focus on the business logic, and unit test their POJOs without the framework. In addition, since POJOs do not need to inherit from framework classes or implement framework interfaces, the developers have a high degree of flexibility to build inheritance structures and construct applications.

However, while sharing an overall philosophy, the two frameworks use very different approaches to deliver POJO services. While numerous books and articles have been published to compare either Spring or EJB 3.0 to the old EJB 2.1, no serious study has been done to compare Spring to EJB 3.0. In this article, I will examine some key differences behind the Spring and EJB 3.0 frameworks, and discuss their pros and cons. The topics covered in this article also apply to other lesser-known enterprise middleware frameworks, as they all converge on the "loosely coupled POJO" design. I hope this article will help you choose the best framework for your needs.