Hi, I mentioned an object type like a Promise that wouldi be capable to 
"unresolve" or "modifications". Some object that doesn't needs to be replaced, 
when there are dynamic changes. Something that can make our add, rem, mod 
callbacks available for field injectionLike getting the ServiceTracker 
injected, but with a nice, fluent, Promis-style API 🙂RegardsMark Hoffmann M.A. 
Dipl.-Betriebswirt (FH) CEO/CTO Phone:   +49 3641 384 910 0 Mobile:  +49 175 
701 2201 E-Mail: m.hoffm...@data-in-motion.biz Web: www.datainmotion.de Data In 
Motion Consulting GmbH Kahlaische Strasse 4 07745 Jena Germany 
Geschäftsführer/CEO Mark Hoffmann Jürgen Albert Jena HRB 513025 Steuernummer 
162/107/05779 USt-Id DE310002614
-------- Ursprüngliche Nachricht --------Von: BJ Hargrave via osgi-dev 
<osgi-dev@mail.osgi.org> Datum: 28.09.20  17:41  (GMT+01:00) An: 
osgi-dev@mail.osgi.org Betreff: Re: [osgi-dev] SCR: ServiceInjection into 
Fields that are       Optional<Service> I kind of like the idea of Optional<T> 
for field injection. As Neil says, it is short hand for 
cardinality=ReferenceCardinality.OPTIONAL.
 
Since R8 supports, Java 8 as the base language level, we can now add support 
for Optional as a field (and constructor) injection type. Bnd can infer the 
actual service type from the generic T.
 
So
 
@Reference
Optional<Foo> foo;
 
would be a static optional reference to a Foo service, The foo field would be 
injected with either an empty Optional if there is no target Foo service, or a 
non-empty Optional with the bound Foo service. Like all static references, the 
foo field would not be changed by SCR during the life cycle of the component 
instance. This can also be used in constructor injection with a Optional<Foo> 
constructor parameter.
 
@Reference
volatile Optional<Foo> foo;
 
would be a dynamic optional reference to a Foo service. The foo field would be 
injected with either an empty Optional if there is no target Foo service, or a 
non-empty Optional with the bound Foo service. Like all dynamic references, the 
value of the foo field can be changed by SCR at any time during the life cycle 
of the component instance. So when the component wishes to use the field, it 
should copy the field's value into a local variable before inspection and use.
 
Optional<Foo> localFoo = foo;
if (localFoo.isPresent()) { do something with localFoo; }
 
I do not think Promise is a proper type to use here. Promise is about a future 
result and is a one-time latch on resolving the value. At the time SCR will 
inject the field, the state of the target service must be known. For dynamic 
references, SCR must replace the field as the bound service changes. So there 
is no real utility in using Promise here as you still would have know way to 
know there was a new Promise object to which you might want to attach a 
callback.
 
I will open an issue to add Optional support for field and constructor 
injection to DS 1.5 for R8.
 
--BJ HargraveSenior Technical Staff Member, IBM // office: +1 386 848 1781OSGi 
Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 
3788hargr...@us.ibm.com
 
 
----- Original message -----From: Mark Hoffmann via osgi-dev 
<osgi-dev@mail.osgi.org>Sent by: osgi-dev-boun...@mail.osgi.orgTo: Neil 
Bartlett <njbartl...@gmail.com>Cc: OSGi Developer Mail List 
<osgi-dev@mail.osgi.org>Subject: [EXTERNAL] Re: [osgi-dev] SCR: 
ServiceInjection into Fields that are Optional<Service>Date: Wed, Sep 23, 2020 
10:14        

 

Hi Neil,
 
exactly I thought of a fluent API for a ServiceTracker.
 
Regards,
 
Mark Hoffmann 
M.A. Dipl.-Betriebswirt (FH) 
CEO/CTO 
 
Phone: +49 3641 384 910 0 
Mobile: +49 175 701 2201 
E-Mail: m.hoffm...@data-in-motion.biz 
 
Web: www.datainmotion.de 
 
Data In Motion Consulting GmbH 
Kahlaische Strasse 4 
07745 Jena 
Germany 
 
Geschäftsführer/CEO 
Mark Hoffmann 
Jürgen Albert 
 
Jena HRB 513025 
Steuernummer 162/107/05779 
USt-Id DE310002614
 
 
-------- Ursprüngliche Nachricht --------
Von: Neil Bartlett <njbartl...@gmail.com>
Datum: 23.09.20 16:01 (GMT+01:00)
An: Mark Hoffmann <m.hoffm...@data-in-motion.biz>
Cc: OSGi Developer Mail List <osgi-dev@mail.osgi.org>
Betreff: Re: [osgi-dev] SCR: ServiceInjection into Fields that are 
Optional<Service>
 
Ah okay thank you. So you're not talking about the existing Promise class, 
rather a class that would keep track of the changing state of the service.
 
