EJB 3 application in Glassfish 3x

Posted: June 7, 2012 in Techilla
Tags: ,

Today, we are going to put forth a small EJB 3 application in Glassfish v3.

Why EJB3?

 Coding in EJB3 is almost as simple as it gets. EJB has gone some major intuitive simplifications in order of coding from releases 2x to 3x.

Gone are the days of cumbersome home interfaces, remote interfaces, deployment descriptors and checked exceptions in SessionBean implementations.

EJB3 supports annotation based coding and dependency injections. While we can (and will ) do the JNDI lookups to get hold of an EJB/Resource, DI takes away the need to do so.

 While the deployment descriptors (xml based) can still be used, we are going to develop a simple application which will be wholly annotation based.

Why Glassfish?

Glassfish is probably the easiest application server out there. It’s so intuitive that it almost feels like a web server. We will eventually use the same application in a Weblogic server(the big daddy) but Glassfish is great because you can start it up and test concepts in almost no time.

Lets then put the 2 heads together and  build a small EJB3 application and deploy it in Glassfish v3.

We will be doing this in Windows and we shall use Eclipse as our IDE.

Pre-requisites

Download the zip file –  glassfish 3x.zip

Our version : glassfish-3.1.2.

Startup of Glassfish

Go to the bin directory after unzipping and key in the following(or start up asadmin.bat)

asadmin start-database ( If you really need Derby to start)
asadmin start-domain

Open http://localhost:4848/asadmin. to test the installation.

 Login using the user ID admin and password adminadmin. This will validate the installation.

Coding our EJBs

We only need a POJI and a POJI and then we will add some simple annotations to magically turn the POJO to an EJB. We will be using here a stateless session bean.

@Remote
public interface PlaceAuctionItem {
	void placeAuctionItem();
}


@Stateless(name="PlaceAuctionItem", mappedName="ejb/PlaceAuctionItem")
public class PlaceAuctionItemBean implements PlaceAuctionItem{


	@Override
	public void placeAuctionItem() {
		System.out.println("saving the AuctionItem ");
		//save the auctionItem in the database
		
	}
	 

}

Annotations:

@Stateless: marks the session bean as stateless

mappedName: would be used to do JNDI lookup from the client

@Remote: tells that this is the remote interface.

Once done, we need to deploy the EJB to Glassfish

 EJB Deployment in Glassfish

  • Right click and Export the project as a jar file(let’s name it as test-ejb.jar) and deploy it to

                glassfish-3.1.2\glassfish3\glassfish\domains\domain1\autodeploy\test-ejb.jar

  • Glassfish auto redeploys the jar file, so every time you change anything on the EJBs, you have to re-export the jar(obviously) but you don’t have to restart the server.

Check out the image below.(ActionBazaar is our project name in Eclipse)

export ejb jar eclipse glassfish

Once we have done this, we would create the client which will be a simple java class to test our EJBs.

EJB Client

public class TestStatelessSessionBeans {
@EJB
private PlaceAuctionItem placeAuctionItem;

public void mimicPlaceAuctionItem(){
	placeAuctionItem.placeAuctionItem();
}

public TestStatelessSessionBeans() {
	super();

	try {
		Properties props = new Properties();
		props.put(Context.INITIAL_CONTEXT_FACTORY, 							"com.sun.enterprise.naming.SerialInitContextFactory");
		props.setProperty("org.omg.CORBA.ORBInitialHost", "localhost");

		// glassfish default port value will be 3700,
															props.setProperty("org.omg.CORBA.ORBInitialPort", "3700");

		InitialContext ctx = new InitialContext(props);
			
		this.placeAuctionItem = (PlaceAuctionItem) 								ctx.lookup("ejb/PlaceAuctionItem");
	} catch (NamingException e) {
		e.printStackTrace();
	}

}

public class TestModule {
	public static void main(String args[]){
	   new TestStatelessSessionBeans().mimicPlaceAuctionItem();
	}
}

Some common errors

• @EJB will also mark this EJB to be DI by the container, however, we are not deploying the client in Glassfish, and hence we would need to do the JNDI lookup.

• We have to use the properties mentioned while instantiating the InitialContext to prevent error:

Lookup failed for ‘ejb/PlaceAuctionItem’ in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.url.pkgs=com.sun.enterprise.naming, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl} [Root exception is javax.naming.NameNotFoundException: PlaceAuctionItem not found]

Or

javax.naming.NoInitialContextException: Need to specify class name in environment or system property, or as an applet parameter, or in an application resource file: java.naming.factory.initial

Libs required by project

  • appserv-rt.jar
  • gf-client.jar
  • javaee.jar

 But take note, that the gf-client.jar must not be copied into your workspace. It needs to be referenced from the Glassfish server location. It acts like a wrapper for other glassfish client libraries.

Now, if we run the client, and see the server.log under domains/domain1/logs we get the following statement printed from our StatelessSessionBean.

[#|2012-06-06T01:20:12.346+0800|INFO|glassfish3.1.2|javax.enterprise.system.std.com.sun.enterprise.server.logging|_ThreadID=20;_ThreadName=Thread-2;|saving the AuctionItem AuctionItem

Next up would be deploying an ear into Glassfish(which shall contain this EJB and a servlet to test our DI)

About these ads
Comments
  1. Leandro Sehnem Bortolotto says:

    Congratulations for you. Very nice article, inclusive the session named “Some common errors” that hope me very much.

    • I am getting this exception when i tried the same setup. I am trying to run the ejb using simple java class main method with the same jndi properties. Please do the needful.

      Exception in thread “main” java.lang.NoClassDefFoundError: org/glassfish/api/naming/NamedNamingObjectProxy
      at java.lang.ClassLoader.findBootstrapClass(Native Method)
      at java.lang.ClassLoader.findBootstrapClassOrNull(ClassLoader.java:1061)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:412)
      at java.lang.ClassLoader.loadClass(ClassLoader.java:410)
      at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)

  2. Gokhan says:

    nice wrap-up mate, thanks

  3. Petr says:

    Thanks for nice article.
    If client is enterprise application client and you’ll use @EJB annotation on remote interface, client throw
    javax.naming.NamingException: Exception resolving Ejb for…
    javax.naming.NamingException: Lookup failed for…

  4. martinanderssondotcom says:

    Related: I just wrote a tutorial on how to create a JavaFX application that launch through Java Web Start and who will have server side resources injected through dependency injection:

    http://blog.martinandersson.com/the-enterprise-side-of-javafx-the-missing-part/

  5. Sengit U says:

    Thank you so much for this article, I was looking for this for 6 hours.

  6. Amit says:

    Nice article. I get the error which you mention in your post – Lookup failed for ‘java:comp/env/logback/context-name’ in SerialContext[myEnv={java.naming.factory.initial=com.sun.enterprise.naming.impl.SerialInitContextFactory, java.naming.factory.state=com.sun.corba.ee.impl.presentation.rmi.JNDIStateFactoryImpl, java.naming.factory.url.pkgs=com.sun.enterprise.naming}.

    I verified that the above 3 jars are present in the glassfish lib directory. Any suggestions

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s