Organizing the DayTrader Directory Structure
The first step to organizing the directory structure is deciding what build modules are required. The easy answer is to follow Maven’s artifact guideline: one module = one main artifact. Thus you simply need to figure out what artifacts you need. Looking again at Figure 4-1, you can see that the following modules will be needed:
- A module producing an EJB which will contain all of the server-side EJBs.
- A module producing a WAR which will contain the Web application.
- A module producing a JAR that will contain the Quote Streamer client application.
- A module producing another JAR that will contain the Web services client application.
In addition, you may need another module producing an EAR which will contain the EJB and WAR produced from the other modules. This EAR will be used to easily deploy the server code into a J2EE container.
Note that this is the minimal number of modules required. It is possible to come up with more. For example, you may want to split the WAR module into 2 WAR modules: one for the browser client and one for the Web services client. Best practices suggest to do this only when the need arises. If there isn’t a strong need you may find that managing several modules can be more cumbersome than useful. On the other hand, it is important to split the modules when it is appropriate for flexibility. For example, if you needed to physically locate the WARs in separate servlet containers to distribute the load.
The next step is to give these modules names and map them to a directory structure. As a general rule, it is better to find functional names for modules. However, it is usually easier to choose names that represent a technology instead. For the DayTrader application the following names were chosen:
ejb– the module containing the EJBs
web– the module containing the Web application
streamer– the module containing the client side streamer application
wsappclient– the module containing the Web services client application
ear– the module producing the EAR which packages the EJBs and the Web application
There are two possible layouts that you can use to organize these modules: a flat directory structure and a nested one. Let’s discuss the pros and cons of each layout.
Figure 4-2 shows these modules in a flat directory structure. It is flat because you’re locating all the modules in the same directory.
Figure 4-2: Module names and a simple flat directory structure
daytrader/pom.xml file contains the POM elements that are shared between all of the modules. This file also contains the list of modules that Maven will build when executed from this directory (see the Chapter 3, Creating Applications with Maven, for more details):
[...] <modules> <module>ejb</module> <module>web</module> <module>streamer</module> <module>wsappclient</module> <module>ear</module> </modules> [...]
This is the easiest and most flexible structure to use, and is the structure used in this chapter. However, if you have many modules in the same directory you may consider finding commonalities between them and create subdirectories to partition them. Note that in this case the modules are still separate, not nested within each other. For example, you might separate the client side modules from the server side modules in the way shown in Figure 4-3.
Figure 4-3: Modules split according to a server-side vs client-side directory organization
As before, each directory level containing several modules contains a
pom.xml file containing the shared POM elements and the list of modules underneath.
The other alternative is to use a nested directory structure, as shown in Figure 4-4. In this case, the
web modules are nested in the ear module. This makes sense as the EAR artifact is composed of the EJB and WAR artifacts produced by the ejb and web modules. Having this nested structure clearly shows how nested modules are linked to their parent.
Figure 4-4: Nested directory structure for the EAR, EJB and Web modules
However, even though the nested directory structure seems to work quite well here, it has several drawbacks:
- Eclipse users will have issues with this structure as Eclipse doesn’t yet support nested projects. You’d need to consider the three modules as one project, but then you’ll be restricted in several ways. For example, the three modules wouldn’t be able to have different natures (Web application project, EJB project, EAR project).
- It doesn’t allow flexible packaging. For example, the
webmodules might depend on a utility JAR and this JAR may be also required for some other EAR. Or the
ejbmodule might be producing a client EJB JAR which is not used by the EAR, but by some client-side application.
These examples show that there are times when there is not a clear parent for a module. In those cases using a nested directory structure should be avoided. In addition, the nested strategy doesn’t fit very well with the Assembler role as described in the J2EE specification.
The Assembler has a pool of modules and its role is to package those modules for deployment. Depending on the target deployment environment the Assembler may package things differently: one EAR for one environment or two EARs for another environment where a different set of machines are used, etc. A flat layout is more neutral with regard to assembly and should thus be preferred.
Now that you have decided on the directory structure for the DayTrader application, you’re going to create the Maven build for each module, starting with the
sappclient module after we take care of one more matter of business. The modules we will work with from here on will each be referring to the parent
pom.xml of the project, so before we move on to developing these sub-projects we need to install the parent POM into our local repository so it can be further built on.
mvn -N install in
daytrader/ in order to install the parent POM in your local repository and make it available to all modules:
C:devm2bookcodej2eedaytrader>mvn -N install [INFO] Scanning for projects... [INFO] ------------------------------------------------- -------------------- [INFO] Building DayTrader :: Performance Benchmark Sample [INFO] task-segment: [install] [INFO] ------------------------------------------------- -------------------- [INFO] [site:attach-descriptor] [INFO] [install:install] [INFO] Installing C:devm2bookcodej2eedaytraderpom.xml to C:[...].m2repositoryorgapache geronimosamplesdaytraderdaytrader1.0daytrader-1.0.pom.
We are now ready to continue on with developing the sub-projects!