You're right Tim, it's not a bug per say and that's why I never called it
that. But it sure is damned annoying. And frankly I don't have a really
good solution either.

However it seems the only truly logical thing the proxy could do is
blacklist any of the Object non-arg methods. To be honest, I think that
wouldn't be a bad thing... if someone really uses any of these "properties"
I'd question their motives:

getClass
hashCode
clone
toString
notify
notifyAll
wait

They could get a better result with any kind of prefix.

- Ray

On Sun, Nov 20, 2016 at 6:56 PM, Tim Ward <tim.w...@paremus.com> wrote:

> I'm not sure how you would fix this. Isn't toString a valid (and unset)
> property of a configuration?
>
> Sounds like a working, albeit non-obviously so, implementation to me.
>
> Regards,
>
> Tim
>
> Sent from my iPhone
>
> On 20 Nov 2016, at 23:43, Raymond Auge <raymond.a...@liferay.com> wrote:
>
> Scott, the null is a tricky side effect of the config proxy's toString
> method. It's not your code. The object is indeed not null, but putting it
> in a string triggers this naughty output which I admit has caused me
> headaches a few times. Someone should really fix it.
>
> - Ray
>
> On Nov 20, 2016 2:27 PM, "Scott Lewis" <sle...@composent.com> wrote:
>
>> I've created these two components:
>>
>> #1 FooImpl of IFoo service
>>
>> @ObjectClassDefinition(name = "Foo Configuration")
>> @interface FooConfig {
>>   String message() default "Hi There";
>> }
>> @Designate(ocd = FooConfig.class, factory=true)
>> @Component(scope=ServiceScope.PROTOTYPE,configurationPolicy=
>> ConfigurationPolicy.REQUIRE)
>> public class FooImpl implements IFoo {
>>
>>     private FooConfig config;
>>
>>     @Override
>>     public String getMessage() {
>>         return config.message();
>>     }
>>
>>     @Activate
>>     void activate(FooConfig config) throws Exception {
>>         System.out.println("activate instance="+this+" with
>> config="+config);
>>         this.config = config;
>>     }
>>
>>     @Deactivate
>>     void deactivate() {
>>         System.out.println("deactivate instance="+this);
>>     }
>>
>>     @Modified
>>     void modified(FooConfig config) {
>>         System.out.println("modified instance="+this+" with new
>> config="+config);
>>     }
>> }
>>
>>
>> // #2 The FooConsumer that creates the prototype instances
>>
>> @Component(immediate=true)
>> public class FooConsumer {
>>
>>     private ComponentServiceObjects<IFoo> f;
>>
>>     @Reference(scope=ReferenceScope.PROTOTYPE_REQUIRED)
>>     void setFooFactory(ComponentServiceObjects<IFoo> fact) {
>>         this.f = fact;
>>     }
>>
>>     void unsetFooFactory(ComponentServiceObjects<IFoo> fact) {
>>         this.f = null;
>>     }
>>
>>     private IFoo[] foos;
>>
>>     @Activate
>>     void activate() {
>>         System.out.println("activate FooConsumer="+f);
>>         foos = new IFoo[5];
>>         for(int i=0; i < 5; i++) {
>>             foos[i] = f.getService();
>>             System.out.println("foos["+i+"].getMessage() returns:
>> "+foos[i].getMessage());
>>         }
>>     }
>>
>>     @Deactivate
>>     void deactivate() {
>>         for(int i=0; i < 5; i++) {
>>             f.ungetService(foos[i]);
>>         }
>>     }
>> }
>>
>> When the two bundles (IFoo API bundle and bundle containing above 2
>> components) are installed and started on Karaf 4.0.5 no output is produced,
>> since there is no configuration created and the consumer ref to the
>> ComponentServiceFactory is set to REQUIRE. When I go to the webconsole and
>> create a Foo Configuration the following output is produced:
>>
>> karaf@root()> activate FooConsumer=ComponentServiceObjectsImpl
>> [instances=[], se
>> rviceObjects=org.apache.felix.framework.BundleContextImpl$Se
>> rviceObjectsImpl@b55
>> a5b0, deactivated=false, hashCode=2085697315]
>> activate instance=org.eclipse.ecf.test.foo.impl.FooImpl@6d86a6c2 with
>> config=null
>> foos[0].getMessage() returns: Hi There Scott
>> activate instance=org.eclipse.ecf.test.foo.impl.FooImpl@68a1dfe8 with
>> config=null
>> foos[1].getMessage() returns: Hi There Scott
>> activate instance=org.eclipse.ecf.test.foo.impl.FooImpl@215c5b23 with
>> config=null
>> foos[2].getMessage() returns: Hi There Scott
>> activate instance=org.eclipse.ecf.test.foo.impl.FooImpl@7bba307e with
>> config=null
>> foos[3].getMessage() returns: Hi There Scott
>> activate instance=org.eclipse.ecf.test.foo.impl.FooImpl@21f74969 with
>> config=null
>> foos[4].getMessage() returns: Hi There Scott
>>
>>
>> I don't know why the config=null is reported...the config passed in is
>> not null (via debugger), and you can see that the config.message() call
>> returns Hi There Scott.  It appears to me to be a small bug (e.g. in the
>> toString() impl of the proxy that's passed in)?
>>
>> This is fine for my use case WRT creating service instances on demand via
>> the FooConsumer.   However, I would like to be able to have a distinct/new
>> configuration associated with each new FooImpl, rather than a single
>> FooConfig instance assigned to all of them.   Is this possible using the
>> PROTOTYPE pattern, or is it necessary to use the ComponentFactory in the
>> manner Tim describes to accomplish this:
>>
>> The way that this is done is to pass the configuration using the
>> newInstance method. Effectively your pattern would be to register a
>> ConfigurationListener or ManagedServiceFactory, passing the configuration
>> Dictionary to the Component Factory for each Factory Configuration.
>>
>> Thanksinadvance,
>>
>> Scott
>>
>> _______________________________________________
>> OSGi Developer Mail List
>> osgi-dev@mail.osgi.org
>> https://mail.osgi.org/mailman/listinfo/osgi-dev
>>
> _______________________________________________
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org
> https://mail.osgi.org/mailman/listinfo/osgi-dev
>
>
> _______________________________________________
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org
> https://mail.osgi.org/mailman/listinfo/osgi-dev
>



-- 
*Raymond Augé* <http://www.liferay.com/web/raymond.auge/profile>
 (@rotty3000)
Senior Software Architect *Liferay, Inc.* <http://www.liferay.com>
 (@Liferay)
Board Member & EEG Co-Chair, OSGi Alliance <http://osgi.org> (@OSGiAlliance)
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to