EJB 3 beans can be configured with annotations in Java Code, Deployment Descriptors in ejb-jar.xml and a mix of both of them. An interesting post tries to answer the question for which case what option should be used. In my Java EE 5 projects, however, I went another path and thought about probability of change and worse case scenarios. If something is not likely to be changed, I put it into an annotation. Rather instable configuration was extracted into ejb-jar.xml. Some examples:
- JPA-DataSource - no problem here, it is already configured in persistence.xml - this is a good idea.
- Injection of EntityManager with @PersistenceContext: in bigger project it is a good idea to specify the unitName explicitly, because it is likely to have more than one persistence-units. Otherwise the introduction of an additional EntityManager would break the code. It isn't a huge problem, but can cost some hours. I wouldn't resolve the unitNames in ejb-jar.xml in addition - the names are stable enough.
- Dependency Injection between Beans: in 99% of all cases I'm relying on annotations and conventions - except the DI is used as a "configurable factory", where different implementations of the same interface has to be injected. This is not the common case.
- Transaction: it is a good idea to configure them with code - this documents the principle in code - there should be no surprises.
- Security roles: even security roles were in my projects either not existent (because the EJB 3 security model wasn't flexible enough), or statically configured in security. The roles were stable, but the association between the roles and the users varies in general.
- Interceptors: I configured them mostly with annotations, except for interceptors which were only relevant for the development cycle, like debugging or tracing. It is better to document the interceptors with annotations, rather than with JavaDoc :-).
- Injection of JMS, JDBC resources etc: this depends on the operations. If the application server is in your control, I would even use mappedNames / JNDI-names in code - there is actually no reason to introduce another level of indirection. In case your application is deployed by operations (another department), XML-configuration is better idea. The biggest problem here: collision of JNDI-names on multi-project servers.
- General configuration with primitive values: it doesn't makes sense to hardcode them. If you need to configure some primitive attributes - use ejb-jar.xml. I didn't used this feature, and used mostly the database for configuration purposes.
In vast majority we relied on annotations - which saved us a lot of time. We used XML-configuration only in few projects for configurable monitoring and additional "nice to have" services. It worked really well - most of the applications are already in production, there were no problems so far. But it really dependends on your projects / situation. In EJB 3 you have all options, from very lean and pragmatic, to flexible but more work intensive. The most important questions are:
- What happens, in case you hardcoded your decisions and it will change in worst case?
- Is it worth to protect a certain variation externalizing it into XML?
- How likely are changes in certain areas? What's your experience in the last projects?
NEW 2016: Java EE 7 Workshops: Bootstrap, Effective, Architectures, April, 4th-6th, Munich's Airport
On demand workshops: Java EE 7 Bootstrap, Effective Java EE 7 and NEW: Java EE 7 Testing are available for streaming