Better Programming With Java EE: A Conversation With Java Champion Adam Bien

   
By Janice J. Heiss, April 2008  

Interviews Index

This series of interviews spotlights Java Champions, individuals who have received special recognition from Java technology developers across industry, academia, Java User Groups (JUGs), and the larger community.

Adam Bien Bio: Java Champion Adam Bien is a self-employed consultant, lecturer, software architect, developer, and author in the enterprise Java sector in Germany who implements Java technology on a large scale. He is also the author of several books and articles on Java and J2EE technology, as well as distributed Java programming. His books include J2EE Patterns, J2EE HotSpots, Java EE 5 Architectures, Enterprise Architectures, Enterprise Java Frameworks, SOA Expert Knowledge, and Struts, all published in German.

A BEA technical director, Bien is also a member of the NetBeans Dream Team; an Expert Group member of the Java Community Process for EJB 3.1, JPA 2.0, and Java EE 6; and involved in embedded Java, Grid, and P2P technology. He currently works as an architect and developer in several J2EE-Java EE Model-Driven Architecture (MDA) and EAI component architecture projects for the Java EE platform and .NET.

He has worked with the Java SE and Java EE technologies since their inception with JDK 1.0 and Java Web Server.

(JSC): What are some major fallacies that you encounter in regard to the Java EE platform?

Bien: There are three big fallacies. First, believing that J2EE is complex; second, believing that Java EE 5 is easy; and third, believing that distributed programming could be simpler.

 
"It's kind of funny that developers still explore new frameworks and hope for magic solutions -- and forget about core problems."
 
 
Adam Bien
Java Champion

The truth is that building J2EE applications has never been really complex but is work- or typing-intensive. The developer had to accomplish rather boring activities. To deploy a simple server-side component -- HelloBean -- the following artifacts had to be created:

  • The Remote Interface, which inherits from EJBOBject -- for example, HelloRemote
  • The Home Interface, a factory, which creates the Remote Interface and inherits from EJBHome, HelloRemoteHome
  • An indirect implementation of both, for example, HelloBean, which only implements the SessionBean interface
  • An XML-deployment descriptor that acts as a glue or link between these items

Much work was required, but the individual tasks were simple. Tools such as XDoclet generated everything from the Bean class with only a few additional metadata in Javadoc format.

/**
 * @ejb.bean name = "HelloBean" transaction-type = "Container" view-type = "remote"
jndi-name = "HelloBean" type = "Stateless"
 * @ejb.transaction type = "RequiresNew"
 */