As I think you said, that's basically a ServiceTracker. However the existing 
ServiceTracker class has a lot of complexity and still uses ancient APIs like 
Dictionary. So the requirement could be to define a new interface 
("ServiceHandle"?) that has methods like:
 
    interface ServiceHandle<S> {
        void ifPresent(Consumer<? super S>); // from Optional
        Stream<S> stream(); // from Optional
        Promise<S> whenResolved();
        Promise<Void> whenUnresolved();
    }
 
SCR could inject an instance of this interface into a component (component 
authors would not be able to instantiate their own instance).
 
It's an interesting idea, but I believe it would be better to keep it as a 
separate requirement from the "support Optional-typed field injection" 
requirement.
 
Neil
    

On Wed, 23 Sep 2020 at 14:24, Mark Hoffmann <m.hoffm...@data-in-motion.biz> 
wrote:
Hi Neil,
 
thus is why I said something like a Promise. I think in my first post this 
morning I mentioned e.g. the missing unresolve or reresolve.
 
On the other side, if we had such an special Object, we could also bring the 
feature of callbacks back to field injection.
 
Just to get you right, I am not against the idea, I just wanted to get a step 
further !? 🙂
 
 
Mark Hoffmann 
M.A. Dipl.-Betriebswirt (FH) 
CEO/CTO 
 
Phone: +49 3641 384 910 0 
Mobile: +49 175 701 2201 
E-Mail: m.hoffm...@data-in-motion.biz 
 
Web: www.datainmotion.de 
 
Data In Motion Consulting GmbH 
Kahlaische Strasse 4 
07745 Jena 
Germany 
 
Geschäftsführer/CEO 
Mark Hoffmann 
Jürgen Albert 
 
Jena HRB 513025 
Steuernummer 162/107/05779 
USt-Id DE310002614
 
 
-------- Ursprüngliche Nachricht --------
Von: Neil Bartlett <njbartl...@gmail.com>
Datum: 23.09.20 13:14 (GMT+01:00)
An: Mark Hoffmann <m.hoffm...@data-in-motion.biz>
Cc: OSGi Developer Mail List <osgi-dev@mail.osgi.org>
Betreff: Re: [osgi-dev] SCR: ServiceInjection into Fields that are 
Optional<Service>
 
Can you clarify how you would expect a Promise to work?
 
It sounds a bit like forcing dynamic behaviour into a static reference, i.e. 
you get a static field of type Promise which may later resolve to the bound 
service. But this disconnects the lifecycle of the component from the 
availability of the service. The problem is that the service can change state 
many times between available and unavailable, whereas a Promise only ever has a 
single state change (from unresolved to resolved). That is, a Promise cannot 
revert from resolved to unresolved.
 
It seems to me that we already have a mechanism for tracking the dynamic state 
of a service with callbacks, and that is method injection. The bind and unbind 
methods can be called as many times as necessary. I don't see how Promises make 
this any cleaner.
 
The idea of explicitly supporting Optional fields does not have any lifecycle 
implications for the component. We simply change the representation of 
"unbound" from null to Optional.empty() and eliminate a whole class of 
potential NPE-throwing code patterns.
 
Neil 

On Wed, 23 Sep 2020 at 12:01, Mark Hoffmann <m.hoffm...@data-in-motion.biz> 
wrote:
Hi,
 
Neill I see the point. As already mentioned I would rather see something like 
Promise instead fd an Optional, where I could stay with one instance.
 
In addition to that I would get onResolve out-of-the-box.
 
Regards,
 
Mark Hoffmann 
M.A. Dipl.-Betriebswirt (FH) 
CEO/CTO 
 
Phone: +49 3641 384 910 0 
Mobile: +49 175 701 2201 
E-Mail: m.hoffm...@data-in-motion.biz 
 
Web: www.datainmotion.de 
 
Data In Motion Consulting GmbH 
Kahlaische Strasse 4 
07745 Jena 
Germany 
 
Geschäftsführer/CEO 
Mark Hoffmann 
Jürgen Albert 
 
Jena HRB 513025 
Steuernummer 162/107/05779 
USt-Id DE310002614
 
 
-------- Ursprüngliche Nachricht --------
Von: Neil Bartlett <njbartl...@gmail.com>
Datum: 23.09.20 11:50 (GMT+01:00)
An: Mark Hoffmann <m.hoffm...@data-in-motion.biz>, OSGi Developer Mail List 
<osgi-dev@mail.osgi.org>
Betreff: Re: [osgi-dev] SCR: ServiceInjection into Fields that are 
Optional<Service>
 
I like Stefan's suggestion and I disagree with some specific points made by 
Mark... responses line below. 

On Wed, 23 Sep 2020 at 05:35, Mark Hoffmann via osgi-dev 
<osgi-dev@mail.osgi.org> wrote:
Hi Stefan,
 
