Announcement Announcement Module
Collapse
No announcement yet.
test existing EJB Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • test existing EJB

    I want to unit test some existing EJBs, but I want to do it without launching a full J2EE app server. At first glance, it looks like Spring is a handy way to do that. But now that I've read over the documentation more carefully and looked through this forum, it appears that Spring does not have an easy way of "wrapping" or "deploying" an existing EJB. It looks like I must first re-work the EJB itself to make it a subclass of a Spring class (e.g. AbstractStatelessSessionBean). Is that correct? If so, are there any general recommendations for testing existing EJBs?

    Thanks,

    Lee

  • #2
    Even converting your application to use the Spring EJB classes won't allow you to test your EJB. Only your business object inside of it. Of course that is the most important part. But I've had my business object work properly and the little logic I had in my EJB fail.

    In any case, what you need is an EJB testing framework. Like MockEJB

    Comment


    • #3
      Sorry, but I don't see why we need MockEJB. Seems to me that what Lee is asking for is one of the essential promises of Spring:

      From Chapter 18 of the "Spring Java/J2EE Application Framework Reference Document" I downloaded from springframework.org:

      "As a lightweight container, Spring is often considered an EJB replacement. We do believe that for many if not
      most applications and use cases, Spring as a container, combined with its rich supporting functionality in the
      area of transactions, ORM and JDBC access, is a better choice than implementing equivalent functionality via
      an EJB container and EJBs.
      However, it is important to note that using Spring does not prevent you from using EJBs. In fact, Spring makes
      it much easier to access EJBs and implement EJBs and functionality within them. Additionally, using Spring to
      access services provided by EJBs allows the implementation of those services to later transparently be switched
      between local EJB, remote EJB, or POJO (plain java object) variants, without the client code client code having
      to be changed."

      I am new to Spring, but not to EJB. What are we missing here?

      Ben

      Comment


      • #4
        Hi Ben.

        The Spring container (or more formally BeanFactory) is not an EJB container.

        What the quoted paragraph is saying is that utilising the Spring container will allow you to access your EJBs in a convenient way. This is not implying you can use EJBs without an EJB container. As it states:
        However, it is important to note that using Spring does not prevent you from using EJBs. In fact, Spring makes
        it much easier to access EJBs and implement EJBs and functionality within them.
        So for example; Spring would recommend you expose the functionality of an EJB within an interface. Objects which require that functionality accept the interface, *not* the EJB, which is just one possible implementation. This means that instead of wiring up the Object with an EJB implementation of the interface; you could wire it up with another implementation, and the Object won't care.

        I would also suggest (as I expect, would the Spring team) that you do *not* put business logic within EJBs, rather you refactor the business logic into it's own Class and have the EJB (if you still need them) simply reference the class. This allows you to unit test your logic in a unit test because your logic is container within a POJO.

        One of the core concepts of Spring is that you describe functionality with interfaces, and then use those interfaces, not the implementations within dependant classes.

        The other point in the quoted text is that of Container provider services. The Spring framework does provide (either native, or integration with 3rd parties) the same services that the EJB container gives you, only without the heavyweight EJB container.

        This was a bit of an hairy fairy answer; and for that I apologise, but there is much to say . Have you read the reference manual? You might find it answers your questions much better than I http://www.springframework.org/docs/reference/ and http://www.springframework.org/docs/reference/ejb.html

        Comment


        • #5
          No apology necessary. Thanks for the reply.

          In answer to your question, yes, I have read through the manual. That's where the quote came from (Ch 18 instead of 17 - later version?).

          To new people coming into Spring (or to me, at least), the quote (near the bottom) is clearly implying that you don't need to run in a container, and apparently, if you are using EJB 3 entity beans (but not session or message, hmmm...), that is exactly what you can do. From the book "POJOs In Action" page 361:

          "What's more, EJB 3 entity beans can be run outside the container, which makes testing much easier."

          From my study of Hibernate, Sping, POJOs, etc. I think that, high-level, that is where the java development world wants to go now...outside the container, at least for debugging.

          I mean, the bottom line is that most application developers have deadlines and just want tools that help them get their functionality written, debugged, deployed and maintained in production, faster and with fewer errors. This was the essential promise of EJB 1.0...and then EJB 2.0...and now Spring, Hibernate, Struts, AppFuse, and on and on.

          If a tool (like, say EJB 1.x and 2.x) causes more problems than it solves (solving one problem, but creating three more elsewhere), then app developers start looking for better tools, and, pretty soon, by the natural law of supply and demand, the tool developers write them.

          In the case of EJB, one of the big problems has been the "annoyingly long edit-compile-debug cycles" ("POJOs In Action" p 10).

          If calls to EJB services can (again, from the Spring reference doc) "transparently be switched
          between local EJB, remote EJB, or POJO (plain java object) variants, without the client code client code having
          to be changed."...

          ...and you put that together with the current desire to code/debug outside the container, well, that pretty much implies that Spring enables us to modify code and debug it outside the container, doesn't it?

          I mean, what would be the point of it implying that we can quickly re-build (re-compile) such "switched" code without being able to quickly debug it as well?

          For me personally, I don't have time to wait for EJB 3.0 to fulfill its promise, as I'm on a fairly short deadline in J2EE 1.4 (EJB 2.x). This is why I'm currently evaluating Spring. I need POJOs that I can quickly code/debug outside the container, but which I can also fairly quickly/easily transform into full-blown "heavy-weight" EJBs, once the development iterations settle down and we near production deployment. I can't take the chance that Spring will somehow subtlely lock me to a framework from which I can't make the "switch" without a significant re-write.

          So, my general question for the group is:

          Does Spring fulfill that implied promise or not?

          Ben

          Comment


          • #6
            There are two points I would like to make:

            Spring facilitates the "switching" by advocating class depend on interfaces, not implementations, so choosing an implementation (EJB, POJO etc.) is a matter of configuration:

            Code:
              interface MyService {
              void doSomething();
              }
            
              public final class YourClass {
                private final Service service;
                public YourClass(final MyService theService) {
                  this.service = theService;
                }
              }
            Thus; you can provide any implementation of MyService to YourClass and so long as the implementation fulfills the contract specified by MyService; you are fine. This is nothing *specific* to Spring, it is just good practice.

            To demonstrate, the Spring BeanFactory would look like:

            Code:
            <bean id="yourClass" class="YourClass">
              <constructor-arg ref="myService"/>
            </bean>
            
            <!-- I don't use EJBs, so this may not be the right factoryBean -->
            <bean id="myService" class="org.springframework.ejb.access.SimpleRemoteStatelessSessionProxyFactoryBean">
              <property name="jndiName" value="EJBJndiName"/>
            </bean>
            if you decided to not use EJBs (which is another discussion in itself ) and used a POJO for the service:

            Code:
            <bean id="yourClass" class="YourClass">
              <constructor-arg ref="myService"/>
            </bean>
            
            <bean id="myService" class="YourPOJOService"/>
            This allows you to unit test your domain objects (YourClass) in isolation because you can provide stubs or mock objects for the collaborators (MyService).

            Spring also provides a large number of services that a J2EE container providers; transaction management; pooling etc. although of course; it does a lot more.

            OK; I have to ask Why are you using EJBs in the first place? Do you need the remoting functionality?

            But yes; even if you are using EJBs; there are a large number of reasons why Spring would still be a "good thing".

            I feel bad because I am hugely underselling Spring, but without writing a whole bookshelf of books....

            Does that clarify things?

            Comment


            • #7
              A bit, yes, thanks, but it doesn't really answer the essential question, does it?

              Use or non-use of EJB is out of my control. I can often influence the decision from higher-ups, but once it is made, I have to abide by it. I'm pretty sure most J2EE designer/developers are in the same boat these days. Sometimes we're stuck with "legacy" EJBs (gee, legacy already?:-)) and just need a way to refactor them a bit so that they can be debugged outside the container (for reasons already mentioned).

              This article below appears to me to be also saying that one can easily write/debug EJBs outside of the container:

              http://dev2dev.bea.com/pub/a/2005/12...jb.html?page=1

              ...but I just read over it yesterday briefly and I haven't yet had time or high-level confidence in Spring to try and implement what he's saying. Is he saying what I'm thinking he's saying? i.e. that we CAN write/debug EJB in OR OUT of the container, with only relatively minor config changes?

              Please understand that I'm only asking to be able to EFFECTIVELY (i.e. in effect) write/debug EJBs outside the container. From my readings, it sounds to me like that is one of the promises of "dependency injection". All I need is a reasonable and intuitive way of doing this. It doesn't have to be perfect or seamless. It just has to be significantly better than the "old way", the in-container way mentioned before in this thread. (Yes, I already know about in-container hot-swapping. It comes with its own set of issues.)

              So, this is still my high-level question, perhaps for someone on the Spring team now:

              If calls to EJB services can (again, from the Spring reference doc) "transparently be switched between local EJB, remote EJB, or POJO (plain java object) variants, without the client code client code having to be changed."...

              ...and you put that together with the current desire to code/debug outside the container, does Spring enable us to modify EJB code and debug it outside the container or not?

              I want to understand what Spring can and cannot do for me high-level, before I make a significant investment of my time...and book money :-)

              Ben

              Comment


              • #8
                As far as I can tell Spring does not allow you to Debug a 2.x version EJB outside of the container.

                Because of the way its suggested EJBs can be implemented (and called by the client), the business object (a POJO) that an EJB encapsulates can easily be debugged. But this is more due to dependency injection and decoupling than Spring. Spring allows you to take decoupled, dependency injection style components and wire them together. Spring is the glue. A decoupled architecture (which Spring encourages) is really what enables you to debug your business code outside of a container.

                However, I have seen at least one case where getting the business to work wasn't enough. Once I wired my EJB (using a Spring base class) with my business object and deployed it inside a container, I had some infrastructure issues. Apparently my understanding of EJB exception handling was inadaquate. That is when I decided that in those cases, it helps to use a testing framework like MockEJB to be able to test my EJB infrastructure. Not everyone will need to do this. If you business code is tested, and the EJB wrapper works, testing it may not be worth it.

                Spring rarely stands alone. There is always some component it doesn't supply 100% that some J2EE application use. Whether it be ORM, object pooling, connection pooling, non-POJO testing (i.e. database or other infrastructure intergration tests).

                The bottom line is I believe Spring is right for you. By itself it can help you make your client code EJB agnostic, your server code allow you to choose between remote EJB, local EJB and POJO (as well as others) out of the box. You can create integration and unit tests for your business code. But if you need to actually test the EJB part of the EJB (meaning not the business code) Spring doesn't cover that.

                Comment


                • #9
                  Originally posted by benethridge
                  If calls to EJB services can (again, from the Spring reference doc) "transparently be switched between local EJB, remote EJB, or POJO (plain java object) variants, without the client code client code having to be changed."...
                  My previous post explains this, and shows how Spring achieves this. The Spring BeanFactory is reponsible for wiring up a graph of beans. Whether those beans are POJOs, EJBs, RPC facades etc; is in the configuration. Swapping one implementation for another *is* trivial. Accessing any one of those implementations outside of it's native environment (EJB container for EJB, HttpServlet for Servlets etc.) is not part of Springs remit. Having said that, Spring does provide a number of mock implementations (Check out org.springframework.mock.* packages: http://www.springframework.org/docs/api/index.html).

                  ...and you put that together with the current desire to code/debug outside the container, does Spring enable us to modify EJB code and debug it outside the container or not?
                  The use of EJBs inside/outside the container is nothing to do with Spring; it is to do with the EJB spec. As I understand, part of the EJB 3.0 spec is addressing this issue.

                  Spring makes it easy to access EJBs *from* an EJB container, but Spring itself *isn't* an EJB container.

                  HTH.

                  Comment


                  • #10
                    Thanks, Bill and HTH.

                    It is only fair that if I want to "test the EJB part of the EJB" as you say, that I would need to be testing in-container.

                    Between your two answers, I think this adequately answers my essential question (and perhaps Lee's as well?), and I agree that it sounds like Spring will get me where I need to go.

                    Now, on to the bookstore

                    Thanks again for taking the time to answer these questions.

                    Ben

                    Comment


                    • #11
                      Originally posted by benethridge
                      Thanks, Bill and HTH.
                      Actually HTH means "Happy To Help", that wasn't his signature And I was happy to help as well.

                      It is only fair that if I want to "test the EJB part of the EJB" as you say, that I would need to be testing in-container.
                      Actually EJB testing can also be done with MockEJB in case you want to write integration tests for that part of your system without having to deploy it to an EJB container.

                      Good luck. And we'll be here for more questions

                      Comment


                      • #12
                        Originally posted by benethridge
                        It is only fair that if I want to "test the EJB part of the EJB" as you say, that I would need to be testing in-container.
                        Indeed. Cactus and MockEJB are (of the top of my head) two solutions to this...

                        Between your two answers, I think this adequately answers my essential question (and perhaps Lee's as well?), and I agree that it sounds like Spring will get me where I need to go.
                        Glad to hear it

                        HTH means "Hope This Helps"; my signature is yatesco, my name is Colin

                        Comment


                        • #13
                          Oh. Silly me . Well, anyway thanks, Colin.

                          BTW, I just purchased "Spring In Action". A cursory look through section 6.5 looks very promising for EJB usage with Spring.

                          Ben

                          Comment

                          Working...
                          X