Skip to content
CMO & CTO
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

  • Digital Experience
    • Experience Strategy
    • Experience-Driven Commerce
    • Multi-Channel Experience
    • Personalization & Targeting
    • SEO & Performance
    • User Journey & Behavior
  • Marketing Technologies
    • Analytics & Measurement
    • Content Management Systems
    • Customer Data Platforms
    • Digital Asset Management
    • Marketing Automation
    • MarTech Stack & Strategy
    • Technology Buying & ROI
  • Software Engineering
    • Software Engineering
    • Software Architecture
    • General Software
    • Development Practices
    • Productivity & Workflow
    • Code
    • Engineering Management
    • Business of Software
    • Code
    • Digital Transformation
    • Systems Thinking
    • Technical Implementation
  • About
CMO & CTO

Closing the Bridge Between Marketing and Technology, By Luis Fernandez

What J2EE Gets Right and Wrong

Posted on July 11, 2006October 17, 2025 By Luis Fernandez
\n\n\n\n\n

The night the EAR would not die

\n\n\n\n

I was in a glassy meeting room, staring at a console that had too much gray. The app server was chewing on an EAR file like it had all the time in the world. Build with Ant, pack the EAR, deploy to WebLogic, watch logs. Coffee in one hand, grep in the other. The sales demo was in the morning and the page that should list customers was timing out after login.

\n\n\n\n

We fixed it, but not because the stack made it easy. We fixed it because the team knew where the wires were. We knew which EJB had a chatty finder, which JSP was doing work it should not, and which datasource had a pool set to five for a load that wanted fifty. That night taught me what J2EE gets right and what it gets painfully wrong.

\n\n\n\n

What J2EE gets right

\n\n\n\n

J2EE gives you contracts that matter. Servlets and filters are solid. JDBC is boring in the best way. JMS is a clean pipe. JTA lets you wrap a unit of work so your database and your queue keep the same story. JAAS security is predictable. JNDI makes resources findable. When you move from WebSphere to WebLogic to JBoss to GlassFish, these pieces feel familiar. That is not marketing, that is years of field work poured into specs.

\n\n\n\n

App servers give you the heavy lifting that many teams forget to count. Connection pools, threading, transactions, clustering, session replication, monitoring hooks with JMX. You can scale read traffic by adding nodes. You can set timeouts for a hung call. You can ship a WAR today and add a queue tomorrow without switching platforms.

\n\n\n\n

The best part is portability of skills. A servlet is a servlet. A filter is a filter. Your logging story works with Log4j or JUL. That means hiring is easier, onboarding is faster, and you can swap vendors without rewriting everything. That promise is real, as long as you use the parts that honor it.

\n\n\n\n

Where J2EE trips you

\n\n\n\n

Then there is EJB 2.x. Remote vs local. Home interfaces. XML for days. Container managed persistence that hides SQL so well you forget what the database wants. Finder methods that pull rows one by one. A Service Locator pattern that exists because lookup is a chore. Half the code you write is ceremony, not behavior.

\n\n\n\n

There is also XML fatigue. web.xml, ejb jar.xml, application.xml, vendor descriptors. One typo and you learn new curse words. When your stack is slow to deploy, that typo costs you minutes you do not have. You stall, you alt tab to mail, you lose flow. That hurts teams more than any algorithmic issue.

\n\n\n\n

Every server has quirks. Classloader rules change enough to keep you humble. A JNDI name that works on JBoss might not on WebSphere without extra sauce. Message driven beans behave slightly differently on timeouts. People say write once run anywhere. You can do that, but you need discipline and tests.

\n\n\n\n

And the big one. Feedback cycles. Waiting eight minutes to see a change kills motivation. Rails kids are shipping a feature while your EAR inflates. The browser world is buzzing with Ajax and you are still adding yet another taglib to a JSP to bind a list.

\n\n\n\n

What to use right now

\n\n\n\n

If you pick a lean slice of J2EE, you win. Servlets and filters for web. JSP or a simple MVC like Struts if you are already invested. Spring for wiring and transactions. Hibernate or plain JDBC where it fits. JMS only when you truly need async. Keep it as POJOs with small adapters to the app server world. Let the server do sessions, pools, and JTA. Let your code stay testable.

\n\n\n\n

Or jump to EJB 3 where your server supports it. Annotations and sensible defaults fix a lot of pain. Here is the difference in lookups.

\n\n\n\n
// EJB 2.x lookup\nContext ctx = new InitialContext();\nObject obj = ctx.lookup("java:comp/env/ejb/CustomerService");\nCustomerServiceHome home = (CustomerServiceHome) PortableRemoteObject.narrow(obj, CustomerServiceHome.class);\nCustomerService svc = home.create();\nCustomer c = svc.findById(42L);
\n\n\n\n
// EJB 3\nimport javax.ejb.EJB;\n\npublic class CustomerAction {\n    @EJB\n    private CustomerService svc;\n\n    public Customer show(Long id) {\n        return svc.findById(id);\n    }\n}
\n\n\n\n

Or skip EJB for a service with Spring and JTA. It is simple and plays nice with tests.

