This project demonstrates how you can develop applications with the Java EE platform using widely adopted architectural best practices like Domain-Driven Design (DDD). The code is intended to mirror a non-trivial application that developers in the real work would work on. It attempts to demonstrate first-hand how you can use Java EE to effectively meet practical enterprise concerns such as productivity, agility, testability, flexibility, maintainability, scalability and security.
The project is directly based on the well known original Java DDD sample application developed by DDD pioneer Eric Evans' company Domain Language and the Swedish software consulting company Citerus. The cargo example actually comes from Eric Evans' seminal book. That project uses older versions of Spring, Hibernate and Jetty whereas we focus on vanilla Java EE.
In the same vein as that project, we certainly are not in the business of prescribing how you should write Java EE applications. The code simply demonstrates ideas that you could adopt if you think they are right for you. We've also tried to show you just some of the many different approaches that you could take to interpret and implement DDD concepts. You are of course warmly welcomed to provide feedback and contribute to this Open Source project.
As such, we will continue to rely heavily on the original DDD sample application as well as the existing knowledge base in the DDD community as invaluable resources on further details on DDD as it applies to this code base (please see the Resources page for vital details). We also highly recommend you read the DDD and Java EE section. It is perhaps best to skim it, explore the application/code and revisit the section.
This effort is very grateful for the kind blessings and guidance of the good folks behind the original DDD sample application.
Contrary to beliefs long held by some folks, Java EE does not attempt to be a walled garden. Like all open standards, the goal of Java EE is to provide a reliable core standard foundation that a vibrant ecosystem of plug-ins and extensions can be built around. In that spirit, we will incorporate a select set of representative tools that complement Java EE well such as Maven, JUnit, Cargo, JMeter, soapUI, Arquillian, PrimeFaces and DeltaSpike.
Before exploring the code, it may be helpful to view a demo of the application functionality. You can do that through a screen cast that covers most of the major functionality for Cargo Tracker.
If you simply wish to explore the code, download it as a Zip or browse the repository.
The source is a Maven project, so you should be able to easily build it or set it up in your favorite IDE. We currently have instructions for NetBeans and we would welcome a contribution showing how to use the project with IntelliJ IDEA. Note that we currently do not recommend Eclipse due to it's poor support of Maven. For the detailed reasons, please look here.
You can also run the application directly from the Maven command line using Apache Cargo. All you need to is navigate to the project source root and type:
mvn package cargo:run
Once the application starts up, just open up a browser and navigate to http://localhost:8080/cargo-tracker/.
The project currently runs on Java EE 7/GlassFish 4 and Java SE 8 by default. You can also run the project using WebLogic 12.2.1 and Java SE 8 using these instructions. We welcome contributions for running the application on other Java EE application servers (as you will see in the source code, there are few dependencies on GlassFish or WebLogic so this should be pretty easy to do).
Our roadmap (see JIRA) includes plans to create a Java EE 6 version of the application.
Many of you might have at least heard of the J2EE Blue Prints/PetStore. In many ways, the J2EE Blue Prints/PetStore was far ahead of it's time. It helped establish some degree of order out of the chaos of mid-nineties enterprise development. It brought to the mainstream many architectural patterns like separation of concerns, layering, MVC, DAO, DTO and the like that we now mostly take for granted. It also helped catapult J2EE itself. The PetStore of course was not without its own fair share of problems. The most significant of these problems is the fact that many patterns in the PetStore were either motivated or encumbered by the problems of the then relatively new J2EE and EJB 2 technologies and EJB 2 entity beans did not support OO well.
DDD provided concrete solutions to the weaknesses in the PetStore with the help of emergent concepts of POJO programming, ORM and lightweight frameworks. It is no accident that DDD is now widely adopted by the Spring, .NET and Rails communities. As Java EE has now fully embraced concepts like POJO programming, lightweight programming models, annotations, ORM, rich domain models, agility and testability, this project brings things full circle. It demonstrates first hand how you can utilize the best of the breed in enterprise software development practices using the power and simplicity of the standard, vendor-neutral Java EE platform. Notably unlike the J2EE Blue Prints/PetStore, we will not invent new patterns here but simply adopt the proven, mature ideas in the DDD community.
As the name implies, Domain-Driven Design is an approach to software design and development that focuses on the core domain and domain logic. The domain is implemented through a careful focus on traditional OOAD (Object Oriented Analysis and Design) and modeling the real world problem the software is trying to solve as closely as possible.
Wikipedia does a surprisingly good job at overviewing DDD. Aslam Khan's DDD Ref Card on DZone is a brief read and does a great job of explaining the core concepts of DDD. For a bit more detail, you could read the free DDD eBook on InfoQ. Finally, you can of course read Eric Evans' book itself. However, we recommend not starting with the book until you get a bit of your bearings around this application first.
The basic building blocks of the domain are entities, value objects, aggregates, services, repositories and factories. The Characterization page overviews how these concepts are implemented in the application using Java EE. Logical layers partitioning distinct concerns are super-imposed on the core concept of the domain. These layers generally consist of the UI/interface layer, the application layer, the domain layer (of course!) and the infrastructure layer respectively. The Layers page explains the architectural layers in the application and how they relate to various Java EE APIs. The DDD community also fully embraces practices like Test Driven Development, Agile, Emergent Design, Refactoring and Continuous Integration. We've incorporated all these practices into the application in a pragmatic fashion.
One of the primary principles of DDD is that design should be focused on the business domain, not technology. The role of technology is to empower software developers to implement readable, productive, maintainable systems that mirror the real world, not place constraints on design choices. Most mainstream technology stacks today have matured enough to make this principle a reality, Java EE is no exception. In fact, with a single-minded focus on simplicity, POJOs, Java/OO centric strong typing, annotations and intelligent defaults that minimize system configuration and lets developers focus on solving the business problem, we think Java EE is one of the best platforms to support DDD. Java EE makes it possible to quickly and effectively produce a working system by annotating domain and application classes and implementing interface and infrastructure code. In the Characterization and Layers pages we've overviewed how some key Java EE APIs map to DDD concepts and pointed you to some of the most important bits of implementation code in the application. In the figure below, we've summarized how this mapping looks like visually as a handy cross reference.
Note, the diagram above is most certainly not intended to be comprehensive. For example, besides JSF, JAX-RS, WebSocket and JBatch, some other technologies that are very useful in implementing interfaces are CDI (for JSF backing beans), Bean Validation, EJB (e.g. remote or JMS messaging end-points), JAX-WS (SOAP end-points) and JSON. Similarly, you can choose to implement application services as transactional CDI beans as opposed to EJB and you can use Interceptors, the low level JTA API and Java EE Concurrency Utilities in the application layer. Value Objects can be implemented as either JPA embeddables or entities. In addition to JPA, JMS, JAX-RS clients, JAX-WS clients and EJB clients it is very likely may use CDI, Bean Validation, JCA and WebSocket clients to implement infrastructure components. The point really is that Java EE APIs are there to help you implement elegantly designed systems as needed.
This is by no means a comprehensive list of the features used. Please see our roadmap for APIs and features we plan to include in the future.
|JSF||Facelets, templates, view parameters, view actions, message bundles, CDI compatible view scope, HTML 5 pass-though attributes, HTML 5 pass-though elements|
|CDI||Basic injection, scopes, named beans, qualifiers, events, observers, default enablement|
|EJB||Transactions, stateless session bean, message driven bean, startup singleton, CRON style scheduling, application exceptions, XML deployment descriptors, portable activation configuration|
|JPA||Generated ID, basic mapping, embeddables, many-to-one, one-to-many, enumerations, temporal types, named queries, managed persistence context, portable data source definition, schema generation|
|JAX-RS||REST endpoint, MIME types, client API, JSON processing, content-type negotiation|
|WebSocket||Server-side endpoint, sending messages to remote endpoints, EJB integration|
|JSON-P||Writing JSON using Streaming API|
|Bean Validation||Basic validation annotations, method level validation for REST endpoints, method level validation for local EJB application services|
|JMS||JMS 2 simplified API message send, portable JMS resource definition|
|Java Batch||Job operator, job XML, job properties, job context, job listener, skip listener, reader, writer, skippable exceptions, checkpointing, chunking|
|JTA 1.2||@Transactional interceptor|