Accessing A Remote EJB With Spring

Hopefully our systems, more often than not, follow Martin Fowler’s First Law of Distributed Object Design: Don’t distribute your objects. But unfortunately, this is not always the case. Often we have to access remote EJBs, for instance, maybe:

  • You are working with a “legacy system” (you know, real old, like from 2000-2003)
  • Your PHB said that you had to use EJB’s because he had a bunch of Websphere or WebLogic licenses “lying around”
  • Or maybe there is actually a good reason (there are some)!

Regardless of the reason, the beautiful thing is that Spring makes it extremely easy to integrate with EJBs. Even better, if you want, you can treat the EJB just as any other configured Spring bean and use that bean interchangeably with any locally configured POJO that implements the same basic interface.

So, for example, if the PHB contracted a team to write a remote EJB implementation of our WidgetDAO interface, we can use it without changing any of our code (we just have to rewire up our configuration to talk to the remote EJB).

So, previously, where we defined our WidgetDAO like this:

  <!-- WIDGET DAO -->
  <bean id="widgetDAO"
        class="com.zabada.springbook.base.WidgetDAOMapImpl"/>

we now have to wire up our remote DAO in two steps. First, wire up the remote JNDI connection like this:

  <!-- REMOTE JNDI CONNECTION -->
  <bean id="remoteWidgetDAOJndi"
        class="org.springframework.jndi.JndiTemplate">
    <property name="environment">
      <props>
        <prop key="java.naming.factory.initial">
          org.openejb.client.JNDIContext
        </prop>
        <prop key="java.naming.provider.url">127.0.0.1:4201</prop>
        <prop key="java.naming.security.principal">Admin</prop>
        <prop key="java.naming.security.credentials">pass</prop>
      </props>
    </property>
  </bean>

and then replace our original widgetDAO bean with the remote EJB config:

<!-- REMOTE WIDGET DAO -->
<bean id="widgetDAO" lazy-init="true"
      class=
       "org.springframework.
        ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
  <property name="jndiName">
    <value>/RemoteWidgetDAO</value>
  </property>
  <property name="businessInterface">
    <value>com.zabada.springbook.base.WidgetDAO</value>
  </property>
  <property name="jndiTemplate">
    <ref bean="remoteWidgetDAOJndi"/>
  </property>
</bean>

That’s it! Spring even deals with remote exceptions, re-throwing them as non-checked RemoteAccessExceptions, which is a subclass of RuntimeException. As a result, the rest of your code can stay the same, and you, the developer, can decide how you are going to handle those potential exceptions.

The attached zip contains a fully working, scaled down OpenEJB distribution set up with a pre-deployed remote WidgetDAO. You can startup the EJB server, and then see the simple JSP, PDF, Excel and RSS examples from previous sections working, but the backend calls are being handled remotely by OpenEJB (make sure to change the Spring root context to: applicationContext-ejb.xml in web.xml)!

Sample EJB server: Download OpenEjb-WidgetDAO.zip

Further Reading

Next: Scheduling Jobs with Spring and Quartz