How to create a simple EJB3 project in Eclipse (JBoss 6.1)

10 February 2012 By Nithya Vasudevan 18,078 views 12 Comments
4 Flares Twitter 2 Facebook 2 Google+ 0 4 Flares ×

Environment Used

  • JDK 6 (Java SE 6)
  • EJB 3.0 (stateless session bean)
  • Eclipse Indigo IDE for Java EE Developers (3.7.1)
  • JBoss Tools – Core 3.3.0 M5 for Eclipse Indigo (3.7.1)
  • JBoss Application Server (AS) 6.1.0 Final

Setting up development environment:
Read this page for installing and setting up the environment for developing and deploying EJB 3.0 Session bean on JBoss application server.

Project Description:

  • We are going to create a simple EJB 3 HelloWorld stateless session bean project and a remote Java application client which will call/invoke the bean.
  • This “HelloWorld” example explains how to develop, deploy and run EJB3 Session Bean (stateless and stateful) in JBoss application server.
  • For testing this “HelloWorld” example we write a remote Java Application Client (main() method).
  • For simplicity, the session bean and the client to access the session bean are created in the same project.

Creating New EJB Project

  • Open Eclipse IDE and create a new EJB project which can be done in three ways,
    • Right click on Project Explorer -> New -> EJB Project
    • File menu -> New -> EJB Project
    • Click on the down arrow on New icon on toolbar -> EJB Project

  • Enter the project name as “HelloWorldSessionBean” and make sure the JBoss 6.x Runtime has been selected with the EJB 3.0 Module version.

  • Click Next -> Next -> and Finish.
  • You will see an EJB project in the Project Explorer view.

Creating Session Bean and Bean Interface

  • Right click on ejbModule -> New -> Session Bean (EJB 3.x)
  • Enter the Java package name as com.ibytecode.businesslogic
  • Enter the Class name as HelloWorldBean
  • Select the State type as Stateless
  • Check the Remote Business Interface and enter the name as com.ibytecode.business.HelloWorld. The business interface will be created in different package (com.ibytecode.business)
  • Click Finish

Coding Bean and the Interface

  • Open Bean Interface and type the following code and save the file (Ctrl+s).
  • Interface can be either @Remote or @Local. In this example we have used @Remote.
package com.ibytecode.business;
import javax.ejb.Remote;

@Remote
public interface HelloWorld {
	public String sayHello();
}

  • Open Bean and type the following code and save the file.
  • Bean type can either be @Stateful or @Stateless. In this example we have used @Stateless.
package com.ibytecode.businesslogic;

import com.ibytecode.business.HelloWorld;
import javax.ejb.Stateless;

@Stateless
public class HelloWorldBean implements HelloWorld {
    public HelloWorldBean() {
    }

	public String sayHello() {
		return "Hello World !!!";
	}
}

Now the Stateless Session Bean has been created. The next step is to deploy the bean on the server.

Deploying EJB project

  • Now we need to deploy the stateless session bean “HelloWorldBean” on server.
  • Deploying the project can be done in two ways,
    • Right click on the EJB project -> Run As -> Run On Server. Select the existing “JBoss 6.x Runtime Server” and click Finish.
    • Right click on “JBoss 6.x Runtime Server” available in Servers view -> Add and Remove… -> Select the EJB JAR file from the left pane and click Add-> and then Finish.

Start/Restart the Server

Right click on “JBoss 6.x Runtime Server” from Servers view and click on Start if it has not yet been started.
If the project is deployed properly with global JNDI mapping then you will see the following message in the console.

Creating Client

  • The next step is to write a remote Java client application (with main()) for accessing and invoking the EJBs deployed on the server
  • Client uses JNDI to lookup for a proxy of your bean and invokes method on that proxy.

Creating JNDI InitialContext

Obtaining a Context using InitialContext

  • All naming service operations are performed on some implementation of the javax.naming.Context interface. Therefore, the starting point of interacting with the naming service is to obtain a Context by providing the properties specific to the server implementation being used. In our case it is, JBoss Application Server.
  • To create a javax.naming.InitialContext, we need to initialize it with properties from the environment. JNDI verifies each property’s value by merging the values from the following two sources,
    • Using parameterized constructor of InitialContext which takes properties of supplied environment
    • jndi.properties resource files found on the classpath.
  • NOTE:We will use constructor for initializing the InitialContext

For JBoss AS 6 we need to set following properties,
Context.INITIAL_CONTEXT_FACTORY = org.jnp.interfaces.NamingContextFactory
Context.URL_PKG_PREFIXES = org.jboss.naming:org.jnp.interfaces
Context.PROVIDER_URL = jnp://localhost:1099

The following utility class is used to create InitialContext for JBoss AS and can be reused in all applications. Otherwise the code written in this class should be repeated in all clients.

  • Right click on ejbModule -> New -> Class
  • Enter the package name as com.ibytecode.clientutility
  • Enter the Class name as ClientUtility
  • Click on Finish

package com.ibytecode.clientutility;
import java.util.Properties;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
public class ClientUtility {
	/*location of JBoss JNDI Service provider the client will use. 
	It should be URL string.*/
	private static final String PROVIDER_URL = "jnp://localhost:1099";
	
	/*specifying the list of package prefixes to use when 
	loading in URL context factories. colon separated*/
	private static final String JNP_INTERFACES = 
			"org.jboss.naming:org.jnp.interfaces";
	
	/*Factory that creates initial context objects. 
	fully qualified class name. */
	private static final String INITIAL_CONTEXT_FACTORY = 
			"org.jnp.interfaces.NamingContextFactory";

