EJB 1.1 affects use of BusinessInterface pattern?


EJB design: EJB 1.1 affects use of BusinessInterface pattern?

  1. EJB 1.1 affects use of BusinessInterface pattern? (7 messages)

    I've been reading up on the differences between EJB 1.0 and 1.1, and I've noticed something in the 1.1 spec that seems to affect the use of the BusinessInterface pattern.
    As a reminder, this pattern involves defining an interface that declares the business methods of an EJB, separate from the remote interface. Then the remote interface extends this business interface _and_ the bean implementation class implements it. One side effect of applying this pattern is that all of the business methods must be declared as throwing RemoteException, since these are the method declarations that the remote interface will use. In EJB 1.0 this is no problem because it was OK for the implementing bean class to declare "throws RemoteException".

    Now in section 12.3.7 of the EJB 1.1 specification, I read the following:
    "The EJB 1.0 specification allowed the business methods, ejbCreate, ejbPostCreate, ejbFind, ejbRemove, and the container-invoked callbacks (i.e. the methods defined in
    the EntityBean, SessionBean, and SessionSynchronization interfaces) implemented in the enterprise bean class to use the java.rmi.RemoteException to report non-application excep-tions to the Container.
    This use of the java.rmi.RemoteException is deprecated in EJB 1.1 — enterprise beans written for the EJB 1.1 specification should use the javax.ejb.EJBException instead.
    The EJB 1.1 specification requires that a Container support the deprecated use of the java.rmi.RemoteException. The Container should treat the java.rmi.RemoteException
    thrown by an enterprise bean method in the same way as it is specified for the javax.ejb.EJBException.
    Note: The use of the java.rmi.RemoteException is deprecated only in the above-mentioned
    methods. The methods of the remote and home interface still must use the java.rmi.RemoteException as required by the EJB specification."

    This seems to be saying that the bean implementation class should not declare that it throws RemoteException, even if it does not actually throw them. If so, the BusinessInterface pattern is no longer legal since the methods in the Business interface must declare RemoteException in order to be used by the remote interface.

    What are the experts' thoughts on this issue?
  2. The Business Interface pattern is also discussed in the Patterns repository.
  3. Good catch! My first impression is that you're absolutely
    right...It would still be OK if EJBException was a subclass
    of RemoteException, but it isn't...

  4. I thought about it some more, and here is why it doesn't work anymore in more detail:

    Leaving off the throws RemoteException in the implementation is OK, even though the BusinessInterface specifies it. However, adding the throws EJBException, which
    is NOT specified in the BusinessInterface is NOT OK....

  5. The BusinessInterface pattern still holds.

    As you mentioned, just because RemoteException is specified in the interface, the implementing class need not declare it. This solves the first problem.

    The second problem is solved because EJBException extends RuntimeException, so it is not necessary to declare it in the implementation's throws clause.

    There is a good discussion of the BusinessInterface in Richard Monson-Haefel's EJB book (2nd ed), which covers EJB1.1.

    Of course this discussion should be linked to the wiki page.

    Jeff Schnitzer
  6. You are correct. I just looked it up.
    The strange part is that I have to different versions
    of the javax.ejb javadoc and both state that EJBException
    extends Exception, not RuntimeException.... The spec
    agrees with you and I'll assume it's correct :-)


  7. You must have been looking at the EJB 1.0 Javadocs. I was seeing the same thing until I went to the Java web site and browsed the 1.1 Javadoc for EJBException. Apparently they moved EJBException down in the hierarchy for EJB 1.1 - it now subclasses RuntimeException as the spec indicates.

    Oh well...much ado about nothing. ;)
  8. We are solving this problem by basically adding an additional layer of indirection. We defined our business interfaces separately making sure that all of our methods threw Exception (or in our case, our own custom exception called CoreException). For each of our business interfaces, we also specified factory interfaces for creating these objects. The factory implentation calls the home to create the EJB and wraps the EJB inside a proxy object that implements the business interface. Any RemoteException thrown (or any exception for that matter) is wrapped inside our CoreException which is then thrown.

    One advantage of this approach is that the implementation is fully encapsulated because all user refer to the business interfaces only. Implementation can easily be changed since the factories and proxies hide the EJB details.