Hi,

2010/8/2 Hynek Mlnařík <[email protected]>

> Hi,
>
> thanks a lot for your explanations. Now I understand the desired iPOJO
> behaviour regarding instantiation much better.
>
> However the problem with calling a parameterless constructor remains. I've
> made a short research into the issue and created a test case which could be
> found at http://www.sendspace.com/file/imhlcx. It is a simple
> two-component sample (one component requires the other). The components are
> created programmatically (via IPOJOHelper class fragment taken from
> junit4osgi project). It correctly does not invoke a parameterless
> constructor of a.b.LoggerComponent when a.b.LoggerComponent class does not
> contain a @Validate annotated method. However, if such a method exists in
> the class, a parameterless constructor is invoked. This seems a bug to me.
> Could you please confirm it or let me know what I'm doing wrong?
>

The @Validate callback will create the object using a parameterless
constructor. Indeed, to call the validate method, iPOJO needs to create an
object first. This object is created by using a parameterless argument or a
static factory method (@Component.factory_method). This method is also
called without parameters. If you want to set 'fields', just declare
properties and give the values in the instance configuration.

But in your case, it will not help :-). You're using service object creation
strategy, so you can't use the @Validate annotation because both have
the responsibility to create the service objects. @Validate is called first
and immediately after the instance validation. The object is created using
the parameterless constructor. However, to get your code working correctly,
just call the method annotated with @Validate in the constructor and remove
the @Validate.
LoggerComponent(final String name) {
        this.name = name;
        System.out.println("constructor with parameter " + name);
        validateLoggerComponent(); // <-- Added
}

Only the service providing strategy has the responsibility to create your
object. And so, it will call the correct constructor.

Regards,

Clement


>
> Thanks,
>
> --Hynek
>
> On 30.7.2010, Clement Escoffier wrote:
> > Hi
> >
> > On 29.07.2010, at 15:59, Hynek Mlnařík wrote:
> >
> > > Hi,
> > >
> > > I have two questions. To start with a simple one - is there a way to
> let iPOJO
> > create default (empty) component instances on demand when requested by
> > @Requested annotation? I only found a possibility of explicit
> instantiation via
> > @Instantiate annotation explicitly but the on-demand one would be nice.
> >
> > No there is not @Requested annotation. The @Instantiate annotation
> declares an
> > instance. However:
> > - @Instantiate declares the instance BUT does not create the POJO object
> > (service object), which is created lazily. So, it's an empty shell until
> the
> > service object is required (if the component is not configure to be
> immediate).
> > - You can create iPOJO instances using the Factory service (exposed by
> all
> > 'public' component types). If you need to handle lazy instance
> declarations, you
> > can still use this API to create instances on the fly.
> >
> >
> > >
> > > The second question might be linked to the previous one. I'd like to
> have a
> > component (logger) that gets parametrized by requesting components. I
> found that
> > a way to get it working might be using strategies like this:
> > >
> > > @Component
> > > @Provides(strategy="LoggerComponentStrategy")
> > > class LoggerComponent implements LoggerComponentInterface {
> > > ...
> > > }
> > >
> > > public class LoggerComponentStrategy extends
> ConfigurableCreationStrategy
> > implements ServiceObjectFactory {
> > >    @Override
> > >    protected ServiceObjectFactory getServiceFactory(final
> InstanceManager
> > manager) {
> > >        return this;
> > >    }
> > >
> > >    @Override
> > >    public Object getService(final ComponentInstance instance) {
> > >        final String name =
> > instance.getInstanceDescription().getComponentDescription().getName();
> > >        return safelyCreateLogger(name);
> > >    }
> > >  ...
> > > }
> > >
> > > @Component
> > > @Instantiate
> > > class B {
> > >    @Requires LoggerComponentInterface l;
> > > }
> > >
> > > B gets only instantiated when the LoggerComponent class is annotated
> with
> > @Instantiate annotation, ie. there already exists a Logger instance in
> iPOJO
> > manager. That empty instance however is not used (and never will): the
> obtained
> > instance of Logger injected into B must be parametrized with "B" name. Is
> there
> > any way to have B initialize with the correct logger without the
> necessity of
> > that useless empty Logger instance?
> >
> > The LoggerComponent instance should not be created until B is really
> requiring
> > the logger. So, the 'getService' method should not be called before 'l'
> is
> > accessed.
> > Did you see a different behavior ?
> >
> >
> > Regards,
> >
> > Clement
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [email protected]
> For additional commands, e-mail: [email protected]
>
>

Reply via email to