Thank you for the hints.
Alas, am still struggling with realization of template method.
I tried different approaches now and am unable to find the "clean"
implementation for my problem. Ok thats my problem and not a CDI issue,
but just for the sake of completeness I'd like to show the solution I
now have and to put the disadvantages to the discussion.
So now I changed AbstractFooProducer to
class BaseFooProducer {
protected void init(Foo foo) {
throw new NotImplementedException();
}
@Produces
public Foo produceFoo() {
//method template goes here e.g. init()
}
}
and
@Specializes
public class ConcreteFooProducer extends BaseFooProducer {
@Override
protected void init(Foo foo) {
foo.setI(234);
}
}
This works as expected but is no elegant solution I would get with an
abstract base class.
Someone suggested me to use @Alternative but I don't see how that can
help me. I don't have different implementations for the same interface
but, rather, I want to enforce particular program flow and allow
descendants to implement parts of it in a specific way (e.g. load data
from xml source or otherwise).
Would be great if someone could suggest me a pattern for this.
br
Reinis
On 27.05.2013 22:50, John D. Ament wrote:
The answer's in the spec (JSR-299)
A producer method must be a non-abstract method of a managed bean class or
session bean class.
Your abstract class is neither a managed bean nor a session bean.
I also confirmed that your project doesn't run with weld.
On Mon, May 27, 2013 at 9:57 AM, Reinis Vicups <[email protected]> wrote:
Hello,
I have three classes
public abstract class AbstractFooProducer {
protected void init(Foo foo) {}
@Produces
public Foo produceFoo() {
Foo foo = new Foo();
init(foo);
return foo;
}
}
then
public class ConcreteFooProducer extends AbstractFooProducer {
@Override
protected void init(Foo foo) {
foo.setI(234);
}
}
and
@Typed(Object.class)
public class Foo {
...
}
Foo is annotated with @Typed to avoid CDI directly injecting Foo in
injection points.
This cause following exception:
javax.enterprise.inject.**UnsatisfiedResolutionException**: Api type
[de.orbitx.specializes.Foo] is not found with the qualifiers
Qualifiers: [@javax.enterprise.inject.**Default()]
for injection into Field Injection Point, field name : foo, Bean Owner :
[FooTest, Name:null, WebBeans Type:ENTERPRISE, API
Types:[java.lang.Object,de.**orbitx.specializes.FooTest,**java.io.Serializable],
Qualifiers:[javax.enterprise.**inject.Default,javax.**
enterprise.inject.Any]]
at org.apache.webbeans.util.**InjectionExceptionUtil.**
throwUnsatisfiedResolutionExce**ption(InjectionExceptionUtil.**java:77)
at org.apache.webbeans.container.**InjectionResolver.**
checkInjectionPoints(**InjectionResolver.java:178)
at org.apache.webbeans.container.**BeanManagerImpl.validate(**
BeanManagerImpl.java:947)
at org.apache.webbeans.config.**BeansDeployer.validate(**
BeansDeployer.java:440)
at org.apache.webbeans.config.**BeansDeployer.**
validateInjectionPoints(**BeansDeployer.java:390)
at org.apache.webbeans.config.**BeansDeployer.deploy(**
BeansDeployer.java:194)
at org.apache.openejb.cdi.**OpenEJBLifecycle.**startApplication(**
OpenEJBLifecycle.java:182)
at org.apache.openejb.cdi.**ThreadSingletonServiceImpl.**initialize(**
ThreadSingletonServiceImpl.**java:158)
at org.apache.openejb.cdi.**CdiBuilder.build(CdiBuilder.**java:43)
at org.apache.openejb.assembler.**classic.Assembler.**
createApplication(Assembler.**java:798)
at org.apache.openejb.assembler.**classic.Assembler.**
createApplication(Assembler.**java:612)
at org.apache.openejb.assembler.**classic.Assembler.**
createApplication(Assembler.**java:608)
at org.apache.openejb.testing.**ApplicationComposers.before(**
ApplicationComposers.java:580)
at org.apache.openejb.testing.**ApplicationComposers.evaluate(**
ApplicationComposers.java:664)
at org.apache.openejb.junit.**ApplicationComposer$**
DeployApplication.evaluate(**ApplicationComposer.java:64)
at org.junit.runners.**ParentRunner.runLeaf(**ParentRunner.java:263)
at org.junit.runners.**BlockJUnit4ClassRunner.**runChild(**
BlockJUnit4ClassRunner.java:**68)
at org.junit.runners.**BlockJUnit4ClassRunner.**runChild(**
BlockJUnit4ClassRunner.java:**47)
at org.junit.runners.**ParentRunner$3.run(**ParentRunner.java:231)
at org.junit.runners.**ParentRunner$1.schedule(**ParentRunner.java:60)
at org.junit.runners.**ParentRunner.runChildren(**
ParentRunner.java:229)
at org.junit.runners.**ParentRunner.access$000(**ParentRunner.java:50)
at org.junit.runners.**ParentRunner$2.evaluate(**
ParentRunner.java:222)
at org.junit.runners.**ParentRunner.run(ParentRunner.**java:300)
at org.eclipse.jdt.internal.**junit4.runner.**JUnit4TestReference.run(
**JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.**junit.runner.TestExecution.**
run(TestExecution.java:38)
at org.eclipse.jdt.internal.**junit.runner.RemoteTestRunner.**
runTests(RemoteTestRunner.**java:467)
at org.eclipse.jdt.internal.**junit.runner.RemoteTestRunner.**
runTests(RemoteTestRunner.**java:683)
at org.eclipse.jdt.internal.**junit.runner.RemoteTestRunner.**
run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.**junit.runner.RemoteTestRunner.**
main(RemoteTestRunner.java:**197)
Why is AbstractFooProducer#**produceFoo() not seen by CDI?
I am also attaching a test project
Thank you very much for your hints
Reinis.