12 Replies Latest reply on Apr 15, 2009 1:56 AM by dan.j.allen

    use Outjection wisely?

    gonorrhea

      ok so here's a thread that started in the Web Beans forum.


      I very rarely argue with the Seam devs' ideas and opinions (well, lately anyways :)


      But consider this from PMuir in my link:



      Q: So is outjection (which is 1/3 of bijection), now an anti-pattern, so to speak?


      PMuir: It's not an anit-pattern IMO, but I would always use it as an optimization, not part of the base design for the app.


      Q: I've used outjectin a lot in my code using @Out in Seam apps... Is the problem due to the fact that the HttpSession gets bloated with objects when you continually outject to session and/or conversation contexts?


      PMuir: No, for me the problem is it produces apps in which the wiring can be harder to understand.

      So I'm wondering if any of you Seam developers agree/disagree with these statements (I'm neutral now)?  I think the reason PMuir is talking about the wiring being harder to understand is that it's sometimes difficult (even in a small app) to track down to which Seam component the injected variable was originally outjected from.


      Perhaps a productivity issue?  The bijection occurs in a context space (e.g. HttpSession or Conversation scope, which is managed space in HttpSession) which is sort of invisible to the developer.


      Well, isn't that what JBoss Tools is for?  There is a Seam components view available.  But all it shows is the scope for that Seam component, the package and class for that component, and that's it.  No context variable data is available.  And even if it was, what if you had dozens or hundreds of Seam components that are bijecting variables left and right?  Gets hard to keep track of.  Perhaps that's what he means by wiring can be harder to understand.  And then compared to using JNDI lookups like we did left and right in Struts/EJB2.x apps (and even straight-up EJB3)?

      Wondering if DI w/ Guice in JSR299 will be different/better....


      So does the comment about outjection apply to injection as well?  You obviously know exactly where the variable is coming from when you outject (but not necessarily so when you inject).

        • 1. Re: use Outjection wisely?
          norman

          I think the key feature of Seam is in being able to create really simple de-coupled components.  If the amount of injection and outjection in components gets too high, then your components become too complex and perhaps too coupled too.  I think this is less of a problem with bijection and more a problem with the granularity that Java web developers are used to developing at. 


          I find myself all too guilty of developing big monolithic components, but when I step back and simplify the design, many of the problems go away.  If you have several things going on in a component, you are probably being too complex.


          That's just my opinion.

          • 2. Re: use Outjection wisely?
            gonorrhea

            to me, big monolithic components is equivalent to bloated session anti-pattern (if the component is a SLSB/SFSB, of course).


            But then if you refactor the class into smaller classes that are responsible for specific behavior/processes, then you need to @Inject those components into your original main EJB.  This makes the code more complicated in terms of extra bijection (at least DI).


            Perhaps one of these days there will be a book entitled Seam Best Practices or Seam Recipes to cover such issues in detail...

            • 3. Re: use Outjection wisely?
              joblini

              Outjected variables are like global variables.  They should be avoided when possible.


              My 2 cents.

              • 4. Re: use Outjection wisely?
                gonorrhea

                It depends what scope/context they are outjected to (i.e. EVENT and CONVERSATION scope is not as global as SESSION or APPLICATION scope).


                But I get your point...

                • 5. Re: use Outjection wisely?
                  dan.j.allen

                  To answer this question, we need to go look back at why outjection was introduced in the first place. Outjection is an inverted approach to keeping a context variable up to date. I'll explain what I mean by inverted shortly. First, let's look at the two things outjection buys you:



                  1. You don't have to interact directly with the context maps (request, session, application, etc) (i.e., no more request.setAttribute("name", value))

                  2. Seam can offer to wrap the value to further decouple you from tedious APIs (i.e., @DataModel wraps a collection in a DataModel before outjecting)



                  These two tasks may seem trivial, but they happen to be the two most common tasks you perform in a typical Model 2 style web application. When was the last time in a Seam application that you used the tedious ExternalContext API from JSF? Exactly. Now compare that to how many times you used HttpServletRequest and HttpServletResponse in Struts. We have come a long way.


                  So what is this I speak of inverted? Well, when you think about it, instead of asking a bean for its state, outjection is giving you the state ahead of time. This is nice because you don't pay any interceptor penalty at all when you access the data, which would be true if you called getter methods on a component. But, as several people have noted in this thread, it can make things confusing since there is no direct correlation between the context variable and its producer.


                  Ah ha! There is that word producer! A producer is the inverse of outjection. Until Seam came around, the only producers we had were getter methods. And I have witnessed a lot of people put logic in a getter method for this reason. But wouldn't it be nice if JSF supported a factory mechanism for a context variable? If you are familiar with Seam, then you know that is exactly what a factory does. Instead of outjecting data, you designate a component method responsible for seeking out that data and returning it, optionally storing it in a scope to avoid further lookups for the intended lifetime of the data.


                  There are two problems with factory methods though. First, you have to be pretty creative with names since the names of the variables that factories produce must be globally unique. With outjection, the component pushes data to a context variable, so you know it is coming from the right source. The second problem is that you end up having to write a lot of factory methods, when it may seem easier to just do context.set("name", value).


                  And then JSR-299 came along. As we understand more about the patterns of enterprise architecture, the frameworks become better. Outjection is a great concept. JSR-299 just promises something even better. But don't take my word for it. It's best to be a skeptic and let the solution prove itself to you as you experiment with it.


                  So why is JSR-299 better than outjection? First, you have to accept that factories are a more organized approach than outjection. JSR-299 producer methods are a much more sophisticated factory. Most importantly, I think, producer methods can take arguments that are filled in via dependency injection. This gives you much greater flexibility in how you lay out your factory components. You also have the sophisticated component activation mechanism, so you can enable and disable factory methods based on deployment types and other runtime settings. Unfortunately, you still have the global name problem. But where things really pay off is that you know exactly the source of any context variable. There is no more guess work...if you were having that problem.


                  In the end, I have always say what is right is what works for you. You shouldn't be asking other people how to write your application. You should be asking yourself if you feel comfortable or uneasy. If you haven't tried Web Beans, how you can you possibly expect to parse these answers? Be truthful with yourself and don't make excuses for the technology, one way or another.

                  • 6. Re: use Outjection wisely?
                    marx3

                    I don't know webbeans, but in/outjection isn't the best approach. I see main problem: no possibility to debug it (few components outject the same variable, who wins?). I have numerous bugs in our application when injected variable is null (even if it's outjected not-null) and it happens mainly under heavy load, but occasionally in normal conditions too.

                    • 7. Re: use Outjection wisely?
                      gonorrhea


                      you have to be pretty creative with names since the names of the variables that factories produce must be globally unique.

                      perhaps that could be refactored to use the package concept.  So instead of @Factory(foo), we can use @Factory(foo.bar.baz) and @Factory(foo.bar.boo).  that would open up more possibilities.




                      Dan Allen wrote on Apr 09, 2009 06:16:


                      And then JSR-299 came along. As we understand more about the patterns of enterprise architecture, the frameworks become better. Outjection is a great concept. JSR-299 just promises something even better. But don't take my word for it. It's best to be a skeptic and let the solution prove itself to you as you experiment with it.


                      Well, Seam came along 3 years ago and industry adoption is still very minimal.  But I guess we'll wait and see if EE 6 takes over Spring or not.


                      Anyways, I appreciate your feedback.  The @DataModel/@Factory annotation combo is very useful in many use cases I've worked on.

                      • 8. Re: use Outjection wisely?
                        gonorrhea

                        other problem i've noticed with outjection is that the outjection only fires after the method completes successfully...

                        • 9. Re: use Outjection wisely?
                          marx3

                          I do not agree - Seam and RF at last lately stabilized and are stable enough for production, and I see sites based on this combo. It is hard to say if Spring is more popular, because you can see RF (and I am pretty sure Seam is under it) but cannot see Spring...

                          • 10. Re: use Outjection wisely?
                            gonorrhea

                            I don't know what country you're in, but check www.dice.com.  It doesn't lie.  Seam is merely an incubator project for Web Beans....

                            • 11. Re: use Outjection wisely?
                              gonorrhea

                              This is a response I just got from Ted Neward:



                              ThoughtWorks doesn’t do much tech training, period, so we’re hardly a good measure of such things; in general, though, I’d have to agree with you, I think Seam adoption is pretty low.
                              • 12. Re: use Outjection wisely?
                                dan.j.allen

                                Can we please focus on the architecture pattern question that you raised in this thread and not go off on tangents about the adoption of Seam? If you want to discuss Seam adoption, please do so in a thread dedicated to that topic. Threads such as these lose their value to people who are searching for help designing their applications if it doesn't remain focused on the subject line. Thanks.