This post is about the funniest presentation I heard at JavaOne 2013. It was Adam Bien's "Lean and Opinionated Java EE Applications" which started after some nice reggae music in the room. :) The audience really enjoyed this presentation (i.e lot of laughing), I was surprised to see something like this at a technical session. The demonstration was backed by a Maven project with some minimal code samples shown in NetBeans.
You can find the session's site here and the slides here, but there were only a few introduction slides, as the substance was in the speech given. I think that the code and project layout samples are not that important as they were only used to prove some points of the presentation. Some unorthodox opinions about Java EE were shared by Adam Bien, but they are really worth considering.
Below you can find a summary of the ones I liked most, and some quotes with the funniest lines. Please note that most of it is really only quotes from him which I wanted to share as I couldn't find them all in one piece on his blog which I really recommend to anyone in Java EE. Enjoy.
"The most important pattern is: don't distribute." This means that in real-world projects a lot of times the application is overly modularized into different projects and deployments, and probably distributed to different JVMs, whereas it could be kept in one JVM or even one WAR deployment. Since 2008 (Java EE 6), no EARs are strictly needed as you can package a lot of things into plain WARs. So when are EARs neeed? Only when WAR is not enough for yoe, e.g. for more classloading flexibility and packaging JCA connectors.
"Everything is monolithic until it's too big." If it gets too big, then you can modularize and the different WARs can communicate by REST. ("SOAP is the technology of 1945" and "remote EJBs are dead".) "You shouldn't like distributed transactions" because XA is problematic; provide compensation instead. Seeing how often and how well distributed transactions are designed or implemented on real-world projects, even something like this sounds reasonable...
Business and web components do have a many-to-many relation.
If you can achieve a one-to-one relation between business requirements and code, that's just great.
How to Start?
Always use a minimal starting pom, without any super pom. Keep it as minimal and as clean as possible. "treat pom.xml as Java code." Always specify the build/finalName element in pom.xml as it is defining the filename of your deployment unit.
About EE 6 and EE 7: "frameworks are counter-productive", start with implementation of the business logic."Look at JDK first, then EE6, amazing what's there." True again. Amazing how a lot of technical features can be reinvented or reimplemented or taken from external dependencies. All unnecessary a lot of times. External dependencies are forbidden, each one has to be justified, and relied on using your own build, because they may brake or dissapear any time.
A smaller WAR means faster deployment which means productivity gain. How much of your time do you spend just sitting at your desktop and waiting for deployments? (See also JRebel...)
"Meetings are forbidden", minimize meetings, concentrate on business logic.
A vision is always needed (see RUP), because we need to know why we are building the system. We also need to know the key entities and core concepts of the business (so that the components can be identified).
On the other hand, business needs to understand components and focus on business, not on technology. "There are exceptions, beans, DTOs etc. - Who cares?" True again. You will end up running in circles with the business if you cannot talk about the business and business only.
About Layers and Integration
REST: nothing is more portable, you will end up using it anyway with responsive design, iOS, Android etc. It's a good practice to introduce additional resource classes on top of you business logic, even it seems overkill at first, even for small projects. This way no JAX-RS or JAX-WS or other stuff pollutes your business EJBs.
Java client accessing the backend: message border reader/writer. Fastest serialization protocol mentioned: Kryo.
The control layer is empty in 80%. If you get too complex classes then divide and conquer, and the control layer appears. But not before!
About Packages, Classes, and Interfaces
Example package naming: "com.x.business.sessions.boundary", where "business" is to separate business concepts, "sessions" can be the name of a component, and "boundary" is the name of the pattern.
Package names like commons, domain, framework, infrastructure, base, util are forbidden as they have no meaning. In particular, "util is dangerous". You always end up having different non-related concepts in a "util" package.
"If you cannot name the class [implementing an interface] properly, interfaces are forbidden." This refers to an interface MyService, and non-descriptive class names like MyServiceImpl and so on. They really don't make any sense.
In the enterprise, type-safe interfaces are good. But on the web scale, nothing is type-safe.
You shouldn't have base classes at the EJB/CDI level, only at the entity level.
About Data Access and Transfer Objects (DAO, DTO)
Domain store pattern: why use it? the EntityManager is the same and it's already there. Just inject the EntityManager into the boundary. Factor out duplicate queries, handle SQL as Java, as there is no difference. There is usually no need for a separate DAO, it doesn't mean anything, you can call this control something else instead, if it's needed at all.
DTOs are forbidden as we already have one layer (e.g. REST). It is only allowed if it's substantially different from entities, otherwise it leads to more complexity and no encapsulation. If you are using or implementing a mapper between your entities and DTOs, you are in trouble. Experience shows that the mapper is never tested (i.e. builders and so).
Other Quotes, Questions and Answers
Here are a few more notes I've taken, in no specific topic or order. Some of them were Adam's answers to questions of the audience.
- "OO programming for some reason is forgotten in Java EE programming." :)
- Java only development vs. Scala + Groovy + etc. development: the latter one can be a sign of losing focus, meaning that if you need to consider other languages, you must already have a problem with your Java code. Or with Adam's words: "In enterprise development the verbosity of Java is not the problem. The problem is cargo cult and overuse of ancient design patterns. After the bloat elimination Java becomes surprisingly productive."
- Simple classes (with getters and setters) shouldn't be tested.
- Avoid bad architects, promote them to management. :D
- Experience shows that one to five developers working on one WAR is ideal. EJB and web components can go into one piece of WAR. If modularity is needed then introduce JAR projects.
- Avoid proprietary features, not only because of difficulties of migration, but they might disappear any time.
- Lombok is just too much magic for enterprise.
- Performance problems are always in the database, not in the application server, where you can just start more WARs if needed.
- CMT and remote EJBs: "the idea was scalability but it never worked".
What I got out of this presentation is a very pragmatic view of Java EE projects and development. Even if some advices might seem to go against well-established patterns or conventions, at their core they are just practical and common sense. And honestly, I think most of the things described you can experience in real-world EE projects. ;)
I would summarize the presentation in the following very simple points:
- Keep it clean and minimal.
- Focus on business.
- Use your common sense.