	private static Context initialContext;
	
	public static Context getInitialContext() throws NamingException
	{
		if (initialContext == null) {
			//Properties extends HashTable
			Properties prop = new Properties();		    	      
			prop.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
			prop.put(Context.URL_PKG_PREFIXES, JNP_INTERFACES);
			prop.put(Context.PROVIDER_URL, PROVIDER_URL);
			initialContext = new InitialContext(prop);
		}
		return initialContext;
	}
}

Creating client class

  • Right click on ejbModule -> New -> Class
  • Enter the package name as com.ibytecode.client
  • Enter the Class name as EJBApplicationClient
  • Check the main() method option
  • Click on Finish

package com.ibytecode.client;
import javax.naming.Context;
import javax.naming.NamingException;
import com.ibytecode.business.HelloWorld;
import com.ibytecode.clientutility.ClientUtility;

public class EJBApplicationClient {
	private static final String LOOKUP_STRING = "HelloWorldBean/remote";
	public static void main(String[] args) {
		HelloWorld bean = doLookup();
		 //3. Call business logic
		System.out.println(bean.sayHello());
	}

	private static HelloWorld doLookup(){
		Context context = null;
		HelloWorld bean = null;
		try{
                	//1. Obtaining Context
			context = Clientutility.getInitialContext();		
		        //2. Lookup and cast
		       	bean = (HelloWorld)context.lookup(LOOKUP_STRING); 
		}catch(NamingException e){
			e.printStackTrace();
		}
		return bean;
	}
}

The figure below shows the final directory structure of this example.

Run the client

Use Ctrl + F11 to run the client.
If you get any error displaying CreateProcess error=87, The parameter is incorrect as shown below, then follow these steps to recover from this error and run the client successfully.

The above error is due to the long classpath of the client. Client requires only few jar files to run the application. Since we have created client in the same project as the session bean, client classpath has all the jar files from JBoss AS. We have to remove some of the jar files to shorten the classpath, i.e.) it should be only 8191 characters long.
NOTE:
http://support.microsoft.com/kb/830473 indicates that the maximum command prompt line length in Windows XP or later is 8191 characters, and the only solution is to shorten folder names, reduce depth of folder trees, using parameter files, etc.

  • Open Run Configurations… in Run menu or Run Configurations in Run icon

  • Select the client application (EJBApplicationClient) under Java Application from left pane and open the Classpath tab from right side pane. Under “User Entries” select the application’s default classpath (in our example, HelloWorldSessionBean(default classpath)) and Remove it.

  • Now select “User Entries” -> “Add External JARs”. Add the following JAR files,

    JAR nameLocation
    All JAR filesAS6_HOME/common/lib
    jbossall-client.jarAS6_HOME/client

  • Click on “Add Projects…” and add your client project (in our example it is, HelloWorldSessionBean).
  • Click on “Apply” and “Run”.

Hello World !!!

  • Tamilselvan

    very good tutorial and small suggestion if the example is in the form of seperate project that

    means client ,bean,remotebean are used as seperate project means it is more useful.

    • http://theopentutorials.com nithya

      Thanks for your suggestion. We will post that (EJB and Client in a separate project) soon.

  • Tiago

    Wonderful tutorial! I didn´t see something so clear in the last 15 tutorials about ejb that i had read!
    God bless you very much, i finally could run a ejb application.

  • ravi

    Good Work ppl .. thnx a ton

  • leyson castaño

    gracias esta muy completo su guía quisiera saber si también tienes uno con JBoss 7.1

  • peyalnizhalan

    thank you

  • vijay

    Iam using same example in my environment(i.e.,Eclipse Helios,JBoss 4.0).But at initial stage itself I got my project structure with errors like,
    1.The preferences for the xdoclet runtime does not point to a valid installation.
    2.An EJB module must contain one or more enterprise beans.

    Will this example not run in my environment?

  • sello

    excellent toturial

  • http://googl.co.in anand

    I am new to EJB..tried above example in Eclipse but i’m getting below exception.

    i’m using jboss-as-7.1.1.Final and eclipse juno.. Please guide me how to resolve it……

    Thanks in Advance

    javax.naming.NoInitialContextException: Cannot instantiate class: org.jnp.interfaces.NamingContextFactory [Root exception is java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory]
    at javax.naming.spi.NamingManager.getInitialContext(Unknown Source)
    at javax.naming.InitialContext.getDefaultInitCtx(Unknown Source)
    at javax.naming.InitialContext.init(Unknown Source)
    at javax.naming.InitialContext.(Unknown Source)
    at com.ibytecode.clientutility.ClientUtility.getInitialContext(ClientUtility.java:34)
    at com.ibytecode.client.EJBApplicationClient.doLookup(EJBApplicationClient.java:29)
    at com.ibytecode.client.EJBApplicationClient.main(EJBApplicationClient.java:19)
    Caused by: java.lang.ClassNotFoundException: org.jnp.interfaces.NamingContextFactory
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.net.URLClassLoader$1.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
    at java.lang.ClassLoader.loadClass(Unknown Source)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Unknown Source)
    at com.sun.naming.internal.VersionHelper12.loadClass(Unknown Source)
    … 7 more
    Exception in thread “main” java.lang.NullPointerException
    at com.ibytecode.client.EJBApplicationClient.main(EJBApplicationClient.java:21)

  • Rasmita jena

    ejb jar is deployed but not properly how to deploy properly

  • Jack

    In the instructions it says to add all the jar files from the AS6_HOME/common/lib. Where can I download those jar files?