-
1. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
gavin.king Nov 18, 2009 5:40 PM (in response to sboscarine)Nope. Rewrite it like this:
@Model public class Bean { private Logger logger; private String title; @Inject public Recipe(Logger logger) { this.logger = logger; logger.error("i was constructed"); //null pointer exception } public String getTitle() { logger.error("i was called"); //works just fine (if I comment out logger in constructor) return title; } }
-
2. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
asookazian Nov 18, 2009 5:41 PM (in response to sboscarine)so this is a managed bean lifecycle question I guess.
The injection occurs presumably after the construction of the bean instance and thus, the NPE in the constructor. Is it possible to inject values into the instance prior to construction? Not sure if that is possible?
Is there a lifecycle diagram for managed beans and session beans in EE 6?
-
3. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
gavin.king Nov 18, 2009 5:41 PM (in response to sboscarine)BTW, at some stage, we will support injection into static fields (with some restrictions), which is good for loggers.
-
4. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
asookazian Nov 18, 2009 5:54 PM (in response to sboscarine)
Gavin King wrote on Nov 18, 2009 17:40:
Nope. Rewrite it like this:@Model public class Bean { private Logger logger; private String title; @Inject public Recipe(Logger logger) { this.logger = logger; logger.error("i was constructed"); //null pointer exception } public String getTitle() { logger.error("i was called"); //works just fine (if I comment out logger in constructor) return title; } }
It would be nice if we could do this instead:
public Recipe(@Inject Logger logger) { logger.error("i was constructed"); //null pointer exception }
@Target(value={METHOD,CONSTRUCTOR,FIELD}) @Retention(value=RUNTIME) @Documented public @interface Inject
so field level annotation is possible...
-
5. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
gavin.king Nov 18, 2009 6:37 PM (in response to sboscarine)
It would be nice if we could do this instead:No, that would not be nice. How could the container inject just a single parameter, without calling the whole constructor?
-
6. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
asookazian Nov 18, 2009 7:36 PM (in response to sboscarine)
Gavin King wrote on Nov 18, 2009 18:37:It would be nice if we could do this instead:
No, that would not be nice. How could the container inject just a single parameter, without calling the whole constructor?In any event, I still don't like your solution. It's not bad but not great. If you could devise a way to set the instance variable directly and bypass the local variable, that would eliminate a line of boring code.
private Logger logger; @Inject public Recipe(Logger logger) { this.logger = logger; logger.error("i was constructed"); //null pointer exception }
How bout the container tries to inject whenever there will be a NPE?
so like:
private Logger logger; public Recipe() { logger.error("i was constructed"); //null pointer exception }
so there would a config somewhere (say in beans.xml?) that would specify to inject any and all occurrences of Logger type when it may be null at runtime.
I have a feeling this is unorthodox/impossible but it seems cool... like a backup or plan B injection strategy... less lines of code in your classes...
-
7. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
asookazian Nov 18, 2009 7:54 PM (in response to sboscarine)
Gavin King wrote on Nov 18, 2009 18:37:It would be nice if we could do this instead:
No, that would not be nice. How could the container inject just a single parameter, without calling the whole constructor?It would be very nice. But impossible maybe. But I'm not the container designer :).
container first sees this:
public Recipe(@Inject Logger logger) { logger.error("i was constructed"); }
as this:
public Recipe(Logger logger) { logger.error("i was constructed"); }
So the instance now exists. Then proceeds with the injection (post-injection).
So execute this first:
public Recipe(Logger logger) { }
then this:
@Inject logger.error("i was constructed");
Now the problem is that in my version the injection would occur for the local variable, not the instance variable, which is the one we want to be injected.
Although in CDI, there is no dynamic re-injection like in Seam, correct? In Seam, all injections occur prior to public method invocation. Every time a public method is called on that Seam component. Not sure if it works this way with managed beans or session beans in CDI.
I'm going to be bashed on this post, oh well... It really seems to me there's a better way...
Why doesn't this work or why isn't it allowed?
@Model public class Bean { @Inject private Logger logger; ... }
This is a close equivalent in Seam 2.x:
@Name("bean") public class Bean { @Logger private Log log; ... }
???
-
8. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
asookazian Nov 18, 2009 7:55 PM (in response to sboscarine)btw, when I say
container first sees this....
this is my imagination at work, not saying it actually works this way now... -
9. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
gavin.king Nov 18, 2009 8:11 PM (in response to sboscarine)We're not limited by your imagination, Arbi. We are limited by what is possible in the Java language and JVM. I can't inject a field until after the constructor has executed. End of story.
Why doesn't this work or why isn't it allowed?@Model public class Bean { @Inject private Logger logger; ... }
Of course it is allowed, which you would know if you had read the spec.
-
10. Re: Can I use an @Inject-ed class, like Logger, into a no-args constructor?
asookazian Nov 18, 2009 8:25 PM (in response to sboscarine)this is allowed:
@Model public class Bean { @Inject private Logger logger; public void foo() { logger.error("bar"); } ... }
this is not allowed:
@Model public class Bean { @Inject private Logger logger; public Bean(){ logger.error("foo"); } ... }
read the spec. I'm really trying to read the spec some and the ref doc for Weld. That would avoid a lot of these stupid questions/comments I'm sure. I'm having problems understanding the concepts like stereotypes and @Alternatives, for example. Not trivial. Getting there...