J2EE project dangers!

Avoid these 10 J2EE dangers to ensure your enterprise Java project's success

In my various tenures as developer, senior developer, and architect, I have seen the good, the bad, and the ugly when it comes to enterprise Java projects! When I ask myself what makes one project succeed and another fail, it is difficult to come up with the perfect answer, as success proves difficult to define for all software projects. J2EE projects are no exception. Instead, projects succeed or fail by varying degrees. In this article I aim to take the top 10 dangers that affect the success of an enterprise Java project and showcase them for you, the reader.

Some of these dangers simply slow down the project, some are false trails, and still others can outright ruin any chance of success. However, all are avoidable with good preparation, knowledge about the journey ahead, and local guides who know the terrain.

This article is simple in structure; I will cover each hazard as follows:

  • Danger name: One-liner outlining the hazard
  • Project phase: The project phase where the hazard occurs
  • Project phase(s) affected: In a lot of cases, hazards can have a knock-on effect on later project phases
  • Symptoms: Symptoms associated with this hazard
  • Solution: Ways to avoid the hazard altogether and how to minimize its effects on your project
  • Notes: Points I wish to impart that relate to the hazard, but don't fit into the previous categories

As noted above, we'll examine each danger in the context of an enterprise Java project, along with its important phases. The project phases cover:

  • Vendor Selection: The process of picking the best possible mix of tools before you start your J2EE project -- from the application server right down to your brand of coffee.
  • Design: In between a rigorous waterfall methodology and an approach of "code it and see," lies my take on design: I do enough design so that I can move comfortably into development. I consider my design phase complete when I know exactly what I am building and how I will build it. Moreover, I use design templates to make sure I have asked all the right questions of myself and my proposed solution before moving into development. However, I'm not afraid to code in this phase; sometimes it's the only way to answer a question on say, performance or modularity.
  • Development: The project phase where the amount of work done in earlier phases will show. A good choice of tools coupled with a good design doesn't always mean a super-smooth development, but it sure helps!
  • Stabilization/Load Testing: In this phase, the system architect and project manager will impose a feature freeze and focus on build quality, as well as ensure that the system's vital statistics -- number of concurrent users, failover scenarios, and so on -- can be met. However, quality and performance should not be ignored until this phase. Indeed, you can't write poor-quality or slow code and leave it until stabilization to fix.
  • Live: This is not really a project phase, it's a date set in stone. This phase is all about preparation. It's where the ghosts of past mistakes will come back to haunt your project, from bad design and development to a poor choice of vendors.

Figure 1 illustrates the project phases most affected by the different causes (and in particular the knock-on effects).

Figure 1. Enterprise Java project phases and their most likely reasons for failure. Click on thumbnail to view full-size image. (60 KB)

Well then, without further ado, let's dive right into the top 10!

Danger 1: Not understanding Java, not understanding EJB, not understanding J2EE

Right, I'm going to break this one into three subelements for easier analysis.

Description: Not understanding Java

Project phase:

Development

Project phase(s) affected:

Design, Stabilization, Live

System characteristics affected:

Maintainability, scalability, performance

Symptoms:

  • Reimplementing functionality and classes already contained in the JDK core APIs
  • Not knowing what any or all of the following are and what they do (this list represents just a sample of topics):
    • Garbage collector (train, generational, incremental, synchronous, asynchronous)
    • When objects can be garbage collected -- dangling references
    • Inheritance mechanisms used (and their tradeoffs) in Java
    • Method over-riding and over-loading
    • Why java.lang.String (substitute your favorite class here!) proves bad for performance
    • Pass-by reference semantics of Java (versus pass-by value semantics in EJB)
    • Using == versus implementing the equals() method for nonprimitives
    • How Java schedules threads on different platforms (for example, pre-emptive or not)
    • Green threads versus native threads
    • Hotspot (and why old performance tuning techniques negate Hotspot optimizations)
    • The JIT and when good JITs go bad (unset JAVA_COMPILER and your code runs just fine, etc.)
    • The Collections API
    • RMI

Solution:

You need to improve your knowledge of Java, especially its strengths and weaknesses. Java exists far beyond just the language. It's equally important to understand the platform (JDK and tools). Concretely, you should become certified as a Java programmer if you aren't already -- you'll be amazed how much you didn't know. Even better, do it as part of a group and push one another. It's also more fun this way. Further, set up a mailing list devoted to Java technology and keep it going! (Every company I have worked with has these lists, most of which are on life-support due to inactivity.) Learn from your peer developers -- they're your best resource.

Notes:

If you or other members of your team do not understand the programming language and the platform, how can you hope to build a successful enterprise Java application? Strong Java programmers take to EJB and the J2EE like ducks to water. In contrast, poor or inexperienced programmers will construct poor-quality J2EE applications.

Description: Not understanding EJB

Project phase:

Design

Project phase(s) affected:

Development, Stabilization

System characteristics affected:

Maintenance

Symptoms:

  • EJBs that work when they are first called but never thereafter (especially stateless session beans that are returned to the ready pool)
  • Nonreusable EJBs
  • Not knowing for what the developer is responsible, compared with what the container provides
  • EJBs that do not correspond to the specification (fire threads, load native libraries, attempt to perform I/O, and so on)

Solution:

