OverZealous Creations

This article is very out-dated, and is no longer updated. If you are interested in developing J2EE applications using open source tools, the latest version of NetBeans has far more capabilities than when this article was written.

How To: Develop J2EE Applications for Free


Phil DeJarnett

This article is a summary of tips, tricks, and problems I've experienced in starting and developing a J2EE application, with a focus on using open source and free tools. It is not intended as a resource for specific J2EE elements, such as EJBs and Servlets, but rather, as a "getting-started" guide for the development process.

Contents:

Top

My Background


I'm currently a free-lance developer attempting to finish my college degree. I've been a Java devotee since version 1.1.8 - and a much bigger fan since I learned real Java using Sun's VM version 1.2 (Java 2). Because my college couldn't decide what language made sense to teach (here's a clue: not Visual Basic), I really feel I've taught myself the most important programming skills, including being adaptable to the language at hand, and, for the most part, object oriented concepts, by focusing on Java. Since 1999 I've been using Java full time, for tools and small applications. In 2001 I helped start a company, as the sole programmer, and began working on both server and client applications, intended for both intranet and extranet usage. In 2002 I quit, due to being the only programmer, but being surrounded by people with "great ideas." Since then, besides focusing on my studies, I've been working on my own, mostly honing my skills.

I've been developing a large web/J2EE application for about 6 months now. This project started out as a simple Java Servlet/JSP based website. I was mostly concerned with the copy-and-paste update issues that static content sites usually suffered. After this initial design was done, using a tag library to handle cross-site content, the owner and I began discussing larger plans. The overall idea was to eventually enable complete management of the owner's company, from accounting, to product catalogs, to web site administration, through the website itself. The most important thing for this website, though, was low cost, not something you usually associate with an enterprise-class system.

I had originally planned on expanding the Tomcat-based solution I started with. As I began work, I realized that I would have to create tools to manage working with the database (so I wasn't hand coding a lot of stuff repeatedly). Then I would have to ensure the ability to rollback when errors occurred, which is easier said than done. Finally, I'd end up having the visual code closely tied to the business logic. All of this prevented the application from scaling efficiently, and would have increased my development time in the long run.

I decided to give Java 2 Enterprise Edition (J2EE) one more try. I had tried to fiddle with it on several prior attempts, but I gave up because of the complexity and cost associated with any standard J2EE installation. So I did my research. I learned about a totally free-to-use, open source J2EE server called JBoss. I downloaded the template project they offered. And this is where I learned how efficient, and how powerful, J2EE development can be. Not because of JBoss - this isn't an article about them - but because of the tools the template used.

Top

Who Needs J2EE?


"Free" is a relative term. No J2EE application development is easy, or can be done in a short period of time. When you rely on free services and tools, your development time will increase, due to the fact that the number of tools and features you must learn increases almost as rapidly as quality documentation for these tools decreases. It's not impossible, though. For learning or testing the waters, it's much better than sinking cash into someone's application.

Before you decide to use J2EE, you should decide if it is really worth the work. You must ask yourself what you are really planning to do:

Top

CVS


I feel the need to cover this. One of the first things you should worry when developing any application that has importance is how you are backing it up. The safest, and most future-proof method, is to set up a CVS server, or similar versioning tool. While describing how to use this is out of this article's scope, the most important thing to realize is that the earlier you invest the time into CVS, the more work it will save you. Set it up early, and commit any stable changes you make frequently. Preferably, make backups of the CVS server's content as well. I've lost enough information, personally, to feel the need for backing up my backups. Hopefully, you'll never need to know the pain of realizing your backups have trashed just after your main system trashed. (Ever lost both drives in a mirrored RAID array?)

The most important reasons to use CVS: it's totally free, integrates nicely into the NetBeans IDE, and will allow you to do several important things no backup system offers:

That's my lecture on backing up to a versioning sever. Now onto actual J2EE development.

Top

Java 2 SDK


One of the benefits of developing a server application, as opposed to creating a client application, is that you usually have control over then end-client's Java version. Try to always use the latest version. Java not only gets faster and more stable with each version, but security and feature sets improve constantly. Use the latest version that your chosen J2EE server works with. Sun's version is available on their website. But I probably didn't need to tell you that.

Top

Ant


Ant is fast becoming the most powerful development tool on the market. It has no comparison in the Java world, and the make tool used in Linux and C++ development pales when it comes to power and extensibility. It's so powerful that the Apache organization just promoted it - it's now a top-level Apache tool, not "just" part of the Jakarta project.

What does Ant do? Everything but write your code for you (actually, it does that somewhat with XDoclet). Ant allows you to generate, compile, test, update and deploy all at once. The built-in targets have phenomenal power to manipulate files both local and remote. It's also "intelligent", only manipulating files that have changed. A well designed script can cut deployment time during the testing phase by 75% or more. For a scenario, the common steps to make changes to a single Enterprise JavaBean (EJB) for deployment of an application:

  1. Change source the EJB file.
  2. Update/create stub files (if necessary). There can be up to 4 of these files, and they don't really have any content.
  3. Compile files into separate directory.
  4. Update ejb.xml to reflect changes (if necessary).
  5. Re-create ejb JAR.
  6. Recreate application EAR file.
  7. Copy file to server.
With Ant, you only have to do the first step (editing the source file), then run the Ant script. Inside of NetBeans, this means you only have to click a button on the toolbar. Then watch Ant fly. As I'll describe later, these scripts can even work with individual file changes inside of an "exploded" EAR/JAR file, so that the server redeploys quicker.

If you are using NetBeans, and don't plan on working outside of it's massive shell, you can use the built-in Ant. This works ok, but, trust me, there will be times when the changes are far too minor to require starting up NetBeans. In these instances, you'll want to have a command-line ready version of Ant. This is really easy to do. Install Ant from the Apache.org website (usually I put it in a subfolder of my J2SDK), and set the environment variable ANT_HOME to point there. Then add $ANT_HOME\bin or %ANT_HOME%\bin to your PATH. Now you can run Ant from any directory with a build script using the command ant [target-name].

Top

XDoclet


Ant's assistant for working with full-fledged EJBs is XDoclet. XDoclet uses JavaDoc to analyze the EJB and Servlet source files (the ones with content), then it generates: XDoclet can generate other things as well, but the most important ones, by far, are the stubs and ejb.xml files. Keeping these synchronized with your changes is practically impossible, and a terrible headache, especially when you have more than one EJB.

Using XDoclet is a snap. Install it from their website, like Ant, I put it in a subfolder of my J2SDK. Then you tell Ant where to look for the XDoclet jars, and it will dynamically load in the tools. The example that I refer to in Putting It All Together does just this. As for how to tell XDoclet what the EJBs do, it's as easy as adding documentation to your methods: you add @-tags to your source, and define their information, such as the name of the EJB, or the type of bean.

I recommend using the latest beta of XDoclet. Especially since I'm focusing on JBoss development, and a lot of new JBoss tags were added that allow you define table names and field names quickly. This is helpful when constantly redeploying a development application, as the server can check to make sure a table exists before it complains that it can't create the table. (And you don't want to remove the tables every time, or you lose data between restarts!)

Top

JBoss


While this isn't an article about JBoss, or trying to promote it, I must say that I am really fond of the software. It's very stable, and very powerful, and handles nicely even while running on the same machine as my NetBeans, HTML editor, Photoshop, and anything else that gets opened while I'm working. Restarts of the server take less than a minute usually, and redeploys - complete application redeploys - of my 700+ file application happen in a few seconds.

JBoss is one of the few tools I've ever seen with absolutely no restrictions on how you deploy, where you deploy, how many copies you run, etc. It supports clustering out of the box. The only time you shell out money is, if you choose to (I haven't needed to yet), you can purchase access to the documentation. The documentation is supposedly very good, but most of the information can be found, with some hard work, through the use of the JBoss forums, website and Google searches. If you plan on deploying for a money-making company, I would support them, though, through purchasing the documentation.

It is offered (at the time of this writing) in two primary flavors: JBoss with JBossWeb (using Jetty for servlets) and JBoss with Tomcat 4. I find Jetty to be much faster than Tomcat for compiling JSPs, and since most of the tools used in J2EE development are handled by the J2EE container (JBoss itself), the additional features offerred by Tomcat aren't really necessary. If you have a preference, use whichever you are more comfortable with. In either case, running the latest version of JBoss will help protect you against security bugs and make your applications more future proof when you end up needing to upgrade to the next version.

JBoss, like the other tools here, is installed by decompressing the application into a directory, and running a batch file. The free Quick Start documentation on their website explains the ways in which you can set it up to run as a service, on both Windows and *nix servers. It is extremely customizable through xml files that exist in the deploy directory, and any services (including most server features, JARs, WARs, and EARs, and all web-documents) are automatically redeployed when they change. This really speeds up development, because to update a web document, I simply copy it over (in the exploded EAR directory described below), and the next time I want to read it, the server updates the file. If I need to redeploy a class file (such as a changed EJB), I simple touch the application.xml file, and JBoss registers this as an application update, and quickly redeploys the entire application, updating any changed files. Undeploying is as simple as deleting any file or folder I want to undeploy (and touching application.xml for class-file changes).

Top

Database (PostGreSQL)


There are several free databases you can use for developing a J2EE application. The most common is probably MySQL, a Linux staple often required to run many applications. MySQL is favored by many because it is extremely quick. But, because of the dedication to making MySQL fast, the developers have left out some important SQL 97 features, including the ability to perform subqueries.

PostGreSQL (PGSQL) is another favorite open source standard, and my favorite. PGSQL was designed more for the enterprise market, and is designed to look like and work like many of the much larger names out there. It is extensible (something few databases truly are), and has very powerful, built-in procedural languages. PGSQL is included with nearly all Linux distributions, and can be set up very easy. JBoss can be notified that it is running using PostGreSQL, and, in theory, will tailer it's database calls to make use of the features PGSQL offers.

The fact is, however, any database that is intended for server use will work. Since most effective J2EE applications are written using container managed persistence (CMP), most applications will not need to write a single line of SQL. Unless you plan on optimizing your application by tweaking the EJB container (through custom deployment descriptors), or plan on writing all database access code yourself, you can use any Database you are comfortable with.

NetBeans

Top
Since this is on the NetBeans website, I'll assume you already have and use NetBeans. What I will describe is how to setup the project and use the Ant script seamlessly with NetBeans.

First, you'll want to set up your project as cleanly as possible. Do this by mounting the root project folder (the one that contains your build.xml, src, lib, and build directories) into NetBeans. If you are using a versioning server, as I highly recommend, you'll need to add this as a new CVS filesystem to use NetBeans to make updates to the server. Otherwise, just add the folder as a new filesystem. Then, you need to set up certain subfolders as new filesystems by using the treefs experimental addon. Add any folders that are root to class files (ex: src/main/ejb and src/main/servlet), as well as the web-document root, this way. Then, the following JARs from JBoss, if you need them:

To keep this as clean as possible, you can add the directories you will be using the most to the "Project" tab, by right-clicking on them and choosing Add To Project.

Finally, you can add the Ant targets you use to the toolbar. This is done by clicking File > New, then choosing the Ant folder and New Shortcut to Ant Target. Walking through this wizard will then allow you to pick your Ant file and Target, choose a title for the shortcut, and add it to menus, toolbars, etc. Then, assuming it has been attached to the toolbar, you can run targets, such as deploy, with a single mouse click.

Top

Putting It All Together


This brings us to how it all works together, and some tips and tricks for getting the most out of your deployment. To speed up the development of your application, and to give you a kickstart in JBoss, XDoclet, Ant and how they work together, get a copy of the JBoss 3.0 Template and Examples, and the associated Free Quick Start PDF. These are getting outdated, and you'll have to play with the build script to get it to work correctly with the latest release of XDoclet. I did find this website, which explains some of the basics for getting the template working. Even so, this contains an entire working application, though pointless, with examples for server-side code, and client-side code. It does not, however, contain any servlet or JSP examples. You could even use this for a base project to develop non-JBoss applications. It is well laid out in general for starting just about any J2EE application.

Top Tip #1 - Deploying an Exploded EAR File
One of the problems with this setup is that the deployment is always a zipped enterprise archive (EAR). This means that every change requires recreating large zip files, and then copying over the entire multi-megabyte file to the server to test it. This isn't efficient, and, as I'll exlpain in Tip #2, really hampers website design.

The way around this is to deploy the application as an exploded eardir. This looks just like a normal ZIP file, except it's a directory, and everything inside of it is sitting directly on the disk. The general layout of an EAR is like this:

/my-application.ear
 |-- META-INF
 |    '-- application.xml
 |-- ejb.jar
 |    |-- META-INF
 |    |    |-- ejb-jar.xml
 |    |    |-- jboss.xml
 |    |    |-- jbosscmp-jdbc.xml
 |    '-- [Various packages in subfolders]
 '-- webclient.war
      |- WEB-INF
      |   |-- web.xml
      |   |-- jboss-web.xml
      |   |-- classes
      |   |    '-- [Various packages in subfolders]
      |   '-- [Various taglibs, etc]
      '-- [Various web documents and images]
It's really easy to duplicate this into a file structure by modifying the build.xml that comes with the template. This tip is concerned with a frustrating problem during development using this method: file deletion. When you delete a file, Ant has no way to know, by default, that the file isn't supposed to exist. So, we must manually remove files that are no longer in use.

This can be done by using an Ant task called <present> in your copies. This (apparently little-known) task can intelligently determine not only whether or not files exist, but also whether source files exist during copies and builds. For example, if you simply want to delete files that don't exist in the source-copy folder, the task looks like this:

    <delete failonerror="false" includeEmptyDirs="[Delete empty directories?]" verbose="[Show what's been deleted?]">
      <fileset defaultexcludes="no" dir="[Directory to delete from (destination directory)]">
         <present present="srconly" targetdir="[Directory with original files (source)]"/>
      </fileset>
    </delete>
And, if you want to remove source/compiled files with the same intelligence, use this format:
    <delete failonerror="false" includeEmptyDirs="[Delete empty directories?]" verbose="[Show what's been deleted?]">
        <fileset defaultexcludes="no" dir="[Directory to delete from (destination directory)]">
            <and>
                <present present="srconly" targetdir="[Directory with original files (source)]"/>
                    <!-- This maps all compiled files that have the same name to their source files,
                      -- including anonymous classes. It will not remove inner classes, though,
                      -- so be forewarned. -->
                    <mapper from="([^$]*)($.*)?.class$" to="\1.java" type="regexp"/>
                    </present>
                <present present="srconly" targetdir="[Directory with original files (source), again, for non-java files.]"/>
            </and>
        </fileset>
    </delete>
Even though this doesn't (and, really, can't) handle named inner classes, that can be easily circumvented by deleting the class build directory before you recompile when you know you've deleted an inner-class. It's a good idea to clean your build directory (aka: delete it) and do a full build once a week or so, anyway, to make sure everything is still ok. Finally, if you need to validate against multiple source folders (such as the build/generate folder and the src/main/ejb folder), you can add more than one <present> tag inside the <and> tags.

Using these commands before your copies, or after your compilations, you can now easily create an exploded EAR directory that can be copied directly into the server for deployment, and synchronized only with those files that have been changed for updating afterwards.

Top Tip #2 - Updating Web Elements
With a website, you are often making many, little, changes, especially during the design phase. What's even more important, you don't usually need to compile anything to see the change. This could include updating an image, a stylesheet, or a single JSP file. Rebuilding can take some time, especially with XDoclet looking to make sure that there haven't been any changes to the EJBs.

I recommend creating a separate top-level target (I usually call deploy-wardir) to copy over only the changed files from the war-dir. This can include anything in the src/web folder, but should not include anything from the src/main/servlet or src/main/ejb folders. The class files in these folders won't be recognized until you redeploy the application (see Tip #3), and could cause you a headache later if you restart the server.

The best part about this is being able to bypass, if done correctly, most of the build script, while not having to hand-copy any files. You can easily update a hundred images, or change one file 10 times, in seconds. When you start fiddling with the nitty-gritty look-and-feel of the web application, you really appreciate being able to redeploy and validate so rapidly. It also helps with JSPs, since they aren't compiled until they hit the server (usually), and typos and other bugs don't usually show up until then.

Top Tip #3 - Forcing a Redeploy the Easy Way
Sometimes, you just want the server to reload the application, without reloading the entire server. Or maybe you copied over a class file by hand, and, instead of running the entire build script, you just need the server to recognize it. I do this with a simple target called redeploy. It looks like this:
    <target depends="init" name="redeploy" description="Forces the server to reload the application.">
        <!-- Touching this file causes the server to redeploy the application -->
        <touch file="/[Name of application].ear/META-INF/application.xml"/>
    </target>
All this does is change the modified date on the application.xml file. It takes less than a second usually (from NetBeans), but causes the entire application to redeploy.

You can use this target inside of other targets, as well, such as including it as the last dependency after you've copied over the entire directory to the server. (If you try to touch the file before you've copied the files over, rebuilds won't work correctly.)

Top Tip #4 - Application Layout With Web Components
Something I had to learn the hard way was where to put class files, especially when developing web components that need to share access with EJB components. As an example, there are serious issues with trying to access large numbers of EJBs directly from within a webpage, or a custom tag. The server, because it isn't running within a single Transaction, is trying to refresh the data every time you access a method of the EJB.

The common design pattern to solve this is to place your EJB access code into a stateless session bean, and let it handle the calls. This sets up a Transaction, and the server caches any data in memory until the bean exits. Here's where the crossover occurs. If, like me, you want to ensure that HTML code is not only shared, but stored in a way that allows updates to be reflected across the entire site, you'll probably put the code into separate, static Java classes, or utility classes. This way, the tag libraries can have to access this information, and so do the session beans that handle the calls to the entities.

But where do you put the code? In the end, you need to put them in both places. For compilation and management, I put the files into the src/main/ejb directory, then modify the Ant script to copy over these packages after compilation to the build/servlet directory.

Top

Other Tools & Resources


Beyond these basic, almost vital, J2EE tools, there are also several worth mentioning:

Top

Conclusion


While developing J2EE is a time-consuming, and often frustrating, task, it doesn't have to be an expensive one. All of the tools listed in this document are 100% free to use, 100% free to deploy. Most are robust enough to compete directly with any existing costware applications, and most are fairly easy to use. J2EE development itself may not be for everyone, and you will need to familiarize yourself with J2EE concepts and design patterns. In the end, it's worth it, if you need to make an application that is scalable, efficient, and, most importantly, not tied into someone's proprietary framework so tightly that removing it leaves holes you could walk through.

Top

Links


This is a list of links used throughout this document, in alphabetical order. Bold links are critical to developing applications described in the article.

Last Updated: Monday, June 16, 2003 12:00 PM EST