public class  HelloBean implements SessionBean {
 

For small to mid-range projects, Ant and XDoclet did the work for you. However, larger projects were more challenging due to slow generation and deployment.

Java EE 5 was streamlined and got rid of the redundancies, eliminating the need for generation. Through some fresh ideas like Configuration By Exception or Configuration Over Convention and recognition of DRY (Don't Repeat Yourself), Java EE 5 became quite lean -- so lean that you can now develop and deploy applications without sophisticated tools, with vi and Emacs, for instance. In fact, it's hard to optimize it further.

To develop the same component, only the following artifacts are needed.

A familiar interface:

public interface Hello {
    public void sayHello();
}
 

And a familiar Java object:

@Stateless
@Remote(Hello.class)
public class HelloBean implements Hello {
    public void sayHello(){
        System.out.println("Hello World");
    }
}
 

So a deployment of enterprise-class Hello World Bean even to HA-Cluster requires only two additional annotations. What a huge productivity gain, especially given that the complexity is nearly the same. Understanding that this component will be executed in a massively parallel, distributed environment explains why that code won't scale. The problem is the static PrintStream and the indirectly synchronized println. The implementation of the println method looks like this:

  public void println(String x) {
synchronized (this) {
    print(x);
    newLine();
}
    }
 

So only one instance of a stateless session bean in a cluster node can print Hello World at a time, making distributed and parallel programming complex. The problem is not Java EE 5-specific, so Ruby, PHP, Perl, and even .NET developers should understand the potential problems first. It's kind of funny that developers still explore new frameworks and hope for magic solutions -- and forget about core problems.

The Challenges of the Java EE 5 Platform

JSC: Java EE 5 patterns present challenges related to redundancies, layering, lazy or eager loading, state management, distribution, and transactions. What should developers understand about this?

 
"The best advice I know is 'Don't distribute.'"
 
 
Adam Bien
Java Champion

Bien: Distribution of data and concurrency are the hardest challenges. Many of the best practices and patterns address these problems. The best advice I know is "Don't distribute." Therefore, a fat client with a local embedded database, such as Java DB, is the simplest possible solution -- everything else is a workaround.

You are already in trouble if another client would like to access your data, because then you will have to access the database remotely. But with a local embedded database, your data is shared and distributed. Objects with the same identity live in the database and in the clients. If you move your business logic from one client to another tier, you will already get the Java EE 5 complexity.

Java EE 5 addresses most of the problems out of the box. Transactions are started for you, threading is almost transparent, the changed JPA entities -- the cache -- are synchronized automatically with the database, and potential inconsistencies can be easily detected with built-in optimistic collision detection.

You have to "only" understand and configure the desired behavior -- or use the defaults -- and react to possible optimistic collisions. These principles haven't changed since the beginning of distributed computing going back at least 30 years.

With Java EE 5, there are more options. The architecture can be designed in a more pragmatic way. It's no longer necessary to introduce many strict layers, which are mostly independent of each other. Some layers can be collapsed -- for example, the javax.persistence.EntityManager is already a generic DAO (Data Access Object). There is no need to introduce another one.

JPA entities are automatically detached at the end of every transaction -- so you can just pass them to the presentation without the creation of a Value Object. It's even possible to keep them attached, =persistent, and modify them directly in the view. However, you have to really understand what you're doing.

For example, it should be clear to you and especially your team that a detached object is detached, so it's not possible to lazily load its references from the presentation tier. On the other hand, you can only work with attached objects in cases where both layers reside in the same JVM. * Not understanding these basic principles can become very expensive.

Mastering Java EE Patterns

JSC: What Java EE patterns should a developer master?

Bien: Why not all of them? You can't know too much. In the Java EE 5 space, it's more important to decide whether the application should be built on domain-driven (object-oriented) or service-oriented (procedural) principles. Hybrids are possible as well.

Making such decisions is difficult because you have to understand the target domain. It's crucial to think about the nature of the persistent domain objects. Deciding whether they should be anemic or rich can heavily impact the remaining structure of the systems. With Java EE 5, you can even write something like this:

    training.login(userName,password).
            running().
            today().
            weather(SUN).
            averagePulse(135).
            comment("ok").
            length(65).
            maxPulse(165).
            km(12).
            add();
 

The method login belongs to stateful session bean (EJB 3):

   @PersistenceContext(type=PersistenceContextType.EXTENDED)
    EntityManager em;

    private User user;

    public TrainerBean() {
    }

    public Season login(String name,String password) throws
UnknownUserException,AuthenticationException{
        this.user = this.em.find(User.class,name);
        if(user == null){
            throw new UnknownUserException(name);
        }
        if(!user.getPassword().equalsIgnoreCase(password))
            throw new AuthenticationException(name);
        return this.user.getCurrentSeason();

    }
//lot of code omitted

}

@Entity
public class Season implements Serializable {

    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private long seasonId;

    @Column(name="season_year")
    private int year;


@OneToMany(cascade={CascadeType.MERGE,CascadeType.PERSIST},fetch=FetchType.EAGER)
    private Collection<Unit> trainingUnits;

    /** Creates a new instance of Season */
    public Season() {
        this.trainingUnits = new ArrayList<Unit>();
        this.year = GregorianCalendar.getInstance().get(Calendar.YEAR);
    }


    public class UnitBuilder<T extends Unit>{
        protected T unit = null;

        UnitBuilder(T unit){
            this.unit = unit;
        }

      public UnitBuilder<T> averagePulse(int averagePulse){
            unit.setAvgPulse(averagePulse);
            return this;
        }

        public UnitBuilder<T> today(){
            unit.setTrainingBegin(new Date());
            return this;
        }

