Overview
I started with Java Enterprise around 2 years ago, first J2EE and now JavaEE 5. In that time I’ve been through countless articles, several books and tutorials on the subject including, at times, reading the specifications to try and make sense of the framework. What was lacking was a decent, simple tutorial for the complete beginner; a Java SE programmer working on a deadline who just needs to get things done. I’m writing this as the tutorial I wish I’d had.
This tutorial aims to get you started with JavaEE as quickly as possible. There are tons of guides that cover in-depth theory; the JavaEE 5 tutorial from Sun is probably the most comprehensive of the lot; I don’t try to be nearly as in-depth. What you get here is an overview of the major parts of the JavaEE 5 framework you need to get an overall understanding of the system. This tutorial is meant to be a good starting point from which you can increase your knowledge and skill using other material.
Please feel free to comment on this and let me know if you find it useful and how it can be improved, and of any errors you may find etc.
That said, let’s begin.
The Basics
Java Enterprise (Java EE) is a framework for creating enterprise applications. The framework is stable, widely used, has excellent support from multiple vendors, is very scalable, and is backed by community driven open standards (visit jcp.org for more info). JavaEE 5, or JEE 5 is the latest version of the framework at the time of writing this article.
Multiple Vendors
Java Enterprise is a specification only. It’s up to vendors to implement the specification. Examples of vendors include Sun, JBoss, IBM and Apache. Each vendor conforms to the same specification. This means that your code is almost entirely transportable between vendors without changes. The bad news if you’re a beginner is that the specification allows vendors to have vendor-specific features. This means that some things, usually just a few configuration files, changes between vendors. This makes starting out very confusing because it gives you a very large number of options eg. Which vendor should you use? What programming tools must you use? Is it possible to mix components from different vendors? Etc.
This tutorial uses Netbeans 6.1 as the IDE, which has excellent support for Sun’s implementation of the JavaEE 5 Specification. Netbeans supports other vendors as well to varying degrees, but I find their support for Sun to be the best.
Frontend and Backend Processing
One of the core concepts in Java EE is the splitting up of frontend code and backend code. Backend code handles the processing; it’s the engine of your application. It works in the background and is not influenced by any user interface.
The frontend could be a web site (web application), a console or a Swing graphical user interface. Ideally, the frontend shouldn’t be smart, it should only contain enough logic to look pretty. When serious work needs to be done, the frontend tells the backend to perform the task. This has the advantage of allowing you to create multiple frontends, all with the same backend eg. You could allow users to access your system from a website, a cellphone and a standalone desktop application. All of Java Enterprise uses this concept of splitting frontend and backend so bear it in mind.
Managed Code
JavaEE is different from conventional programming in that much of the code you write is “managed”. In traditional programming, your code has a definite starting point (public static void main()), from where other functions are called or objects instantiated, and execution continues until the program exits.
The JavaEE approach is very different. Typically it involves the programmer writing a simple piece of code and then handing it over to the JavaEE framework which takes over and ensures the code is correctly executed. The framework will determine when your code needs to run and will instantiate objects accordingly. The framework will run these objects in multiple threads of execution if necessary and clean up after itself in many cases.
The difficulty for a beginner is switching mindsets from the traditional approach to programming where you’re in control of the entire application, to the new approach where you need to learn a component “lifecycle” and trust that the framework is doing the right thing with the code you’ve given it.
Typical examples of managed code are EJBs and web applications, both of which are covered later.
Where to Begin?
Firstly, you’re going to need a copy of the Netbeans IDE with support for Java Enterprise. This is freely available from netbeans.org. Ensure you download the full IDE with integrated Glassfish application server and Java EE 5 support.
Of course, since we’re working with JavaEE 5, you’ll be expected to have a copy of JavaSE 5.0 already installed on your system. JavaEE depends on JavaSE. This can be downloaded from Sun’s website. Netbeans will work with JavaSE 5 or 6, though I recommend using JavaSE 5. I’ve seen at least one problem with JBoss when trying to create a Web Service using JavaEE 5 with JavaSE 6. I’m not sure if this has been fixed, so please stick to JavaSE 5.
Install the package you’ve downloaded using the suggested defaults.
I’m going to assume the installation was performed in the /usr/local directory for the remainder of this tutorial.
So What Did I Just Install?
You now have a copy of:
-
Netbeans 6.1 (or later) – an excellent IDE for Java (and other) development. If you’re not familiar with IDEs, Java SE and programming, you’re in over your head. Stop now and go cover the basics first.
-
The Glassfish application server which you can find in the /usr/local/glassfish-xxx directory. An application server is the melting pot for all the JavaEE technology. The JavaEE specification covers all sorts of facilities from web applications to Enterprise JavaBean (EJB) support to transaction management to message queuing and the list goes on and on. All these different technologies are generally covered by different specifications and can be implemented and used individually. An application server integrates all these technologies allowing you to benefit from them all in one, easy to use package. In other words, by installing Glassfish, you now have all these fancy toys already set up and ready for use. We’ll talk about application servers a little later.
Ensure you have read-write access to the application server directory. In a short while, we’ll be deploying Enterprise applications to this directory and this won’t be possible unless we have write-access to it. Assuming your username and group are coder:coder on Unix platforms, issue a command like “chown -R coder:coder /usr/local/glassfish-v2”.
What Are We Going To Be Doing?
This tutorial will walk you through building an exceptionally simple application. The application will consist of:
-
A backend using EJBs with just 1 simple function to show how an EJB is created and run (deployed)
-
A standalone console application (as a frontend) that talks to the EJB
-
A web frontend (I.e. A website) that talks to the EJB
-
The backend (EJB) exposed as a web service, and a web service client to test the service
You need to understand how EJBs work, so you’ll need to cover the first point. Once this has been done, you can cover points 2, 3 and 4 in any order.
Creating a Backend
We’re going to create a backend using an Enterprise JavaBean (EJB) and then deploy this EJB on the Glassfish application server. This is going to be the core, or the “engine” behind our application. Everything else will depend on it. For simplicity, we’ll be creating just one EJB with just one function. A real application will have multiple EJBs, each with multiple functions. Our simple case will be sufficient to illustrate the concept however.
What’s an EJB?
EJB, or Enterprise JavaBean is an enterprise component that runs on an application server within an EJB container. I’ll explain containers in a bit. EJBs contain “business logic” which is a fancy way of saying it contains certain functions that must be exposed via an interface to the outside world. Any Java SE developer should be comfortable with the concept of using and interface already. This interface is all that can be seen of the EJB by other parts of the system such as a web frontend you may develop. When deployed, and EJB is managed by the EJB container.
What’s a Container?
Java Enterprise components like EJBs run in things called “containers” which is a type of automated controller. When you write an EJB, you’ll be writing a very simple class. The class you write won’t be multi-threaded, you won’t need to worry about transaction management and thread synchronization and race conditions. The thing is though, that your EJB will run in multiple threads of execution if necessary, and there won’t be race conditions, and there will be automated transaction management. These are all facilities provided by the EJB container which encapsulates and “controls” the code you’ve written. You don’t need to to anything to get this working other than mark you class as an EJB. The application server starts up the container automatically and the rest is done for you. In this way, you focus on your “business logic”, and leave irrelevant things like threading up to the container. When I say “irrelevant”, I don’t mean things like threading aren’t important. But threads generally aren’t the focus of your application; they’re just something you need to implement to solve your real problem: the business logic. The aim of the container is to remove this grunt work and allow you to focus on your problem.
As I’ve stated, different components have different containers. A web application for instance will run in a web container, not an EJB container. Like an EJB container, a web container will automatically handle things like threading, but will also support web-specific features like automated session management.
Containers are exceptionally cool. And the best thing is that they just work. You typically don’t even need to configure them. They’re easiest to understand once you see them in action.
Setting up the Glassfish Application Server in our IDE
Java components will be deployed (in a container) on an application server. During installation, Netbeans installed a copy of Sun’s open source application server called Glassfish. We need to set up Netbeans to use this application server so we can deploy things like EJBs to it. This is very easy to do.
-
Start up Netbeans
-
Click on the “Services” tab. If this tab is not visible, click Window->Services
-
The services tab presents a tree view of options, one of which is an item called “Servers”. Right-click “Servers” and click “Add Server”
-
You’ll be presented with a list of application servers supported by Netbeans. We’re interested in Glassfish, so click on “GlassFish V2”, and then click Next
-
Under “Platform Location”, you’ll need to specify the root directory of the Glassfish application server eg. /usr/local/glassfish-v2. Click Next
-
You’ll be prompted for the username and password for accessing the application server. The default username is “admin” and the default password is “adminadmin”. Enter these defaults (or replace them with the values you’ve specified at install time) and click Finish
The IDE is now configured to use your application server. To start up the application server, right-click the newly created “Glassfish” icon and click “Start in Debug Mode”. After a short while, you should see the message “Application server startup completed” show up in the newly created “Glassfish V2” tab of the output window in Netbeans.
You now have a running application server integrated with your IDE.
Creating an EJB
Next, we create an EJB to deploy on the application server we’ve just started. For this, we need an EJB module which is what Netbeans uses to ease EJB development. Do the following:
-
Click File->New Project
-
Under “Categories” click “Enterprise” and under “Projects” select “EJB Module”. Click Next
-
Enter the project name as “TestEJB” and specify some location for the project. Click Next
-
We don’t have an “Enterprise Application” yet so don’t bother trying to do anything with that field. Under “Server”, select the Glassfish V2 configuration we’ve created. This means that when we deploy our new EJB, it will be deployed to the Glassfish server we’ve already created. Click Finish
We now have an EJB project. Let’s add an EJB.
-
In the “Projects” window, right-click TestEJB->New->Session Bean. If you don’t have that option available, right-click TestEJB->New->Other and find the Session Bean option.
-
Under “EJB Name” type “Test”. Let the package name be “test”. Ensure the session type is “stateless” and create a “Remote Interface” only. Finally, click Finish
At this point, Netbeans considerately creates 2 new files: a class called TestBean and an interface called TestRemote. Alter the code so they look like the code samples below. An explanation follows.
//The TestBean.java class
package
test;
import
javax.ejb.Stateless;
@Stateless
public class
TestBean implements TestRemote {
public int add(int x, int y) {
return x + y;
}
}
//The TestRemote.java interface
package
test;
import
javax.ejb.Remote;
@Remote
public
interface TestRemote {
public int add(int x, int y);
}
That’s it, we’re ready to deploy. But first an explanation of what just happened.
-
We told Netbeans to create an EJB called Test. Netbeans tries to be helpful and created a class called TestBean that implements an interface called TestRemote. Netbeans adds on the suffix “Bean” to the class name and “Remote” to the interface. This isn’t required by any specification, it’s just a useful naming convention.
-
The TestBean class is marked with a @Stateless annotation. This annotation marks the class as an EJB.
-
TestBean implements the TestRemote interface. Users or applications who need access to this bean do so via the TestRemote interface. The function prototypes specified in the interface are all that users/applications have access to.
-
The TestRemote interface uses the @Remote annotation. This annotation marks the class as an EJB remote interface. In a nutshell, this is the annotation that allows the EJB to be seen by the outside world.
We’ve added the function add() to the bean which simply adds two numbers and returns. Since we’ve declared this method in TestRemote, this function will be accessible to other applications/users. TestBean may have functions that are not declared in the TestRemote interface; and likewise, these functions will not be viewable remotely.
Let’s deploy the EJB
This is really easy.
-
Right-click the TestEJB project in the projects window of Netbeans and click “Undeploy and deploy”
Any old copies of the bean will be removed from the Glassfish server and the new copy you’ve just created will be deployed to the application server. If you switch to the Glassfish tab in the “Output” window, you should see “All ejb(s) of [TestEJB] loaded successfully!” as the last message, indicating that everything worked.
So I’ve Deployed an EJB. Now What?
Now you have a backend. Granted your backend is exceptionally simple, but it’s a backend nontheless. To use it, we need a frontend that accesses it, which we’ll build next. Before we get to that, here’s answers to some questions you might have. You can skip ahead to building the frontend if you’re not feeling too theoretical at the moment.
What’s The Difference Between a JavaBean and an Enterprise JavaBean?
An ordinary JavaBean is just a class with one no-argument constructor. Member fields of this class must be declared private and/or protected and if they need to be accessed or modified, these operations should be performed via getter and setter methods. This is simple JavaSE stuff. An example JavaBean is shown below.
public class DummyJavaBean {
private int x;
protected String y;
private long z;
public DummyJavaBean()
{
}
public void setX(int t) {
x = t;
}
public int getX() {
return x;
}
public void setY(String t) {
y = t;
}
public String getY() {
return y;
}
}
In the DummyJavaBean class above, the fields x and y can be modified. The field z may not be modified. There’s nothing fancy about this code whatsoever.
An EJB like the code sample from the last section is a managed component that runs within a container. The container will manage things like when to instantiate a copy of the bean, it will synchronize concurrent access to the bean, handle threading etc.
Despite having similar names, EJBs and normal JavaBeans are very very different. An EJB might even use a JavaBean in some function to pass data around, there’s nothing wrong with that. But understand that there’s a big difference between the two.
What’s JNDI?
One could easily write a book on this subject alone. Someone from Sun probably has. For the purposes of this tutorial, all you need to know is that Java Naming and Directory Inteface, or JNDI, is a big directory where references to Java objects are stored. When you want the object, you can just ask JNDI to get it for you.
For instance, suppose an EJB needs to be accessed. When the EJB is deployed a reference to the EJB is automatically added to the JNDI directory. Similarly when the EJB is undeployed, that reference is removed.
When an application like the standalone console application we’re about to develop needs to access the EJB, it simply asks JNDI for a reference to the remote interface of the bean (I.e. It asks for a reference to TestRemote). JNDI finds the requested information and returns it. In a way, JNDI allows all the different parts of your system to find each other. You’ll see a coding example very soon.
Enough Theory, Let’s create the Console Application
Yes, there’s lots of theory but I’m trying to stick to only the important bits. It just so happens that a lot of the bits are important. But now it’s time to write more code.
You’re expected to understand JavaSE so I’m skipping the obvious stuff here.
Use Netbeans to create a plain old JavaSE application called TestEJBClient. Make your program look like the sample below:
package testejbclient;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.rmi.PortableRemoteObject;
import test.TestRemote;
public class Main {
public static void main(String[] args) {
try {
Context ctx = new InitialContext();
Object o = ctx.lookup("test.TestRemote");
TestRemote tr =
(TestRemote)PortableRemoteObject.narrow(o, TestRemote.class);
System.out.println("The sum of 2 and 7 is "
+ tr.add(2, 7));
} catch (Exception e) {
e.printStackTrace();
}
}
}
That’s it, that’s all the code that’s required for a complete standalone console client. This code won’t compile as is. You need one extra library to make the code compile, and a further 2 libraries to run the code. Add these in and I’ll explain what’s going on.
-
Right-click “Libraries” under TestEJBClient and then click “Add Project”. Add the TestEJB project to the classpath. This is really a cheat. We don’t need the entire project, just the remote interfaces. So we could have refactored the remote interfaces into a different project or a different package which would make creating test clients that much easier. But in the spirit of keeping things simple, for now just cheat and add the entire TestEJB project to the TestEJBClient classpath.
-
Next, we need 2 jar files from the Glassfish lib/ directory. So go to /usr/local/glassfish-v2/lib and add the files javaee.jar and appserv-rt.jar to your project’s classpath.
Now, right-click the TestEJBClient project in the Netbeans Projects window and click “Run”. In the debug tab that opens in the Output window, you’ll see the program run successfully and output the message: “The sum of 2 and 7 is 9”. Ok, so that’s not the most exciting message in the world, but it shows that you’ve successfully created your first standalone console based frontend that talks to a JavaEE backend system and requests an EJB perform a task for you.
Once you understand what’s going on here, the hard work is over; you’ll understand the necessary concepts to start being productive. Of course there’s tons more you can learn but life will be easier once you get over this last hurdle.
So What Did Our Test Client Do?
-
The test client started up, then contacted the JNDI server over TCP/IP and asked it for a reference to the test.TestRemote interface. Don’t forget, the TestRemote interface is from the TestEJB project (which is why we needed to add it to the classpath)
-
The JNDI server gives us the reference to this interface. In the background, the EJB container within the Glassfish application server figures out if a new EJB needs to be created and creates one if necessary. Transaction management, thread handling etc. is all sorted out by the EJB container, but as the code suggests, you don’t have to worry about any of this.
-
Now that we have a reference to the interface, we can call the add() method which is available in TestRemote. When we call this function, we pass up two integer parameters: 2 and 7. This data is serialized and transmitted across the network from TestEJBClient to the application server. The function call is made remotely, the result is computed and the result is serialized and transmitted back to TestEJBClient which then deserializes the response and displays it on screen.
And all you did was write 4 lines of code
Which is one of the reasons JavaEE rocks! Now let’s cover the code in more detail. The most important lines are listed below:
Context ctx = new InitialContext();
Object o = ctx.lookup("test.TestRemote");
TestRemote tr =
(TestRemote)PortableRemoteObject.narrow(o, TestRemote.class);
Firstly, understand that the 3 lines of code shown above are boilerplate code. This means that when you’re writing a standalone application, you’ll use this general form of coding a lot. And it’ll always look the same. Some of the parameters might change, but the overall template will remain as is.
To understand all the details would require a decent understanding of JNDI. I’ve already given a quick overview of this topic in a previous section so you may want to quickly (re)read that.
The first line of code is:
Context ctx = new InitialContext();
You need to contact the JNDI server on some IP adress and port. You also need to specify what classes Glassfish uses to implement these facilities. All this information can be specified programatically which is not recommended unless required for some reason, or alternatively it can be specified in a file called jndi.properties which is expected to be in your classpath. You didn’t explicitly add jndi.properties
to your classpath. However you did add the jar file appserv-rt.jar from the Glassfish distribution to your classpath and appserv-rt.jar contains a copy of jndi.properties. Calling “new InitiallContext()” gets the information necessary to talk to the JNDI server from jndi.properties. This information is now stored in the “ctx” object.
The second line of code is:
Object o = ctx.lookup("test.TestRemote");
Now in the TestEJB project, I mentioned that the remote interface is what other applications/users use to access the EJB. The full name of the interface is “test.TestRemote”. When the EJB was deployed, a reference to this interface was added to the JNDI directory automatically. This line of code grabs that reference by using the ctx object. Remember that the ctx object contains the information required to talk to the JNDI server. So after this line of code executes, we would have talked to the JNDI server and retrieved the reference we were looking for. But we’re not quite out of the wood yet.
The third line of code is:
TestRemote tr = (TestRemote)PortableRemoteObject.narrow(o, TestRemote.class);
This is by far the trickiest line of code. And while some tutorials don’t use it, it’s always recommended that this line of code be used. Much earlier in this tutorial I mentioned that JavaEE is a specification that’s implemented by multiple vendors. Now provided these different vendors conform to the specification, they’re free to implement the code however they feel like it. And when it comes to serializing data and passing this data between clients and servers, they’re free to use whatever protocols they like eg. RMI or CORBA or RPC or even some proprietary protocol they’ve invented. This is a perfect receipe for disaster since, for the most part, different protocols don’t necessarily work together. So some mechanism was required to standardize things, and this is called PortableRemoteObject.narrow(). This function takes the reference received from the ctx.lookup() which could have been in some weird format, and converts it to the requested class. In the line above, it takes the reference (Object o) and converts it to an object of the form “TestRemote.class”. All the ugly details are hidden away. You simply call PortableRemoteObject.narrow() and everything works.
Finally, now that you have an object of type TestRemote, you can call the add() method which is precisely what was done in the last line of code.
Summary
I’ll be expanding on this tutorial soon; it isn’t completed yet. But hopefully it makes for a good start to help you delve head first into the world of JavaEE.


Nice work Faeem. A very good beginner tutorial which I haven’t found anywhere else.
Tom