To improve your EJB knowledge, take a weekend and read the EJB specification (the 1.1 version is 314 pages long). Then read the 2.0 specification (524 pages!) to get a feel for what the 1.1 specification didn't address and where the 2.0 specification will take you. Concentrate on the parts of the specification that tell you, the application developer, what are legal actions in an EJB. Sections 18.1 and 18.2 are good places to start.

Notes:

Don't look at the EJB world through your vendor's eyes. Make sure you know the difference between the specifications underpinning the EJB model and a particular take on them. This will also ensure that you can transfer your skills to other vendors (or versions) as needed.

Description: Not understanding J2EE

Project phase:

Design

Project phase(s) affected:

Development

System characteristics affected:

Maintenance, scalability, performance

Symptoms:

  • The "Everything is an EJB" design
  • Manual transaction management instead of using the container-provided mechanisms
  • Custom security implementations -- the J2EE platform has probably the most complete and integrated security architecture in enterprise computing, from presentation right through to the back end; it is rarely used to its full capabilities

Solution:

Learn J2EE's key components and what advantages and disadvantages each component brings to the table. Cover each service in turn; knowledge equals power here.

Notes:

Only knowledge can fix these problems. Good Java developers make good EJB developers, who in turn are ideally positioned to become J2EE gurus. The more Java and J2EE knowledge you possess, the better you will be at design and implementation. Things will start to slot into place for you at design time.

Danger 2: Over-engineering (to EJB or not to EJB)

Project phase:

Design

Project phase(s) affected:

Development

System characteristics affected:

Maintenance, scalability, performance

Symptoms:

  • Oversized EJBs
  • Developers who can't explain what their EJBs do and the relationships among them
  • Nonreusable EJBs, components, or services when they should be
  • EJBs starting new transactions when an existing transaction will do
  • Data isolation levels set too high (in an attempt to be safe)

Solution:

The solution for over-engineering comes straight from the extreme programming (XP) methodology: design and code the bare minimum to meet the requirements from scoping, nothing more. While you need to be aware of the future requirements, for example future average load requirements or behavior of the system at peak loading times, don't try to second-guess what the system will need to look like in the future. In addition, the J2EE platform defines characteristics such as scalability and failover as tasks the server infrastructure should handle for you.

With minimal systems, composed of small components designed to do one thing and do it well, the reuse level improves, as does system stability. Moreover, your system's maintainability strengthens and future requirements can be added much more easily.

Notes:

In addition to the solutions listed above, employ design patterns -- they significantly improve your system design. The EJB model itself uses design patterns extensively. For example, the

Home

interface of every EJB is an example of a Finder and Factory pattern. The remote interface of an EJB acts as a Proxy for the actual bean implementation and is central to the ability of the container to intercept calls and provide services such as transparent load balancing. Ignore the value of design patterns at your peril.

Another danger that I continually warn against: using EJB for the sake of it. Not only might some parts of your application be modeled as EJBs when they shouldn't be, your entire application might use EJBs for no measurable gain. This is over-engineering taken to extremes, but I have seen perfectly good servlet and JavaBean applications ripped apart, redesigned, and implemented using EJBs for no good technical reasons.

Danger 3: Not separating presentation logic from business logic

Project phase:

Design

Project phase(s) affected:

Development

System characteristics affected:

Maintainability, extensibility, performance

Symptoms:

  • Large and unwieldy JSPs
  • You find yourself editing JSPs when business logic changes
  • A change in display requirements forces you to edit and redeploy EJBs and other backend components

Solution:

The J2EE platform gives you the opportunity to separate presentation logic from navigation and control, and finally from business logic. It's called the Model 2 architecture (see Resources for a good article). If you have already fallen into this trap, a stiff dose of refactoring is called for. You should at least have thin vertical slices that are for the most part self-contained (that is, how I order a widget is a separate slice from how I change my username or password). Use this implicit organization of your system to refactor in stages.

Notes:

Using a consistent design in conjunction with a UI framework (taglibs for example) will also help ensure that you avoid logic separation problems on your project. Don't bother building another GUI framework for your own needs, there are too many good implementations readily available. Evaluate each in turn and adopt the framework that best fits your needs.

Danger 4: Not deploying where you develop

Project phase:

Development

Project phase(s) affected:

Stabilization, Parallel, Live

System characteristics affected:

Your sanity

Symptoms:

  • Multiday or weeklong transitions to live systems
  • The risk involved in going live is substantial, with many unknowns and major usage scenarios not tested
  • Data in live systems not the same as data in development or stabilization setups
  • Inability to run builds on developer machines
  • Application behavior is not the same in the development, stabilization, and production environments

Solution:

The solution to Danger 4 begins with duplicating the production environment faithfully in your development environment. Develop on the exact same setup as that on which you plan to go to live -- don't develop on JDK 1.3 and Red Hat Linux when you plan to go live on JDK 1.2.2 and Solaris 7. Further, don't develop on one application server and go live on another. Also, get a snapshot of data from the production database and use it for testing, don't rely on artificially created data. If production data is sensitive, desensitize it and load it up. Unexpected production data will break:

  • Data validation rules
  • Tested system behavior
  • Contracts between system components (EJB-EJB and EJB-database in particular)

Worst of all, each of these will result in exceptions, null pointers, and behavior that you have never seen before.

Notes:

Developers frequently leave security until stabilization ("Yeah, the screens work, now let's add in the user validation stuff."). Avoid this trap by devoting the same amount of time to implementing security as you do to business logic.

1 2 3 Page
Join the discussion
Be the first to comment on this article. Our Commenting Policies
See more