        public UnitBuilder<T> comment(String comment){
            unit.setDescription(comment);
            return this;
        }
//lot of code omitted
}
 

whereas the other methods are actually a builder pattern inside connected and rich domain entities. You can see the full source code at project RunAndBikeDB.

Such a programming style was simply impossible with standard J2EE 1.4 APIs.

Working with procedures instead of objects can lead to many hard-to-maintain if-else instanceof statements and superfluous type-queries. Some architects still try to enforce stateless, coarse-grained architectures for every use case -- such a decision can result in a hard-to-maintain and expensive system.

On the other hand, pure object-oriented systems can be monolithic. So it's important to verify and adjust such decisions in every iteration or increment.

Patterns only help in the design-implementation phases -- but you have to decide first which architectural style would fit the given context. Actually, services and objects are opposite best practices.

The Inefficiency of Large-Scale IT Projects
 
"Large-scale IT projects are inherently inefficient. It's a misconception to even talk about a large-scale project."
 
 
Adam Bien
Java Champion

JSC: What are the biggest misconceptions that you encounter in implementing Java technology in large-scale IT projects?

Bien: Large-scale IT projects are inherently inefficient. It's a misconception to even talk about a large-scale project. The trick is to divide a huge project into small, two- to five-member developer teams that can act independently and be responsible for particular parts of the project. This is a challenge, but it's worth a try.

Only then will developers identify with the code and feel responsible for it. This is the key to success. In large-scale projects, this feeling of responsibility can dissipate, so developers get distracted and forget coding, which is the beginning of the end. Because really big projects must succeed despite their inefficiencies, they often receive more and more resources and budget.

It's amazing how much you can achieve with a few passionate developers, but sometimes it's hard to convince management of this.

Java SE 6 Platform Features

JSC: What are some lesser-known Java SE 6 features that you think developers should know about?

Bien: First, JDK 6 comes with Java DB, or Derby, a great scalable and embeddable relational database, which is easy to install and maintain and even DB2 compatible.

Second, scripting support: Java SE 6 comes with JavaScript support and even a cool jrunscript that allows you to test the scripts "outside" the VM. Beyond this, there are already many scripting languages available: Groovy, Ruby, BeanShell, JavaFX Script, and so on. See the scripting project home page for more information.

Third, JConsole was extended, so it's easy to create custom tabs. It looks better as well. The java.util.ServiceLoader class is an interesting generic factory that can be configured in a standardized way and can make some of your factories superfluous:

public static <S> S load(Class<S> clazz){
    ServiceLoader<S> loader = ServiceLoader.load(clazz);
    for (Iterator<S> it = loader.iterator(); it.hasNext();) {
        S impl = it.next();
        if(it.hasNext()) {
            throw new IllegalStateException("More than one interface...: " +
clazz.getName());
        }
        return impl;
    }
    throw new IllegalStateException("Cannot find...: " +clazz.getName());
}
 

ServiceLoader just searches for the implementation for the passed interface. ServiceLoader can be configured in a file with the name of the interface. Inside the file, the name of the implementation has to be specified. For example:

package net.java.service;
public interface HelloService{...}

package net.java.service.pojo;
public class SayHello implements HelloService{}
 

You will then need a file named net.java.service.HelloService and the content net.java.service.pojo.SayHello. I really like this mechanism. It standardizes the configuration and it is not XML-based.

Beyond that, Java SE 6 comes with better web service support in addition to its own HTTP server. The performance and scalability have also improved greatly.

Writing Javadoc Comments

JSC: What should developers understand about writing comments for Javadoc? Any tips?

Bien: Most of the Javadoc comments in projects are worthless. They redundantly describe information that can be easily obtained from the method's signature. Developers are actually forced by, for example, QA (Quality Assurance), to write dumb Javadoc, just to increase some metrics.

However, this approach is expensive, first, because the creation of superfluous documentation takes a huge amount of time. Second, redundant Javadoc -- for example, repetition of the parameters and return values in Javadoc -- is hard to maintain. And third, what's worse, in the maintenance phase, all developers are forced to filter out relevant things and ignore worthless information. It is really hard to pick up the essential responsibility of the documented artifact, background knowledge, the "why" from the obvious "noise."

The classic example is this:

/**

* This is a setter that sets the name

@param name - the name to be set as String

*/

public void setName(String name) {...
 

Existing information from the method's signature is replicated to the Javadoc. In my opinion, such a Javadoc is superfluous -- every Java developer knows what getters and setters are. The same antipattern is often applied to document other elements -- not only obvious JavaBean "components."

Instead of writing superfluous documentation, you could also introduce a new Javadoc tag or annotation to mark such use cases, for example, @Obvious. In this particular case, the QAs should be happy with the doc coverage and developers could silently ignore the doc.

@Obvious
public void setName(String name) {...
 

Here's some advice:

  • Document the nonobvious background knowledge, the intention and not the result.
  • Try to capture the concepts in a central place -- for example, a wiki -- and only reference the contents.
  • "Escape" obvious facts with marker tags -- don't describe them over and over again. Be DRY.
  • Include samples, how-to's, and so on in your documentation.
  • Don't allow default Javadoc comments generated by the IDE.
  • Sometimes "No doc is the best doc" -- try to minimize the amount of documentation and describe only the key concepts.
The Power of the GlassFish Application Server

JSC: What are the biggest misconceptions about the GlassFish application server?

Bien: Many developers tried GlassFish's predecessor some years ago and found it wanting and now are no more interested. But it's worth a try. GlassFish's performance and scalability are great.

I especially like several features. The web-based admin console makes it possible to complete all basic administration tasks. The documentation -- even free books in PDF format! -- is already available from the first page. I appreciate the ability to configure even the JVM options inside the admin console. Also, there are different ways to configure: asadmin.bat, the visual admin console, and the XML files.

The monitoring, CallFlow, allows you to visualize the invocation hierarchy of all EJBs -- tree, table, and diagram view -- which is very helpful in the development phase.

I value asupgrade.bat, a small Swing app that can be used to migrate the old configuration to a new one. There is excellent NetBeans integration, with the local and even remote deployments working well. Finally, I'll mention the extensive diagnostic capabilities. You can register your own JMX beans, which can be invoked under certain configurable events, for example, DataSource is empty, and so on.

JSC: How does the world of Java EE differ from the rest of the world of Java technology?

Bien: It's a parallel universe. Java EE abstracts from distribution, transaction, databases, messaging, and back-end connectors. So it's really an object-oriented API of enterprise systems. And it was mainly driven by the vendors. JDBC, JMS, JTA, and JCA APIs were created as standardizations of existing products. If you already know the back-end systems, Java EE should be quite easy.

Passionate, Questioning, and Fun: The Perfect Developer

JSC: Tell us what qualities a perfect developer should have and why.

Bien: A perfect developer should be passionate and willing to ask questions and learn from other team members. Passionate developers can often learn things very fast. Experience is not that important if you are willing to learn from others. This is important for building a team and having fun. To me, the most important quality is the ability to have fun working on projects.

JSC: Do you have any advice to someone just starting out as a Java programmer?

Bien: Yes, just start developing. Hello World is a good start. Be "passionated," not only motivated. Use the Internet resources, read books, don't be shy, ask questions. Everything that you learn will pay off. Java programming is a great place to start -- most of the resources and tools are open and free.

JSC: The Java class that you couldn't live without is...?

Bien: It's not a class, but a whole package. I like Swing. It's fast, looks great -- check out nimbus look and feel or substance -- and becomes even more interesting with the Consumer JRE or Java SE 6 Update N.

I like Swing because I know that everything is possible. I don't feel this about SWT or JFace.

JSC: What recent changes to the platform have made your life easier?

Bien: Annotations, generics, and enums.

JSC: What do you enjoy most about programming?

Bien: The challenges and creativity. It's like sports -- you have to learn and practice a lot and steadily improve your skills. I've been working with the Java language since JDK 1.0 and it's still lot of fun. Too much fun. I actually prefer programming to vacations.

I participate in interesting open-source projects like, for example, p4j5.dev.java.net, underworld.dev.java.net, greenfire.dev.java.net, or fishfarm.dev.java.net in my leisure.

JSC: Where in the process of programming do you have the most fun?

Bien: When I can provide the fastest, quickest, expressive, and simplest but still maintainable and suitable solution for a given problem. I enjoy the whole process then. I really enjoy deleting superfluous "legacy" code as well.

JSC: Where do you feel that you are most creative?

Bien: I like to develop software in trains, planes, and hotels. It's dead time -- I always carry a second power battery with me.

I'm really creative in stressful situations. No matter where I am, when I'm stressed by shipping dates or problems, I come up with the most interesting and creative solutions.

The Process of Writing Code

JSC: Can you describe the process of writing code?

Bien: It is almost mystical and hard to describe. If you are really motivated, you can develop whatever you want in the shortest period of time. The sky is the limit.

To write good code, you have to understand the domain and the actual problem first. But the best way to learn the domain is to write code. So the challenge is to balance between bottom-up and top-down approaches.

I try to analyze the problem, then write some code, verify the solution, and sometimes adjust the problem to code in talking with customers. So the natural way to write code is in short iterations and feedback cycles with a short waterfall phase.

JSC: What technical insights into the Java programming language have been most important to you? When you're stumped, what do you do?

Bien: As JDBC came out (JDK 1.1), I reviewed the source code of the drivers and the API. This was a good learning experience. I understood the power of interfaces, factories, and reflection.

If I'm stumped, I search first in the JSR (Java Specification Request). These are free PDF "books" that can be downloaded from jcp.org. The single truth is inside the specs.

After this, I use Google -- it's faster. I read books just for fun. And it's worth it -- it's hard to find a bad book. Every book describes something new and interesting to some degree.

_______
* As used on this web site, the terms "Java Virtual Machine" or "JVM" mean a virtual machine for the Java platform.

See Also

Adam Bien
Adam Bien's Blog
From Java Platform Improvements to Better Teaching: A Conversation With Java Champion Cay Horstmann
Java Champions
NetBeans Dream Team
Becoming a Better Programmer: A Conversation With Java Champion Heinz Kabutz
Java Champion Geert Bevin and His Work With JavaScript
Java EE at a Glance
Writing Javadocs

Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.