-
1. Re: Someone got @Named producer injection to work?
meetoblivion Dec 27, 2009 8:02 PM (in response to johaneltes)I believe the name for both of those is
jmsTemplate
which is why it's ambiguous. It's based on the returned type, not method name. -
2. Re: Someone got @Named producer injection to work?
johaneltes Dec 27, 2009 8:07 PM (in response to johaneltes)The CDI spec requires them to be named by the producer method, unless the signature is a javabean getter. In the latter case the name should be the java bean property name. I would expect them to be named errorQeueTemplate and logQeueTemplate repectively.
CDI spec:
3.3.8. Default name for a producer method
The default name for a producer method is the method name, unless the method follows the JavaBeans property getter naming convention, in which case the default name is the JavaBeans property name./Johan
-
3. Re: Someone got @Named producer injection to work?
william.drai Dec 27, 2009 8:10 PM (in response to johaneltes)You'd better use qualifiers :
@Produces @Error public JmsTemplate getErrorQeueTemplate(@Named("longReceiveTimeout") int receiveTimeout) { JmsTemplate tmp = new JmsTemplate(); tmp.setReceiveTimeout(receiveTimeout); return tmp; } @Produces @Log public JmsTemplate getLogQeueTemplate(@Named("shortReceiveTimeout") int receiveTimeout) { JmsTemplate tmp = new JmsTemplate(); tmp.setReceiveTimeout(receiveTimeout); return tmp; } }
Then
private @Inject @Error JmsTemplate errorQueueTemplate;
It's a bit more typesafe this way. However it seems that your code should also work. Have you tried :
private @Inject @Named("errorQueueTemplate") JmsTemplate errorQeueTemplate;
-
4. Re: Someone got @Named producer injection to work?
johaneltes Dec 27, 2009 8:17 PM (in response to johaneltes)Debugging weld shows that the injection point is named
errorQueueTemplate
as expected. I suspect the problem is name of the produced bean, which seems to be:org.jboss.weld.bean-se-module-ProducerMethod-se.callistaenterprise.cadec2010.cdi.javase.basic.JmsTemplateConfigurationProducer.getErrorQeueTemplate()
/Johan
-
6. Re: Someone got @Named producer injection to work?
meetoblivion Dec 27, 2009 9:02 PM (in response to johaneltes)no, sorry, i wasn't paying attention as i was typing.
the issue's with the injection point, not the producer.
your injection points are both named
jmsTemplate
. This is why your ints in the rest of your code need to be something like @Named(shortReceiveTimeout
). Weld's not variable name aware as far as i remember.Try changing your injection points to have values in named to match the variable names to see if they get created.
-
7. Re: Someone got @Named producer injection to work?
johaneltes Dec 27, 2009 9:07 PM (in response to johaneltes)The CDI spec requires the injection point @Named-attributed (when value is missing) to default to the name of the field - not to the name of the type of the field:
3.11....If an injected field declares a @Named annotation that does not specify the value member, the name of the field is assumed.
/Johan
-
8. Re: Someone got @Named producer injection to work?
meetoblivion Dec 27, 2009 9:14 PM (in response to johaneltes)Except that you have to take into account this part, right after the part you mention in the spec.
If any other injection point declares a @Named annotation that does not specify the value member, the container automatically
detects the problem and treats it as a definition error. -
9. Re: Someone got @Named producer injection to work?
johaneltes Dec 27, 2009 9:19 PM (in response to johaneltes)I only have one injection point with @Named for that type.
-
10. Re: Someone got @Named producer injection to work?
meetoblivion Dec 27, 2009 9:36 PM (in response to johaneltes)so just to debug a bit, does it work correctly if you @Named your inject points properly
e.g.
private @Inject @Named("errorQueueTemplate") JmsTemplate errorQeueTemplate;
-
11. Re: Someone got @Named producer injection to work?
johaneltes Dec 27, 2009 9:46 PM (in response to johaneltes)It works when I add a value for both injection point and producer @Named annotations. If I leave it out for either producer or field injection point, it fails.
-
12. Re: Someone got @Named producer injection to work?
johaneltes Dec 27, 2009 9:50 PM (in response to johaneltes)I'd like to stress that I think the support for implicit by-convention naming defined by CSI makes a lot of sense. Using strings deviates from the spirit of
type safety
. Declaring custom annotation (to get custom qualifiers) makes a big footprint in small- to midsized projects - especially when the end-goal is to find a CDI-counterpart of Spring property configuration. -
13. Re: Someone got @Named producer injection to work?
meetoblivion Dec 27, 2009 10:25 PM (in response to johaneltes)there's a downside to @Named that you may not have thought of. everything that's @Named is exposed to the view layer. this could be a bit dangerous.
another thing to note, you can get creative with your qualifiers. if you give them enums or strings, you can make them more flexible. right here you are exposing a more complex use case in the realm of CDI, two instances of an object that mean different things.
This is how I would write your code:
@Produces @Templated(TemplateType.ERROR) public JmsTemplate getErrorQeueTemplate(@Named("longReceiveTimeout") int receiveTimeout) { JmsTemplate tmp = new JmsTemplate(); tmp.setReceiveTimeout(receiveTimeout); return tmp; } @Produces @Templated(TemplateType.LOG) public JmsTemplate getLogQeueTemplate(@Named("shortReceiveTimeout") int receiveTimeout) { JmsTemplate tmp = new JmsTemplate(); tmp.setReceiveTimeout(receiveTimeout); return tmp; }
in this case, you need 1 additional qualifier (Templated) and an enum that specifies the types of Templates. The injection points then become
@Inject @Templated(TemplateType.ERROR) JmsTemplate errorTemplate; @Inject @Templated(TemplateType.LOG) JmsTemplate logTemplate;
You can simplify it further if you'd like, using Strings as the value instead of TemplateTypes, and who knows, maybe Seam3 will have support for producing JmsTemplates, as an even better use case would be:
@Target({METHOD, FIELD, PARAMETER, TYPE}) @Retention(RUNTIME) @Qualifier public @interface JmsType { String name() default ""; int timeout() default 30; }
@Produces public JmsTemplate produceJMSTemplate(InjectionPoint injectionPoint) { if (injectionPoint.getAnnotated().isAnnotationPresent(JmsType.class)) { JmsType t = injectionPoint.getAnnotated().getAnnotation(JmsType.class); JmsTemplate tmp = new JmsTemplate(); tmp.setReceiveTimeout(t.timeout()); return tmp; } else { return new JmsTemplate(); } }
Mind you, i've only played with it a little so no claims this will actually work 100% just from this code.
-
14. Re: Someone got @Named producer injection to work?
johaneltes Dec 27, 2009 10:36 PM (in response to johaneltes)@Produces public JmsTemplate produceJMSTemplate(InjectionPoint injectionPoint)...
...This would be immensely cool. Is this a feature of CDI today, or a vision for a forthcoming version?
It would completely reduce the need for been property configurations!
/Johan