I believe Optionals are not optimal for that.
 
If a service is removed, you would need a new empty optional instance. 
Optionals doesn't support to hold a state.
 
The state is in the component, not the Optional instance. References are static 
by default, so under Stefan's example the component would be destroyed if the 
field was bound to a service and that service instance became unregistered. The 
proposed change to the spec is that SCR in this case must reinitialize the 
field with Optional.empty() rather than with null. For a dynamic reference, the 
field would need to be volatile just as it is in R7. The only difference is 
that the field value would be replaced by Optional.empty() rather than null in 
the case where the reference is unbound.
 
There are two advantages that I can see. The first is brevity. When bnd sees a 
field of type Optional, it can infer a cardinality of 0..1, so we do not have 
to annotate with `cardinality=ReferenceCardinality.OPTIONAL`, which is more 
verbose. The second is a thread-safety issue for dynamic references. For 
example, suppose we have a dynamic optional reference in R7, i.e.:
 
    @Reference(cardinality=ReferenceCardinality.OPTIONAL, 
policy=ReferencePolicy.DYNAMIC)
    Foo foo;
 
When we want to use the field value we have to null check first, but the 
following code -- although very clear and intuitive -- is unsafe:
 
    if (foo != null) {
        foo.doSomething();
    }
 
It's unsafe because the value of the field can change between the null check 
and the invocation of the method. The following code patterns with a field of 
type Optional<Foo> are safe however:
 
    optFoo.ifPresent(Foo::doSomething)
 
or:
 
    Stream<String> barNames = optFoo.stream()
      .flatMap(foo -> foo.searchBars("*"))
      .map(Bar::toString);
 
They are safe because the value of the volatile field is only accessed once.
 
 
 
In addition to that you don't have callbacks where to get notified about 
adding, modifying or removing a service.
 
We don't have callbacks today with field injection in R7. If you want callbacks 
you need to use method injection.
 
 
 
I could imagine, to get an object similar to the promise injected, that 
supports the lifecycle callbacks, as well as resolving, unresolving or 
re-resolving as well as handling cardinality. 
 
A fluent API around the OSGi's ServiveTracker could be a solution. Injecting 
Optional for just a subset of the supported cases in DS would, from my 
perspective "pollute" the spec.
 
Maybe you can realize a custom solution using ServiceHooks?
 
I don't think that works because SCR and bnd would both have to explicitly 
understand and support fields of type Optional.
 
 
Regards,
 
Mark Hoffmann 
M.A. Dipl.-Betriebswirt (FH) 
CEO/CTO 
 
Phone: +49 3641 384 910 0 
Mobile: +49 175 701 2201 
E-Mail: m.hoffm...@data-in-motion.biz 
 
Web: www.datainmotion.de 
 
Data In Motion Consulting GmbH 
Kahlaische Strasse 4 
07745 Jena 
Germany 
 
Geschäftsführer/CEO 
Mark Hoffmann 
Jürgen Albert 
 
Jena HRB 513025 
Steuernummer 162/107/05779 
USt-Id DE310002614
 
 
-------- Ursprüngliche Nachricht --------
Von: Stefan Bischof via osgi-dev <osgi-dev@mail.osgi.org>
Datum: 22.09.20 15:48 (GMT+01:00)
An: osgi-dev@mail.osgi.org
Betreff: [osgi-dev] SCR: ServiceInjection into Fields that are Optional<Service>
 
Hi,
I like it to use Optionals if it is possible that a field could be null.
In context of OSGi Services with SCR that means I have to handle it like this:
```
@Componentpublic class MyComponent{    Optional<Foo> oFoo = Optional.empty();   
 @Reference(cardinality = ReferenceCardinality.OPTIONAL)    void bindFoo(Foo 
foo)    {        oFoo = Optional.of(foo);    }}
```
What I really want to do is this:
```
@Componentpublic class MyComponent{    @Reference    Optional<Foo> oFoo;}
```
We have something like this in OSGi - CDI Integration 
Specificationhttps://youtu.be/7-UUJ4WkMsg?t=839
It would be nice to have this feature with the new version of the R8 DS Spec.
 
Regards
Stefan_______________________________________________OSGi Developer Mail 
listosgi-...@mail.osgi.orghttps://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________OSGi Developer Mail 
listosgi-...@mail.osgi.orghttps://urldefense.proofpoint.com/v2/url?u=https-3A__mail.osgi.org_mailman_listinfo_osgi-2Ddev&d=DwICAg&c=jf_iaSHvJObTbx-siA1ZOg&r=p-HkGsKTJWWSiO-pz0kKXl8ALzmlqvUGeFfgHUZX8ms&m=yg2Dmvm8oSDM-t5yDOquKIrr878r8hZKWbEso6SAUlQ&s=QXeTnAmnmT7BVmCTIWaK8SJDQTrOxJQNLGBF01OEA9g&e=
 
 

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to