\n\n\n\n
// Spring XML, JTA transactions on service layer\n<bean id="txManager" class="org.springframework.transaction.jta.JtaTransactionManager"/>\n\n<tx:advice id="txAdvice" transaction-manager="txManager">\n  <tx:attributes>\n    <tx:method name="get*" read-only="true"/>\n    <tx:method name="find*" read-only="true"/>\n    <tx:method name="*"/>\n  </tx:attributes>\n</tx:advice>\n\n<aop:config>\n  <aop:pointcut id="serviceOps" expression="execution(* com.acme.service..*(..))"/>\n  <aop:advisor advice-ref="txAdvice" pointcut-ref="serviceOps"/>\n</aop:config>
\n\n\n\n

And a servlet can still be your sharpest tool. Clear, fast, and debuggable.

\n\n\n\n
public class HealthServlet extends HttpServlet {\n    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {\n        resp.setContentType("text/plain");\n        resp.getWriter().println("OK " + System.currentTimeMillis());\n    }\n}
\n\n\n\n

A short note for managers

\n\n\n\n

If your RFP has a long list of checkboxes, J2EE vendors nail those checkboxes. That does not mean your team needs every feature on day one. Time to first release beats theoretical capability. Ask the team what they can ship in thirty days. Ask how long a full redeploy takes. If the answer is more than a coffee, invest in hot deploy and test cycles.

\n\n\n\n

Pick one app server and stick to it for a project. Do not split between two unless there is a legal reason. Standardize on build and deployment. Ant or Maven, not both. Put continuous integration in place with a simple build that runs unit tests and a smoke deploy to a shared dev box. That finds classloader and JNDI surprises early.

\n\n\n\n

Hiring wise, look for servlet and POJO skills first. EJB 2.x experts are great for rescue work but you will move faster with people who can keep code simple. Budget for monitoring. JMX, log aggregation, heap snapshots. You cannot manage what you cannot see. And do not forget training. One day spent on JTA and transaction scope saves a month of data bugs later.

\n\n\n\n

On the money side, J2EE can be cost friendly if you ride open source with JBoss or GlassFish, or if you already own WebSphere or WebLogic. The bigger cost is usually complexity tax. Trim stack size, trim features, trim XML, and you will see gains in throughput and morale at the same time.

\n\n\n\n

Your next move

\n\n\n\n

Here is a challenge. This week, pick one vertical slice of your app. A list page with search and a detail view is perfect. Build it two ways.

\n\n\n\n

Option one. Use your current path. If that is EJB 2.x with local session beans behind a DAO and Struts on top, do that. Measure build time, deploy time, requests per second on a simple load, and how long it takes to write a test that hits the service layer without a container.

\n\n\n\n

Option two. Use POJO services wired with Spring, JTA, and either JDBC or Hibernate. Same feature. Same data. Measure the same numbers. If your server supports EJB 3, try a third variant with annotations. No debates. Just numbers.

\n\n\n\n

Then share the results with your team. Keep the parts that sped you up. Drop the parts that made you wait. J2EE gives you a big toolbox. The trick is to pick the pieces that give you clarity, speed, and safety without turning your day into a redeploy marathon.

\n\n\n\n

Keywords for the search folks: J2EE best practices, EJB 3, Spring vs EJB, JTA transactions, JMS, JNDI, WebSphere, WebLogic, JBoss, GlassFish, servlet, JSP, Hibernate, Maven, Ant, JUnit, Ajax, REST, SOAP.

\n
General Software Software Engineering

Post navigation

Previous post
Next post
  • Digital Experience (94)
    • Experience Strategy (19)
    • Experience-Driven Commerce (5)
    • Multi-Channel Experience (9)
    • Personalization & Targeting (21)
    • SEO & Performance (10)
  • Marketing Technologies (92)
    • Analytics & Measurement (14)
    • Content Management Systems (45)
    • Customer Data Platforms (4)
    • Digital Asset Management (8)
    • Marketing Automation (6)
    • MarTech Stack & Strategy (10)
    • Technology Buying & ROI (3)
  • Software Engineering (310)
    • Business of Software (20)
    • Code (30)
    • Development Practices (52)
    • Digital Transformation (21)
    • Engineering Management (25)
    • General Software (82)
    • Productivity & Workflow (30)
    • Software Architecture (85)
    • Technical Implementation (23)
  • 2025 (12)
  • 2024 (8)
  • 2023 (18)
  • 2022 (13)
  • 2021 (3)
  • 2020 (8)
  • 2019 (8)
  • 2018 (23)
  • 2017 (17)
  • 2016 (40)
  • 2015 (37)
  • 2014 (25)
  • 2013 (28)
  • 2012 (24)
  • 2011 (30)
  • 2010 (42)
  • 2009 (25)
  • 2008 (13)
  • 2007 (33)
  • 2006 (26)

Ab Testing Adobe Adobe Analytics Adobe Target AEM agile-methodologies Analytics architecture-patterns CDP CMS coding-practices content-marketing Content Supply Chain Conversion Optimization Core Web Vitals customer-education Customer Data Platform Customer Experience Customer Journey DAM Data Layer Data Unification documentation DXP Individualization java Martech metrics mobile-development Mobile First Multichannel Omnichannel Personalization product-strategy project-management Responsive Design Search Engine Optimization Segmentation seo spring Targeting Tracking user-experience User Journey web-development

©2025 CMO & CTO | WordPress Theme by SuperbThemes