Advanced Web Projects
The default project types and layouts cover many of the common application and development needs. Sometimes you need to do more with a Web project; you can use it to improve your development process, organize your code, and share your work with other team members.
Here are some development considerations that can determine the organization of a project:
Project Deliverables: These are the concrete outputs of the development activities. For example, in a J2EE development project, deliverables are the standard modules such as Web application archives (WARs), EJB component archives (JARs), Enterprise application archives (EARs), and so forth. Architecture also influences the design of deliverables. You may use a single EAR project if all the containers run on the same application server. However, it will be better to divide the projects if the Web and EJB containers are on different servers.
Some projects are simple Web applications while others involve multiple modules and components. An application may group many Web applications and EJBs together. The J2EE specification describes a structure for these deliverables.
- Team Organization: Team organization determines who will do what in the project. A team can be one person or it can have groups of developers. The structure of the project is a significant factor in determining the productivity of the team and the management of the overall software engineering process.
- Change Control, Configuration and Release Management: Software can be viewed in terms of components that are assembled and configured to form an application. It is important to track the changes to these components using a version control system. The organization of these components determines the units that are used to control the changes in the scope of the project. The configuration and version of components that make an application are very important to the release process.
- Testing: Test plans, test cases, and execution of the tests must be regular and continuous parts of the development process. Test objectives and responsibilities are determined based on the modules. Unit and integration tests are part of the development for each module.
When the WTP project was started, the development team had long discussions on how to extend the basic Java projects to handle different styles of custom projects. A key requirement for Web projects was to enable the separation of the two fundamental view points to help manage resources in a project, for example, the developer view and the runtime view.
The runtime view is defined by the J2EE specification. The developer's view is most often modeled using the J2EE specification. Mimicking the structures defined in the specification creates valid J2EE applications, but this is not always suitable for all development projects.
In WTP, the developer's view of a project is captured by a model that maps the contents of the project to the runtime view. Each WTP Web project has a structural model that is used to describe how developers lay out the resources. Publishers and WTP tools use the structural model to create J2EE artifacts. This mapping gives you flexibility to create projects in ways that you could not do before. For that reason, WTP developers sometimes also refer to these projects as flexible projects. We'll use the term Web project in this book.
Technically speaking, an Eclipse project that has the Module Core Nature is a Web project. This nature indicates that these projects have a structural model for the modules and will support WTP tools. We will start with a short description of this advanced project capability, and then give examples demonstrating its use. Power users can employ these capabilities to create many different layouts for their projects.
Modeling the Developer View
The structural model of a Web project tells publishers how to compose a runtime artifact (see Figure 6.26).
Figure 6.26 Structural Model
This model is defined in an XML component file stored with the other project settings. The project settings and component files are normally invisible in the Project Explorer view. However, they are visible in the Eclipse Navigator view that is included in the Resource perspective. The structural model is stored in a file named
inside the . settings folder of any Web project (see Figure 6.27).
Figure 6.27 Structural Model Definition
The model file listed in Example 6.1 is for a typical dynamic Web application module. The module is named LeaguePlanetWebProject. The model specifies how resources in the development view map to resources in the runtime view. Here, you map the complete contents of the WebContent folder to the module root. The source-path is relative to the project root and the deploy-path is relative to the module root at the destination. You can have as many resource mappings as you like for each module. The module also has type-specific properties such as context root, which defines the context root of the Web application module. The java-output-path property tells the publisher where to find the compiled classes.
Example 6.1. Web Module Definition
<?xml version="1.0" encoding="UTF-8"?> <project-modules id="moduleCoreId" project-version="1.5.0"> <wb-module deploy-name="LeaguePlanetWebProject"> <wb-resource source-path="/WebContent" deploy-path="/"/> <wb-resource source-path="/src" deploy-path="/WEB-INF/classes"/> <property name="context-root" value="LeaguePlanetWebProject"/> <property name="java-output-path" value="build/classes"/> </wb-module> </project-modules>
Another example is the model of an enterprise application (see Example 6.2). Here the interesting parts are the dependent modules. In this example, the EAR uses an EJB module and a Web module. A dependent module is referenced using a handle, which is a module URL. A module URL starts with the prefix module:, and is followed by a workspace-relative path to determine the project and the name of the module within that project.
Example 6.2. EAR Module Definition
<?xml version="1.0" encoding="UTF-8"?> <project-modules id="moduleCoreId" project-version="1.5.0"> <wb-module deploy-name="LeaguePlanetEar"> <wb-resource source-path="/EarContent" deploy-path="/" /> <dependent-module deploy-path="/" handle="module:/resource/LeaguePlanetEJB/LeaguePlanetEJB"> <dependent-object>EjbModule_1147426182270</dependent-object> <dependency-type>uses</dependency-type> </dependent-module> <dependent-module deploy-path="/" handle="module:/resource/LeaguePlanetWebProject/LeaguePlanetWebProject"> <dependent-object>WebModule_1147426182290</dependent-object> <dependency-type>uses</dependency-type> </dependent-module> </wb-module> </project-modules>
The structural model is a mapping for the organization of files that are distributed over a set of Web projects. A publisher uses this model and can construct a deployable, runtime Web artifact as described in the J2EE specification.
When you create projects and modules using a project creation wizard, the model is automatically added to a project. Wizards create a model based on a default template. However, you can easily modify the default mapping as shown in the next sections. Some of the common types of artifacts used in model definitions are resources, modules, and dependent modules.
A resource is an abstraction of project artifacts such as files, folders, and libraries. An Eclipse project maintains its resources, ensuring that each resource is loaded only once within the workspace. Resources are referenced with resource URIs, which are relative to the projects that contain the resource. WTP has additional URI converters that can resolve URIs to their underlying physical resource, such as the module URI we discussed earlier.
A module represents a deployable artifact, such as a WAR, EJB JAR, or EAR. A WTP project can be associated with only one module, but it can refer to others. This makes it possible to distribute the code for a module over a set of projects.
A J2EE module has a standard layout and is targeted to some J2EE runtime container. J2EE projects generate archives as JARs or as exploded archives. These archives must contain compulsory files, such as deployment descriptors, and must conform to the J2EE specification. There are five core types of J2EE modules and a general-purpose utility module:
- Enterprise application (EAR)
- Enterprise application client (JAR)
- Enterprise JavaBean (JAR)
- Web application (WAR)
- Resource adapter for J2CA (RAR)
- Utility modules (JAR)
As its name suggests, a dependent module is used to define dependencies between modules. It can also help define a module with its code split into several projects. For example, we can maintain the Web applications that are in an enterprise application as dependent modules. Another common pattern is to maintain basic utility JAR modules, which contain the extracted contents of the archive, as separate projects. The benefit of using extracted modules is that all the artifacts can be modified, and Web projects assemble them into a deployable form.