-
1. Re: Injection via abstract getters
gavin.king May 24, 2006 11:22 AM (in response to abirkmanis)A class with abstract methods is not a valid EJB bean and would not be able to be deployed by the container.
If you need laziness, just call Contexts.lookup() -
2. Re: Injection via abstract getters
abirkmanis May 26, 2006 5:44 AM (in response to abirkmanis)Contexts.lookup() is not type safe.
Abstract getters need not be abstract from Java point of view, just conceptually.
For example, their body can do nothing but throw UnsupportedOperationException. -
3. Re: Injection via abstract getters
gavin.king May 26, 2006 10:43 AM (in response to abirkmanis)Right, but nevertheless, this is a problem if the EJB container controls instantiation of the component.
-
4. Re: Injection via abstract getters
abirkmanis May 26, 2006 10:46 AM (in response to abirkmanis)What exactly is a problem? A method that throws an exception? But interceptors are not obliged to call it, right?
-
5. Re: Injection via abstract getters
cptnkirk May 27, 2006 11:33 PM (in response to abirkmanis)The problem is that EJBs can't be abstract. That's an EJB requirement, not a Seam choice. Since Seam deals primarily in EJBs, Gavin can't help you much here.
Seam does support non EJB POJOs, however I wouldn't think the semantics of the framework should change to support abstract JavaBean components. The semantics should be uniform and unfortunately that forces you to conform to the lowest common denominator. Anyway, I think the lack of abstract EJB support is the problem you're looking for.
-Jim -
6. Re: Injection via abstract getters
gavin.king May 28, 2006 12:09 AM (in response to abirkmanis)Note that I am also in priciple against the idea of writing components in terms of abstract classes, since it is significantly more difficult to unit test them (not impossible, but certainly more difficult).
-
7. Re: Injection via abstract getters
abirkmanis May 28, 2006 9:01 AM (in response to abirkmanis)I might have not stressed that enough in the previous posts, but I meant the methods to be conceptually abstract, not formally, e.g.:
@Name("a")
public class ComponentA
{
@In("b")
protected IComponentB getB()
{
throw new UnsupportedOperationException();
}
public void doStuff()
{
getB().doSomeOtherStuff();
// more stuff
}
}
Note that both class ComponentA and method getB should be abstract, but are not.
Is it against the EJB spec to have such SFSB?
Also, I do not see how this class is difficult to test. -
8. Re: Injection via abstract getters
gavin.king May 28, 2006 11:50 AM (in response to abirkmanis)It is difficult to test because
new ComponentA().doStuff() throws an UOE. I have to subclass the class before I can call its methods. -
9. Re: Injection via abstract getters
gavin.king May 28, 2006 11:51 AM (in response to abirkmanis)By the way, it is utterly irrelevant whether it is "conceptually" or actually abstract. In either case my arguments apply.
-
10. Re: Injection via abstract getters
abirkmanis May 29, 2006 3:06 AM (in response to abirkmanis)"gavin.king@jboss.com" wrote:
It is difficult to test because
new ComponentA().doStuff() throws an UOE. I have to subclass the class before I can call its methods.
OTOH, componentAFactory.newInstance().doStuff() works fine.
Also note that in case of eager injections (the current mechanizm) new ComponentA().doStuff() throws an NPE, which is hardly better. -
11. Re: Injection via abstract getters
abirkmanis May 29, 2006 3:09 AM (in response to abirkmanis)"gavin.king@jboss.com" wrote:
By the way, it is utterly irrelevant whether it is "conceptually" or actually abstract. In either case my arguments apply.
Testing is marginally more complex, that's true. But I believe this is outweighted by the improved runtime guarantees.
And the difference between actually and conceptually abstract classes is that the former are not legal EJBs, while the latter are. -
12. Re: Injection via abstract getters
cptnkirk May 29, 2006 4:40 AM (in response to abirkmanis)"abirkmanis" wrote:
Also note that in case of eager injections (the current mechanizm) new ComponentA().doStuff() throws an NPE, which is hardly better.
Had getB() actually been abstract rather than "conceptually" abstract, the compiler wouldn't have even let you create an instance of new ComponentA(). Maybe Seam could do some additional runtime error checking, but something that would have broken in the real world, still breaking in the conceptual world is hardly a shocker.
And even if you were to subclass ComponentA, things still wouldn't work because @In isn't inherited.
Seam components are first class concrete constructs. I don't see a problem with a component's implementation extending an abstract class, but I don't see the value of an abstract component. I do see the problems associated with trying to fake them though."abirkmanis" wrote:
OTOH, componentAFactory.newInstance().doStuff() works fine.
Why not simply do something like this via @Factory or @Unwrap? I'm trying to help, but don't see where this abstractness gets you anything but pain, now, and then later in testing. -
13. Re: Injection via abstract getters
abirkmanis May 29, 2006 5:34 AM (in response to abirkmanis)"CptnKirk" wrote:
"abirkmanis" wrote:
Also note that in case of eager injections (the current mechanizm) new ComponentA().doStuff() throws an NPE, which is hardly better.
Had getB() actually been abstract rather than "conceptually" abstract, the compiler wouldn't have even let you create an instance of new ComponentA().
I meant if I were using the current injections (via setters, not getters), and didn't inject anything for B, but just called doStuff(), I would get an NPE.
Just rewrite the code I suggested to return null instead of throwing UOE, and the failure will be the same for both patterns - NPE in face of missing injection.
Note that I didn't talk about subclassing my component class, Seam could just intercept the call to getB, lookup the value of B and return the value - JIT injection, not sooner when needed.
This JIT nature of injection via getters is their added value compared to injection via setters or fields.
The same effect could be achieved by using Contexts.lookupInStatefulContexts and a type cast inside getB, but then why using annotations and interceptors at all? :-) -
14. Re: Injection via abstract getters
gavin.king May 29, 2006 12:20 PM (in response to abirkmanis)Forget about the abstract getters/setters for now, that is a horrible implementation of laziness anyway.
A good implementation would be to have proxies for the components which actually create the underlying component instance when first invoked. Seam could do that. But it seems to me that the EJB container could do it just as easily, since it already has a proxy.