|
From: <jue...@we...> - 2003-03-25 17:18:35
|
Hi Rod, <rj> I misunderstood: I thought you meant to make the JtaTemplate static. So = I don't object quite so strongly to the use of statics as you've done. However, I think there are still strong arguments against statics. We do need a new general exception as you suggest, and we need to break down = the heuristic exceptions as suggested in my TODOs in the checked in code. </rj> Ehm, I've indeed tried to solely create a static JtaServices helper = class at first. After your comments, I've reworked it into a JtaTemplate = object that uses JtaServices helper methods. <rj> I'm not a fan of static methods other than bootstrap methods, partly = because they're hard to test. My views have probably hardened on this since I = wrote the DataSourceUtils, although I think there are arguments for using = statics for such trivial things. </rj> The question is: Is JndiServices a trivial thing (static helper class), = or should it be turned into JndiTemplate (true object)? Note that = DataSourceUtils uses JndiServices... Should a static helper class need = to create a true object, within Spring? And if we turn JndiServices into = a true object, we would need to apply the same to JtaServices (that just = contains simple access methods used by JtaTemplate), for the sake of = consistency. So let's decide: static helper classes or true objects? - JndiServices (eventually renamed to JndiTemplate); - DataSourceUtils (using JndiServices); - JtaServices (using JndiServices). Note that JtaTemplate will be a true object anyway. <rj> I think that the ability to perform true unit testing in this way is = very important. Too often J2EE code is not properly unit tested, because = things can only be tested indirectly instead of testing just the behaviour of = each class in isolation. Otherwise we might have to get into having a whole = mock JNDI/JTA infrastructure, which could get very messy. The thing that = finally convinced me that EJB is not the way forward is that both infrastructure code and app code written using it is very hard to test: I'm really keen = to move away from this. </rj> Agreed, we need to regard testability. Regarding JNDI, this is easy, see = MockInitialContextFactoryBuilder. It isn't necessary to make = JndiServices a true object to achieve this. I guess this is also an issue of convenience: Static helper classes are = very handy to use. JNDI lookups aren't hard with plain JNDI (OK, = InitialContexts should be closed in a finally block, but this isn't = absolutely necessary, in contrast to JDBC), so IMHO a utility class must = provide noticeable simplification beyond it. Regarding JTA, the tradeoff is different. I agree that there are very = valid reasons for making JtaTemplate a true object. I consider the = lower-level access/exception conversion stuff in JtaServices rather a = candidate for a static helper class, nevertheless. <rj> In this case I think the more general solution isn't really more = complex. For example, we could have a TransactionTemplate with a JtaTemplate = subclass that set its PlatformTransactionManager property to use JTA. Also a TransactionInterceptor that had a JtaTransactionInterceptor subclass = that did likewise. (...) Does the PlatformTransactionManager API itself seem logical? If it = doesn't constrain us, I think it does add value. I don't think efficiency is a = major concern, as the cost of managing a transaction is far greater than that = of calling through an interface or creating an object. (...) OK. If we stick with PlatformTransactionManager it should probably move = to com.interface21.transaction, along with the exceptions. </rj> OK, let's move PlatformTransactionManager to com.interface21.transaction = and try to stick with it. One concern that I see for JtaTemplate is that = it uses JTA status information in its execute method, for flexible = transaction propagation (commit and rollback handling). With = PlatformTransactionManager, we could solve this with some additional = status method (maybe just a flag). Of course, TransactionInterceptor = should work the same way. I'll try to rework JtaTemplate into a = TransactionTemplate accordingly, some time this week. Regards, Juergen |