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?