Package structure and layers
The domain model should not be depended upon any other layer in the system. What we want in an application based upon DDD principles is what Jeffrey Palermo has coined the Onion Architecture. In large, four layers are common: 1. dev:Domain layer. Contains all types of domain objects, and is the core of the business. Examples: Entities, Value Objects, Repositories, Factories, and Domain Services. 1. dev:Application layer. Sits between the UI and the Domain as a facade for the domain objects. Useful for certain application architecture where the UI is separated from the domain application. Otherwise this is probably unnecessary. 1. dev:User interface layer. Contains user interactions, often graphical user interfaces. Web frameworks, MVC, simple user validation, etc. 1. dev:Infrastructure layer. Contains typically database interactions, web services and integration code, other glue code etc.
Structure the source code according to the logical layers of your application. Create a Java base package for each layer. The base package for the domain objects could for example be: "{}". Source code within this package should never depend on any other packages. Create a rule for it in AspectJ if you like, to force this restriction in compile-time. The DDD sample application shows how to structure the domain code into packages. Each aggregate has its own sub-package of the {} base package, which is a good practice. Repositories and Factories belongs to the same package as the root entity. Services are special since these may operate on several aggregates. If a service only operates on a single aggregate, then it should be put in the same package as the root entity. Otherwise they may be put in a separate package.
The sample application does seem to have a different view of the type of logical layers in an application. It has split the system into two core layers only: the domain and the rest of the application. The application layer as described in the numbered list above is put as a sub-package called remoting within the application layer in the sample application. This does actually make the intention of the layer more clear.
What about the implementation of services, repositories, and factories ? To start with the repository implementations, they are often technology specific, and thus should be put in the infrastructure/application layer, for example in a sub-package called "persistence". Mapping classes like Hibernate UserTypes also belong to this package. Service and factory implementations are on the other hand not technology specific, and can therefor be put in the domain package along with the interface they implement. If Spring annotations are used in the code, then the domain code is actually depending on the Spring framework in order to be compiled and function correctly. However this dependency is not problematic for the separation of concerns. The domain model will most often also depend on other libraries, like Log4j, Joda Time, etc.
Ideally it would be a great advantage if we were able to test the complete domain logic, i.e. all the code within the domain base package, without having to deploy the app, use frameworks other than a testing framework, or running a database (in-memory or otherwise). The JigZaw site provides guidelines and more for these and other testing issues.