Announcement Announcement Module
Collapse
No announcement yet.
EJB3.0 without Spring :-) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • EJB3.0 without Spring :-)

    I was reading this article from TSS
    http://theserverside.com/news/thread...hread_id=29318

    Now that EJB is getting improvement:
    EJB 3.0 is a deep overhaul of the old EJB specification. Its goals are to simplify development, facilitate test driven development, and focus more on plain java objects (POJOs) rather than on complex APIs. The introduction of annotations into JDK 5.0 allowed the EJB 3.0 specification to completely remove dependencies on XML deployment descriptors, the biggest bane to EJB developers. This EJB 3.0 Preview Release is almost a complete implementaiton of the specification. We'll be releasing new versions about every 6 weeks until the final draft of the specification.
    Will we still need lightweight container (like Spring) in future since EJB3.0 seems to evolve to the same direction ?

    Just curious

    Thanks,

    Josť.

  • #2
    Josť,

    will you be playing golf untill 2007?

    Comment


    • #3
      In addition to the above post, Spring still provides more functionality:
      - AOP
      - IoC
      - services (such as declarative transactions) available to WAR
      - useful templates (e.g. JDBC)

      Spring is also a framework that promotes good design. See:
      http://www.springframework.org/statement.html

      Comment


      • #4
        EJB3.0 seems to promote IoC too:
        http://docs.jboss.org/ejb3/tutorial/...injection.html

        Josť.

        Comment


        • #5
          Indeed, it might superficially seem that EJB 3.0 (in particular session beans) covers the same area as Spring. However, when you look closer, you'll notice some important differences with regards to IoC capabilities.

          1. DEPENDENCY INJECTION

          EJB3 just provides dependency injection for JNDI objects. All referenced objects need to be managed by the application server in JNDI. This is just feasible for coarse-grained facades, as there is no point in letting the application server manage every single internal object of your application. Essentially, EJB3's dependency injection capabilities are limited to making JNDI lookups more convenient, but do not go beyond that.

          In contrast to the above, Spring is designed for managing fine-grained application objects in a local fashion, without making the server aware of each and every object. You can link in objects from JNDI if you need to, but most of your application objects are not managed by the server. Furthermore, Spring supports prototypes, constructor injection, factory methods, simple property values, placeholders, etc.

          The most important difference is that Spring can seamlessly manage application objects in all sorts of environments, while EJB 3 just allows you to run them in an EJB container. In a test environment or standalone environment, the best you can do with EJB 3 is to instantiate the session beans yourself. With Spring, you'll just use a different context implementation, possibly with the same XML bean definitions.

          2. OTHER CAPABILITIES

          Beyond those basic IoC capabilities, Spring offers full support for proxy-based AOP with prebuilt and custom interceptors, while EJB 3 just offers its fixed set of interceptors (transaction, security). And Spring's declarative transactions can be backed by various transaction strategies, working outside of J2EE too. There's also support for a wide variety of data access strategies (while EJB 3 just integrates a single strategy).

          We've not even touched Spring's web support yet, which range from basic web application context support to its own web MVC framework and prebuilt Struts/JSF integrations, being able to seamlessly reference middle tier beans. There's also support for lightweight remoting with various strategies, rather than just a limited set of protocols that a particular EJB server offers. Etc etc etc.

          3. SPRING IN AN EJB3 SCENARIO

          In many respects, Spring and EJB 3.0 complement each other more than they compete. Like it currently does for EJB 2.x, Spring will be able to link in EJB3 session beans seamlessly (local or remote), and also be able to provide internal contexts for EJB3 session/message-driven bean implementations (holding a Spring bean factory within an EJB).

          In such an EJB3 scenario, Spring would manage the application objects in the web tier (no matter with which web MVC framework), accessing coarse-grainded EJB facades when necessary, and potentially also fine-grained objects behind those facades (for example DAOs, using JDBC, JDO, Hibernate, etc). It still acts as glue for the entire application, just with some EJB3 session beans thrown into the mix.

          Beyond EJB3 session beans, we will also support the new persistence API defined by JSR-220 (formerly known as EJB3 entity beans), as a further O/R mapping strategy - in addition to the current support for Hibernate, JDO, OJB, and iBATIS SQL Maps. This will be completely independent from the rest of EJB3, though: You could easily manage your entire middle tier with Spring, just using JSR-220 persistence.

          4. EJB3 IN A SPRING SCENARIO

          I hope the above answers why it still adds value to use Spring in an EJB3 scenario. Of course, we can also turn the question around: What value is added by EJB3 session beans to a Spring scenario? (JSR-220 persistence is a different matter: It's an alternative to Hibernate/JDO, not to Spring.)

          In principle, Spring covers all capabilities of EJB3 session beans already, offering more flexible and more sophisticated management and deployment options. The main benefit that I see with still modelling components as EJBs is that you're able to export remote services through your J2EE server (for load balancing and failover).

          For purely local needs, I see no compelling reason to choose EJB3 session beans over Spring-managed POJOs, except for one specific scenario: You might want to deploy some of your components in a separate class loader within an EAR, making them accessible to multiple web applications. In such a case, using local EJBs as facades makes sense, possibly with fine-grained networks of Spring-managed application objects behind them.

          Juergen

          Comment


          • #6
            As Juergen points out, the Dependency Injection features of EJB 3.0 are a small subset of Spring's Dependency Injection capabilities. Some of the limitations:

            - Objects must come from JNDI to be injected
            - No ability to manage finer-grained objects than you might want to put in JNDI
            - No ability to manage "singleton" (shared instance) and "prototype" (separate instance per user) objects as in Spring
            - No support for complex types such as lists and maps
            - No support for configuration properties (Strings, ints etc.)
            - No ability to apply custom interception to managed objects
            - It's Java 5.0 only
            - DI won't work with existing classes because it needs custom annotations

            Some simple applications might get by with this limited form of DI; however, using Spring or another lightweight container will still look compelling even behind an EJB 3.0 facade--for those people who choose to use EJB. Once you embrace DI, it's a bit odd to say "this far and no farther. DI is good for objects coming from JNDI but no more."

            Furthermore, the EJB 3.0 spec is likely to be final in early 2006. There are many gaps in the Early Release Draft.

            So it's good to see the EJB spec being influenced by lightweight containers, but EJB 3.0 isn't going to remove the need for them.

            Comment


            • #7
              One has to remember EJB3 is just an API. As the spec is finallized and getting more matured, Spring itself may actually be a light-weigh implementation of the spec (with more features). I see this as great combination, simplified development model and a robust (and free) implementation (those big vendors should watch out!!!).

              Comment


              • #8
                Originally posted by Rod Johnson
                As Juergen points out, the Dependency Injection features of EJB 3.0 are a small subset of Spring's Dependency Injection capabilities. Some of the limitations:

                - Objects must come from JNDI to be injected
                - No ability to manage finer-grained objects than you might want to put in JNDI
                Which is a good thing for server applications, because you can create real singletons and avoid creating the whole object tree with every new transaction.

                - No ability to manage "singleton" (shared instance) and "prototype" (separate instance per user) objects as in Spring
                Except for the trivial application Spring doesn't do a real singleton, too. Nearly every container uses multiple classloaders which makes the use of Spring singletons very dangerous. You might end up with data messed up after a hot redeployment or somthing like that. It claims to be a singleton but it isn't in server context.

                - No support for complex types such as lists and maps
                - No support for configuration properties (Strings, ints etc.)
                - No ability to apply custom interception to managed objects
                - It's Java 5.0 only
                - DI won't work with existing classes because it needs custom annotations

                Some simple applications might get by with this limited form of DI; however, using Spring or another lightweight container will still look compelling even behind an EJB 3.0 facade--for those people who choose to use EJB. Once you embrace DI, it's a bit odd to say "this far and no farther. DI is good for objects coming from JNDI but no more."

                Furthermore, the EJB 3.0 spec is likely to be final in early 2006. There are many gaps in the Early Release Draft.

                So it's good to see the EJB spec being influenced by lightweight containers, but EJB 3.0 isn't going to remove the need for them.

                Comment


                • #9
                  Originally posted by haug
                  Originally posted by Rod Johnson
                  As Juergen points out, the Dependency Injection features of EJB 3.0 are a small subset of Spring's Dependency Injection capabilities. Some of the limitations:

                  - Objects must come from JNDI to be injected
                  - No ability to manage finer-grained objects than you might want to put in JNDI
                  Which is a good thing for server applications, because you can create real singletons and avoid creating the whole object tree with every new transaction.

                  - No ability to manage "singleton" (shared instance) and "prototype" (separate instance per user) objects as in Spring
                  Except for the trivial application Spring doesn't do a real singleton, too. Nearly every container uses multiple classloaders which makes the use of Spring singletons very dangerous. You might end up with data messed up after a hot redeployment or somthing like that. It claims to be a singleton but it isn't in server context.
                  Singleton is defined as a single instance of a certain class. One class in several classloaders is not the same class, so there is nothing wrong with Spring implemented singletons (or pure java static instance implementation singletons for that matter).

                  Anyway, for 90% of the developers in 90% of the cases it doesn't matter if singleton is one of a kind in the known universe or not. If you want you can put your contextLoader in JNDI, but how is that going to fix anything? How will it work in clusters? What are you going to do with stuff that is not serializable?

                  Also, from another thread of yours - java object lifecycle has nothing to do with db transactions. The fact that current entity bean spec tries to enforce that unholy marriage is not really a recomendation for that line of thinking. If you get lazy loading exception it's a bug. Like NullPointer or IndexOutOfBounds. It's a bug and you fix it.

                  Comment


                  • #10
                    Singleton is defined as a single instance of a certain class. One class in several classloaders is not the same class, so there is nothing wrong with Spring implemented singletons (or pure java static instance implementation singletons for that matter).
                    Inside a container you never know if you have a single instance or multible ones and that makes it so dangerous. If you have a counter of something you need to be sure you have a single instance. If you redeploy (the same class file) you might get a second counter and some sessions use the first counter and the new sessions use the new counter. You end up with wrong values, happy bug squashing.

                    Anyway, for 90% of the developers in 90% of the cases it doesn't matter if singleton is one of a kind in the known universe or not. If you want you can put your contextLoader in JNDI, but how is that going to fix anything? How will it work in clusters? What are you going to do with stuff that is not serializable?
                    Have you made some research or are the numbers just a guess? If you configure your caches you normally optimise the size to fit perfectly into the heap. If you have it twice you simply run out of memory. If you have some services that provide aggregated information you need a single instance. If you have big data models and algorithms that need to reserve some resources you need a single instance.
                    Clusters are another story. Applications with sigletons don't cluster well even if you put a RMI object into the JNDI tree. I never said that you should use singletons but there are cases where it makes sense. I claim that a lot of errors occur because the singleton is a multiton in the application server context. Why do I read so many times that redeployment is so error prone and dangerous and that you shouldn't do it?

                    Also, from another thread of yours - java object lifecycle has nothing to do with db transactions. The fact that current entity bean spec tries to enforce that unholy marriage is not really a recomendation for that line of thinking. If you get lazy loading exception it's a bug. Like NullPointer or IndexOutOfBounds. It's a bug and you fix it.
                    If you use persistent objects the Java object life cycle has something to do with transactions because the transaction defines the life cycle of the persistent object. During the transacton the Java object is persistent, every change is written to the DB. After the transaction ended the persistent object is "dead" but the Java object is still "alive" but changed behaviour because it doesn't write its changes to the DB. The persistent object simply isn't persistent any more and has nothing to do with the data in the database. It's just a "dead" object you can't use any more. It would have been better if you had deleted the reference to keep the two life cycles in sync.
                    One solution to avoid storing references to persistent object into the application context. This makes the context quite useless. Another one might be to store the object identifier instead of the reference and load it with every transaction. This needs special treatment of persistent objects and needs a database roundtrip.

                    Comment


                    • #11
                      Originally posted by haug
                      Inside a container you never know if you have a single instance or multible ones and that makes it so dangerous. If you have a counter of something you need to be sure you have a single instance. If you redeploy (the same class file) you might get a second counter and some sessions use the first counter and the new sessions use the new counter. You end up with wrong values, happy bug squashing.
                      Everything is dangerous if you don't know what's going on or what are you doing. I'd say that designing a system so that it's integrity depends on something so brittle is a bad design.

                      Originally posted by haug
                      Have you made some research or are the numbers just a guess? If you configure your caches you normally optimise the size to fit perfectly into the heap. If you have it twice you simply run out of memory. If you have some services that provide aggregated information you need a single instance. If you have big data models and algorithms that need to reserve some resources you need a single instance.
                      Clusters are another story. Applications with sigletons don't cluster well even if you put a RMI object into the JNDI tree. I never said that you should use singletons but there are cases where it makes sense. I claim that a lot of errors occur because the singleton is a multiton in the application server context. Why do I read so many times that redeployment is so error prone and dangerous and that you shouldn't do it?
                      JNDI is not the solution for the singleton "problem". Most of the singletons out there are stateless and depend only on other stateless singletons. That's why it's threadsafe and why it works in clusters or no clusters, in one or one thousand classloaders. Putting a state in singleton is simply a bad idea. The only global stateful singleton you have is your database and/or your cluster-wide cache. Spring is not a database or a cluster-wide cache product.

                      Originally posted by haug
                      If you use persistent objects the Java object life cycle has something to do with transactions because the transaction defines the life cycle of the persistent object. During the transacton the Java object is persistent, every change is written to the DB. After the transaction ended the persistent object is "dead" but the Java object is still "alive" but changed behaviour because it doesn't write its changes to the DB. The persistent object simply isn't persistent any more and has nothing to do with the data in the database. It's just a "dead" object you can't use any more. It would have been better if you had deleted the reference to keep the two life cycles in sync.
                      No, java objects have nothing to do with transactions. They can also be written to xml files, but it doesn't mean they have anything to do with file system or xml. The fact that some of them may or may be not used in the context of a thread that's bound or not bound to the transaction and that I decided to persist some of them doesn't mean they must die - I may decide to persist them again, maybe to something transactional, maybe not, just keep them as a history or do whatever I want with them. The fact that they are not in sync with some persisted representations may be intentional and relevant or not.

                      Originally posted by haug
                      One solution to avoid storing references to persistent object into the application context. This makes the context quite useless. Another one might be to store the object identifier instead of the reference and load it with every transaction. This needs special treatment of persistent objects and needs a database roundtrip.
                      This part I don't understand. What is "application context" for you exactly? Spring application context?

                      Comment


                      • #12
                        To be honest, I did not know that java scripts can be transferred to xml files and I thought it has to do with transactions. I think it is like the wrong treatment for a chest pain: you take on pill for your chest, and your java will get sick.

                        Comment

                        Working...
                        X