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