You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@felix.apache.org by Al...@miranda.com on 2014/04/03 19:59:53 UTC
iPOJO instances
I am having some problems understanding the concept of component
instanciation. I read
http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/apache-felix-ipojo-instances.html
and I get the analogy to classes and objects but I still have some
concrete problems and some conceptual problems that I hope someone can
clarify
I thought I needed to create instances via iPOJO (@Instantiate or
factories) only for service providers since they never use new because the
impl is always hidden. However, I have some consumers @Component that I
instanciate myself (say in a main() method where I call new on them
directly). I made them @Component because they need to have things
injected. I was assuming that the ipojo bytecode manipulation would make
it so that when the objects were constructed, they would have their
dependencies injected (I'm using mostly method injection with @Bind) but
it seems that is not the case. Can someone clarify this for me please. Now
it seems to me that for iPOJO to do any injection at all I need to always
use one of the iPOJO instantiation techniques. The problem I have is that
then the constructors I made in the consumer classes are not called
This is a simplified example to illustrate my confusion
@Component(name="test")
public class MyFoo {
private List<External> externals; //injected
private Bar bar; //passed via constructor
public MyFoo(Bar otherBar) {
bar = otherBar;
externals = new ArrayList();
}
@Bind(aggregate=true)
public addExternal(External service) {
externals.add(service);
}
}
So, as can be seen here, I need to have all the providers of interface
External, but I also need a Bar object that I pass when I construct the
object using new MyFoo(someBar)
My problem is that if I need to pass a Bar to the constructor then I need
to use new; but If i use new, iPojo never invokes my injection method. On
the other hand, if I use iPOJOs instantiation (say I add @Instantiate)
then the injection does happen but it throws a NPE because the list has
not been created yet + bar will not be set. I know I can create the list
inside the injection method, but my question is more conceptual.
1) How are you supposed to accomplish this (making sure that the
constructor is invoked)?
2) How can iPOJO be calling addExternal (which means the object has been
created) without calling my one and only constructor that creates the
object? this is very counter-intuitive in standard java
3) Are you just not supposed to use constructors when using iPOJO
components maybe?
Thanks for any help
Alejandro Endo | Software Designer/Concepteur de logiciels
DISCLAIMER:
Privileged and/or Confidential information may be contained in this
message. If you are not the addressee of this message, you may not
copy, use or deliver this message to anyone. In such event, you
should destroy the message and kindly notify the sender by reply
e-mail. It is understood that opinions or conclusions that do not
relate to the official business of the company are neither given
nor endorsed by the company.
Thank You.
Re: iPOJO instances
Posted by Al...@miranda.com.
Aha,
that makes it clear.
Thank you Clement.
Alejandro Endo | Software Designer/Concepteur de logiciels
From: Clement Escoffier <cl...@gmail.com>
To: Apache Felix - Users Mailing List <us...@felix.apache.org>,
Date: 2014-04-04 01:40 AM
Subject: Re: iPOJO instances
Hi,
On 3 avr. 2014, at 19:59, Alejandro.Endo@miranda.com wrote:
> I am having some problems understanding the concept of component
> instanciation. I read
>
http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/apache-felix-ipojo-instances.html
> and I get the analogy to classes and objects but I still have some
> concrete problems and some conceptual problems that I hope someone can
> clarify
>
> I thought I needed to create instances via iPOJO (@Instantiate or
> factories) only for service providers since they never use new because
the
> impl is always hidden. However, I have some consumers @Component that I
> instanciate myself (say in a main() method where I call new on them
> directly). I made them @Component because they need to have things
> injected. I was assuming that the ipojo bytecode manipulation would make
> it so that when the objects were constructed, they would have their
> dependencies injected (I'm using mostly method injection with @Bind) but
> it seems that is not the case. Can someone clarify this for me please.
Now
> it seems to me that for iPOJO to do any injection at all I need to
always
> use one of the iPOJO instantiation techniques. The problem I have is
that
> then the constructors I made in the consumer classes are not called
>
> This is a simplified example to illustrate my confusion
>
> @Component(name="test")
> public class MyFoo {
> private List<External> externals; //injected
> private Bar bar; //passed via constructor
>
> public MyFoo(Bar otherBar) {
> bar = otherBar;
> externals = new ArrayList();
> }
>
> @Bind(aggregate=true)
> public addExternal(External service) {
> externals.add(service);
> }
> }
>
> So, as can be seen here, I need to have all the providers of interface
> External, but I also need a Bar object that I pass when I construct the
> object using new MyFoo(someBar)
>
> My problem is that if I need to pass a Bar to the constructor then I
need
> to use new; but If i use new, iPojo never invokes my injection method.
On
> the other hand, if I use iPOJOs instantiation (say I add @Instantiate)
> then the injection does happen but it throws a NPE because the list has
> not been created yet + bar will not be set. I know I can create the list
> inside the injection method, but my question is more conceptual.
>
> 1) How are you supposed to accomplish this (making sure that the
> constructor is invoked)?
> 2) How can iPOJO be calling addExternal (which means the object has been
> created) without calling my one and only constructor that creates the
> object? this is very counter-intuitive in standard java
> 3) Are you just not supposed to use constructors when using iPOJO
> components maybe?
iPOJO is a component model where instances are composed by a container and
?content? objects. Calling ?new? would not work as the container won?t be
created (only the content). As soon as you have a class with @Component,
you should not call the constructor by yourself, but use iPOJO
instantiation mechanism. Whether or not your component provides a service
does not matter. It?s the responsibility of the container to call the
constructor when required. This has one major impact on the constructor
signatures. They have to be either without parameters, or with injected
parameters only (@Requires, or @Property, and more recently @Context).
In your case, there are several way:
1) add the @Instantiate annotation (below @Component), and it will create
the instance. Your constructor would have to be empty or receive the
?otherBar? as a service (@Requires, but this would require to have a
component publishing this service).
2) Create an instance of MyFoo using the Factory service and inject
?otherBar? as a property (@Property). In this case the instance
configuration contains the ?otherBar: whatever Bar object?.
Regards,
Clement
>
>
> Thanks for any help
>
> Alejandro Endo | Software Designer/Concepteur de logiciels
>
> DISCLAIMER:
> Privileged and/or Confidential information may be contained in this
> message. If you are not the addressee of this message, you may not
> copy, use or deliver this message to anyone. In such event, you
> should destroy the message and kindly notify the sender by reply
> e-mail. It is understood that opinions or conclusions that do not
> relate to the official business of the company are neither given
> nor endorsed by the company.
> Thank You.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org
DISCLAIMER:
Privileged and/or Confidential information may be contained in this
message. If you are not the addressee of this message, you may not
copy, use or deliver this message to anyone. In such event, you
should destroy the message and kindly notify the sender by reply
e-mail. It is understood that opinions or conclusions that do not
relate to the official business of the company are neither given
nor endorsed by the company.
Thank You.
Re: iPOJO instances
Posted by Clement Escoffier <cl...@gmail.com>.
Hi,
On 3 avr. 2014, at 19:59, Alejandro.Endo@miranda.com wrote:
> I am having some problems understanding the concept of component
> instanciation. I read
> http://felix.apache.org/documentation/subprojects/apache-felix-ipojo/apache-felix-ipojo-userguide/apache-felix-ipojo-instances.html
> and I get the analogy to classes and objects but I still have some
> concrete problems and some conceptual problems that I hope someone can
> clarify
>
> I thought I needed to create instances via iPOJO (@Instantiate or
> factories) only for service providers since they never use new because the
> impl is always hidden. However, I have some consumers @Component that I
> instanciate myself (say in a main() method where I call new on them
> directly). I made them @Component because they need to have things
> injected. I was assuming that the ipojo bytecode manipulation would make
> it so that when the objects were constructed, they would have their
> dependencies injected (I'm using mostly method injection with @Bind) but
> it seems that is not the case. Can someone clarify this for me please. Now
> it seems to me that for iPOJO to do any injection at all I need to always
> use one of the iPOJO instantiation techniques. The problem I have is that
> then the constructors I made in the consumer classes are not called
>
> This is a simplified example to illustrate my confusion
>
> @Component(name="test")
> public class MyFoo {
> private List<External> externals; //injected
> private Bar bar; //passed via constructor
>
> public MyFoo(Bar otherBar) {
> bar = otherBar;
> externals = new ArrayList();
> }
>
> @Bind(aggregate=true)
> public addExternal(External service) {
> externals.add(service);
> }
> }
>
> So, as can be seen here, I need to have all the providers of interface
> External, but I also need a Bar object that I pass when I construct the
> object using new MyFoo(someBar)
>
> My problem is that if I need to pass a Bar to the constructor then I need
> to use new; but If i use new, iPojo never invokes my injection method. On
> the other hand, if I use iPOJOs instantiation (say I add @Instantiate)
> then the injection does happen but it throws a NPE because the list has
> not been created yet + bar will not be set. I know I can create the list
> inside the injection method, but my question is more conceptual.
>
> 1) How are you supposed to accomplish this (making sure that the
> constructor is invoked)?
> 2) How can iPOJO be calling addExternal (which means the object has been
> created) without calling my one and only constructor that creates the
> object? this is very counter-intuitive in standard java
> 3) Are you just not supposed to use constructors when using iPOJO
> components maybe?
iPOJO is a component model where instances are composed by a container and ‘content’ objects. Calling ‘new’ would not work as the container won’t be created (only the content). As soon as you have a class with @Component, you should not call the constructor by yourself, but use iPOJO instantiation mechanism. Whether or not your component provides a service does not matter. It’s the responsibility of the container to call the constructor when required. This has one major impact on the constructor signatures. They have to be either without parameters, or with injected parameters only (@Requires, or @Property, and more recently @Context).
In your case, there are several way:
1) add the @Instantiate annotation (below @Component), and it will create the instance. Your constructor would have to be empty or receive the ‘otherBar’ as a service (@Requires, but this would require to have a component publishing this service).
2) Create an instance of MyFoo using the Factory service and inject ‘otherBar’ as a property (@Property). In this case the instance configuration contains the ‘otherBar: whatever Bar object’.
Regards,
Clement
>
>
> Thanks for any help
>
> Alejandro Endo | Software Designer/Concepteur de logiciels
>
> DISCLAIMER:
> Privileged and/or Confidential information may be contained in this
> message. If you are not the addressee of this message, you may not
> copy, use or deliver this message to anyone. In such event, you
> should destroy the message and kindly notify the sender by reply
> e-mail. It is understood that opinions or conclusions that do not
> relate to the official business of the company are neither given
> nor endorsed by the company.
> Thank You.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@felix.apache.org
For additional commands, e-mail: users-help@felix.apache.org