by Steven J. Owens (unless otherwise attributed)
Somebody asked:
I'm new to the world of j2ee and would appreciate your guidence. I'm about to start a new project. Its a relatively straight forward database application - inventory, sales etc. Its for a small company and will end up serving about 20 people. [...] What is the recommended architecture for this kind of project today? Is it J2EE? Can you point me to some articles that could help me make an informed decision? Are there any development tools that you recommend?
There are a lot of good books out there on J2EE. One I like for the general stuff is Mastering EJB and the J2EE Platform Enterprise Edition, by Ed Roman. Sun has their "Blueprint", which includes a description of a sort of generic system. There are tons of articles. See some more specific recommendations at the end.
Thinking about it, I guess I'd like to see a full-blown J2EE reference application, as open source, somewhere. It'd be pretty straightforward to code, and it'd be the best way (along with good docs) to explain J2EE to somebody.
Here's my off-the-cuff outline of the J2ee basics:
JSP is focused on the presentation of your application - the order entry screens, the inventory report screens, etc. Build dummy HTML pages for all of these (keeping them as simple as possible), then convert them to JSPs (which should be pretty trivial at this point). JSPs work like templates - you type up the HTML for what you want to see, then at various points you insert special little JSP tags that do the scripting, pull the data in from elsewhere, etc.
For now, just pretend the JSPs are templates - flat text files that you're going to later write code to insert your live data into. What you'll learn later is that the J2EE JSP compiler actually converts your JSP into the java code necessary to make a servlet that does exactly that - insert your live data for you.
There is a lot more you can do with JSPs - and what you can't do, you can define tag libraries to let you do. You could build an entire system in JSPs alone, with embedded chunks of java where necessary in the JSP, to do stuff that JSP alone can't handle. However, just because you can doesn't mean you should. Not when there are better, more powerful tools available. For now, focus your JSP efforts solely on the template role. Later on you can get tricky.
Remember when I said your JSP tags get converted into a servlet? Servlets are basically an HTTP entry point into the JVM, along with a lot of handy classes, like:
In general, you use servlets for the really complicated stuff about your site, the traffic cop functions, the business logic. When it comes time to actually send something back to the user, you should use RequestDispatcher to send bounce the connection over to a JSP, which constructs the HTML text to send back. Data that the JSP needs to get at should either be stuck in a Session variable, or if you have a lot of data, or a complicated structure, then you build a special class to hold it, usually a JavaBean, and stick that in the session variable.
JavaBeans are an annoying topic to try to write about, because they're a meta-topic. Most articles on JavaBeans start by saying a JavaBean is a component, but that doesn't mean a whole hell of a lot to a working programmer.
The most succinct way I've come up with to define them is to say that a JavaBean is any class which, if you hand it to the JavaBean Introspector, the Introspector can come up with a BeanInfo object. Other tools (like the BeanBox and similar tools) can then use that BeanInfo to figure out how to interact with your JavaBean class. The classic example is to dynamically generate a GUI with an input box for each instance variable in your JavaBean.
There are generally two ways for the JavaBean Introspector to come up with a BeanInfo object. One way, which doesn't seem to get used a lot, is to manually write your own code to define a MyComponentBeanInfo object, which the Introspector will look for when you hand it a MyComponent object. Another way is to code all of your component's instance variables with accessor methods that fit a certain naming format. Generally the pattern is:
String myInstanceVariable ; public String getMyInstanceVariable() ; public void setMyinstanceVariable(String myNewInstanceVariable) ;
The parameter name (i.e. "myInstance") is not part of the JavaBean pattern. There's a little bit of a gotcha to watch out for there - if your instance variable is named "myInstance", it will be capitalized differently in the method name. See the example above: myInstance --> getMyInstance.
Getting back to J2Ee, generally, especially in this sort of context, a JavaBean is meant to be fairly simple and straightforward - a sort of messenger class; you stick the values in here, send the class over there, and pull them back out. However, in other places (like all over the Swing library), JavaBeans are used in much more complex ways. Also, you're going to run into "Enterprise Java Beans", which will seem to be something else entirely (and although they are still in fact JavaBeans, they aren't built or used like JavaBeans, which will confuse the heck out of you; so don't think of them as the same thing, for now).
Two general gotchas about servlets to watch out for.
One that I've seen several times with good programmers just starting out with servlets is the tendency to overuse instance variables and treat the servlet as single-threaded. More to the point, if servlets were "properly" designed in an OO sense, you'd instantiate a new servlet object to handle each request. Then you could use instance variables all over the place to avoid having to pass a ton of parameters in each method call. There'd be a single thread dealing with each servlet instance at any given time, and you wouldn't have to worry about two or more threads all trying to write a different value to an instance variable at the same time.
Well, that's not the way servlets work. Servlets get instantiated once, the first time a browser asks for a URL that the servlet engine configuration says is associated with that servlet. Then they hang around. Servlets are multi-threaded; any number of requests could be winding their way through the servlet code at any given point in time. What you do, instead of what I described above, is keep as much of that state as possible in the Session, and try to make the in-servlet methods as static as possible; i.e. pass all of the parameters in with the method call, take the output from the return.
Unless you really need to write complex code, which is where the second gotcha comes in. There's a tendency for programmers to keep too much of the code in the servlet itself, to feel like they're constrained to the boundaries of the servlet. They're not entirely wrong - there's a lot you can do by focusing at the browser-server boundary, and using standard web techniques, bouncing back and forth from one to the other. However, really the servlet is just an entry point, a gatekeeper that deals with getting HTTP requests into the system and HTML responses back out. You can build the rest of the system using standard java/object-oriented design and build an interface layer with servlets and JSPs. You'll probably (almost certainly) be better off, if you do.
One thing I highly recommend is that, after you get basically familiar with servlets, read a good tutorial on building applications with JSPs. I don't necessarily recommend using a lot of that JSP complexity, but this can be a very useful thing to study, because the JSP spec basically formalizes a lot of basic good practice in coding servlets.
A simple example would be variable scoping. JSPs let you define variables with request scope, page scope, and application scope. In servlet terms, they map like this:
Now, notwithstanding my comments above about only using the servlet as an entry point, this illustrates a generally good idea - you will notice that you have to keep data around generally for one of those three scopes, and if you need to, then it's probably a good idea to use those mechanisms. All three of them provide you with places to stash variables when you need to keep them around. Which one you should use depends on how long you need the data, and how widely you want it to be available. I've seen a lot of servlet code where the developer obviously didn't quite understand the roles the three scopes play. Hell, I've written some code like that! (though in my own defense, a lot of that came from starting out with servlets before a lot of this was formalized :-).
Enterprise Java Beans are not at all like plain old Java Beans, at least not in any sense that's going to matter to you. Somebody will certainly pop up and quibble with this - EJBs do in fact meet the Java Beans spec, etc, etc. Fine, but that's not going to be any use to you in understanding EJBs. I'm going to be vague and imprecise below, because I really just haven't played with EJBs all that much. So take all of this with a huge grain of salt. I'm sure those more knowledgable will correct me where necessary.
EJBs are like servlets, in that they get instantiated by the server as necessary, and hang around waiting for requests. However, EJBs are engineered at another level - instead of being built to deal with HTTP requests, which are basically text pumped over a TCP/IP connection, EJBs work over Java RMI (Remote Method Invocation). RMI is java's network protocol for objects in one JVM to talk to objects in another JVM, without the programmer having to invent a network protocol and write a bunch of code. You can actually push an object (as long as it's serializable) or a bunch of interconnected objects, across an RMI request to another JVM.
At a higher level, EJBs have built-in support for transaction processing and for managing data persistence. There are two main kinds of EJBs, Entity Beans and Session Beans. The most recent EJB spec added a third kind, Message Beans, to help integrate JMS message queues with EJBs. Session Beans aren't related to Servlet Sessions, but I'll get to them in a moment.
Basically an Entity Bean's job is to be a glorified data object, with code built into it to manage pulling the data from the database and writing it back out.
The basic layout of the Entity Bean itself has methods that automatically get called by the server at various times, like when the bean needs to be loaded, when it needs to be saved, when it needs to be swapped out, when it needs to be swapped back in, and so forth. The EJB server (called a "Container" in EJB parlance) loads the EJB in, and calls the appropriate methods according to whatever's going on.
Entity Beans get a bad rap from a lot of people, due to performance problems. I haven't worked directly with EJBs enough to comment on that, but my guess is that EJBs are neither a panacea nor perfect, and it's human nature to want to stick with what you know unless you see a major advantage in moving.
Entity Beans come in two sub-flavors - Container-Managed Persistence (CMP) and Bean-Managed Persistence (BMP):
BMP means that the you write your own code on the Bean to handle loading and saving the data.
CMP means you use some mechanism - usually an XML configuration file (or maybe a GUI tool provided by the company that wrote the server you're using) - to define the database-table-to-object-instance-variable mappings. Then the container handles loading and saving the data for you.
CMP sometimes gets a bad rap, but I take it all with a grain of salt. First there are my comments about EJB's bad rap in general. Second, well, frankly, I'm pretty cynical - I long for true orthogonal persistance; even if CMP worked perfectly it'd still be lame in my eyes!
Session Beans are oriented towards transactions, not data persistence. Session Beans, like Entity Beans, come in two flavors: Stateless and Stateful.
In a sense, a Stateful Session Bean is a lot like what "Servlets Done Right" would be like. The server maintains a pool of Stateful Session Beans, and checks out one to each user. The code can feel free to tweak instance variables and generally use OOP techniques, because nobody else gets into that Stateful Session Bean until the request is completed. However, this is Not Cheap, so of course you don't want to use them unless you have to.
Stateless Session Beans are, well, stateless. They're less expensive that Stateful Session Beans, so you use them where you don't need to have state.
In general, you're supposed to use EJBs for business logic. In other words, you use JSPs for presentation, Servlets for directing traffic, and for doing the actual business stuff - entering an order, or making a reservation, etc - you make a call over to a Session Bean. The Session Bean has the code for doing the actual logic, and it uses (in theory) an Entity Bean to actually get at the data.
You're going to need a whole stack of books on diverse topics, most of them java related but some not, to really learn this topic.
I'll omit the metric ton of general java books, not to mention various works on HTML and related topics, but I strongly recommend you learn as much as you can about HTTP. Get a packet sniffer and watch the requests and responses going back and forth from browser to server. Not only is a great way to learn about what's going on, it's useful as hell when debugging.
If you're on a unix system, a good one is tcpflow. One caveat is that tcpflow doesn't log the requests/responses sequentially, because strictly speaking, in TCP there is no request/response. Just two separate messages between two different programs on two separate machines/ports, that happen to use symetric port numbers and be going in one direction and then the other. Still, you can fake it easily enough. Someday I'll get around to writing a sniffer specifically for this purpose, and it'll do useful things like skip over binary data...
The Jakarta SOAP project has a TCPTunnel class and a TCPTunnelGUI class that is designed for just this purpose, although it only displays a single request and response. To use it, get the soap.jar from xml.apache.org/soap. A brief description of it is in the docs there:
http://xml.apache.org/soap/docs/guide/tools.html
Now, on to the books...
Of course, I highly recommend Jason Hunter's Java Servlet Programming.
In general, I'd recommend reading the servlet spec, then the JSP spec, then the J2EE spec. I particularly recommend reading the servlet spec, it's very useful but also not that long. I remember it being something like 60 to 90 pages, whereas the J2EE spec is much, much longer. JSPs compile to servlets, sooo... (see my comments above about good practices and JSP).
In addition, I have recently been reading O'Reilly's _Programming Internet Email_, by David Wood. I've been finding this a useful and interesting read, even before I get to the point of doing any fun stuff with email, because a big chunk of the book is about the MIME format, which is what HTTP uses for requests back and forth. This is a good thing for any servlet programmer to know about.
In general, note that J2EE is really an umbrella over - and a coherent approach to bringing together - numerous enterprise-level java APIs, so reading the specs on all of the involved APIs can be quite useful - but that's a heck of a lot of APIs (Servlets, JSP, EJB, RMI, JNDI, JMS, and JTA are just the ones I can think of off the top of my head!). You will probably find it a lot easier to read some J2EE-focused books first, and then try to fit the individual APIs into the picture, rather than looking at each API and trying to assemble a picture. There's also the voluminous (if not longer) Sun J2EE Blueprint.
Given all of these APIs, you might find the O'Reilly Java Enterprise In a Nutshell book, by David Flanagan, Jim Farley, William Crawford, Kris Magnusson, useful. The copy I have dates from 1999, I'm not aware if there've been any updated editions since then. On the other hand, according to O'Reilly's site, that edition is up to date to Java 1.2 and the releases since then haven't really made any major changes to the various enterprise APIs (although J2EE itself changed, particularly in the servlet spec and the EJB spec).
I'd also strongly recommend J2EE Applications and BEA Weblogic Server by Gridley/Woollen/Emmerson, particularly if you're going to use BEA, but I've found it generally worthwhile. Note that is not the similarly-named Java 2 Enterprise Edition with BEA Weblogic Server, by Paco Gomez and Peter Zadrozny, Wrox Press, which I didn't find that useful (sorry guys).
I have yet to get and read the Sun Microsystems Press J2EE book, but it's on my list. While I find the Sun Microsystems Press books to be massive tomes and somewhat tedious reading, part of that is because of the massive detail; they're inevitably worthwhile. I find Core Java, Volumes 1 and 2 indispensable. I generally try to read a friendlier book on any given topic first, then once I have a general sense of it, I go to the Sun Microsystems Press book when I need to check specific details or get detailed clarification.
The O'Reilly JSP book, Java Server Pages by Hans Bergsten, is pretty good, but (sorry Hans) this is one of those rare cases where another publisher's book is better, that being JavaServer Pages by Larne Pekowsky, Addison-Wesley.
While I don't work with EJBs nearly as much, I liked Ed Roman's Mastering Enterprise Java Beans and J2EE Platform Enterprise Edition book, and I also liked Addison-Wesley's EJB book somewhat. Richard Monson-Haefell's EJB book is widely respected, but I found it slow going - it may have been too deep for my first time around and since most of my J2EE work has not been focused on the EJB aspects, it hasn't made it back to the top of the stack yet.
While it's not intrinsic to J2EE, books on the various XML APIs for java are highly recommended reading, particularly with the rising popularity of Web Services. I don't have any specific recommendations offhand, other than (of course) O'Reilly's books on the topic (XML in a Nutshell, by Elliotte Rusty Harold and W. Scott Means, Java & XML, 2nd Edition, by Brett McLaughlin). I've had some friends highly recommend the Wrox books, but I have yet to crack 'em open.
Mark Galbreath, a regular contributor on the j2ee-interest@java.sun.com mailing list, also makes the following book suggestions (reprinted with his permission).
There is no single volume [that will cover everything you need to know to do J2EE].
IMHO, the Wrox book [on j2ee] is worthless. I have both Professional Java Server Programming and Professional Java Programming [from Wrox]. I find subjects on which I need information are scattered throughout the book (check out the index), the material is presented in a vague, incomplete manner, often with references to other parts of the book and the code examples are incomplete, rarely compile and assume knowledge on the part of the user that, if there in the first place, would negate having to use reference material. In short, they suck.
I also have Professional ASP and Profession Visual Basic Programming. They are much better organized and clearly presented than the Java books.
On the whole, I've found the Sun (published by Prentice-Hall) and O'Reilly books unbeatable in clarity and content for any subject from language specifications to programming tutorials. I particularly like the "nutshell" books.
Finally, there are absolutely no substitutes for reading the Java Language, J2EE, Servlet, and JSP specifications!!
Cheers!
Mark
P.S. If all the above is not enough, then check out http://jakarta.apache.org/struts. ;-)~,