Hi,

not sure if this answers your question, but actually I thought of something 
similar for the Eclipse Platform Runtime.

The issue I am seeing there is probably an incorrect bundle design where 
service interfaces and default implementations of the services are in one 
bundle. Well, it could be discussed if this is sometimes ok, but that should 
not be part of this discussion. In the end it would not be an issue when the 
services are referenced dynamic greedy so one could simple register a service 
with a higher ranking to override the default.

The bad thing at the moment is that some of these service implementations are 
dependent on Equinox, as they use classes from the org.eclipse.osgi.service.* 
packages. With non-optional Import-Package statements that means the Eclipse 
Platform Runtime needs Equinox OSGi to run. From my point of view that 
dependency is too strict for that project and it should be possible to also 
start it with another OSGi implementation.

Therefore I was thinking about making these imports optional, so the bundles at 
least start without throwing wiring errors. It would of course mean on the 
other hand that those default service implementations are not getting activated 
because the required classes are not found. But that could be solved afterwards 
by adaptors that want to run on a different OSGi implementation.

But even a simple test turned out that this is not working as intended. SCR 
loads the XML and even activates the component. At execution time of the 
service there is a NoClassDefFoundError. The expectation (even from BJ’s 
answer) would be that SCR does not even activate the service implementation 
because the class cannot be loaded.

I created the following test scenario:

Bundle: org.fipro.test.helper
Public Package: org.fipro.test.helper
Helper-Class:
public class SimpleHelper {

       public static void doSomething() {
             System.out.println("do something");
       }
}

Bundle: org.fipro.test.service
Private Package: org.fipro.test.service
Import-Package: org.fipro.test.helper (optional)

public interface SimpleService {

       String calculateSomething(String input);
}

@Component
public class SimpleServiceImpl implements SimpleService {

       @Override
       public String calculateSomething(String input) {
             SimpleHelper.doSomething();
             return "SimpleServiceImpl calculated something with " + input;
       }

}

@Component
public class TestServiceImpl implements SimpleService {

       @Override
       public String calculateSomething(String input) {
             return "TestServiceImpl calculated something with " + input;
       }

}

@Component(
             property= {
                           "osgi.command.scope:String=fipro",
                           "osgi.command.function:String=simple"
                    },
                    service=SimpleServiceCommand.class)
public class SimpleServiceCommand {

       @Reference
       List<SimpleService> services;

       public void simple(String input) {
             System.out.println("number of services: " + services.size());
             services.forEach(s -> s.calculateSomething(input));
       }
}

Start the test without the bundle org.fipro.test.helper. The startup is fine, 
because the org.fipro.test.helper package import is optional. Calling the 
command “simple test” does not execute because of the NoClassDefFoundError 
underneath.

I also modified the example for service references. So I created a service 
interface in org.fipro.test.helper

public interface OtherService {

}

Then I added a service reference to the SimpleServiceImpl

@Component
public class SimpleServiceImpl implements SimpleService {

       @Reference
       OtherService blubb;

       @Override
       public String calculateSomething(String input) {
             SimpleHelper.doSomething();
             return "SimpleServiceImpl calculated something with " + input;
       }

}

This way SimpleServiceImpl is not started because it cannot be satisified. Fine 
so far. But a strange effect is coming up when changing the reference to an 
OPTIONAL cardinality. In that case a NullPointerException is thrown in 
FieldHandler#validateField()


For the Eclipse Platform Runtime scenario one could argue that using 
service.ranking and single service references are suitable and it should work. 
Especially for mandatory service references it should be ok. But the optional 
dependencies for services does not seem to be working as expected from the 
initial question.

But I have to admit that I am not sure if my test scenario is itself a good one 
because of the static helper.

Mit freundlichen Grüßen / Best regards

Dirk Fauth

Automotive Service Solutions, ESI application (AA-AS/EIS2-EU)
Robert Bosch GmbH | Postfach 11 29 | 73201 Plochingen | GERMANY | 
www.bosch.com<http://www.bosch.com>
Tel. +49(7153)666-1155 | dirk.fa...@de.bosch.com<mailto:dirk.fa...@de.bosch.com>

Sitz: Stuttgart, Registergericht: Amtsgericht Stuttgart, HRB 14000;
Aufsichtsratsvorsitzender: Franz Fehrenbach; Geschäftsführung: Dr. Volkmar 
Denner,
Prof. Dr. Stefan Asenkerschbaumer, Dr. Rolf Bulander, Dr. Stefan Hartung, Dr. 
Markus Heyn, Dr. Dirk Hoheisel,
Christoph Kübel, Uwe Raschke, Peter Tyroller


Von: osgi-dev-boun...@mail.osgi.org [mailto:osgi-dev-boun...@mail.osgi.org] Im 
Auftrag von Felix Meschberger
Gesendet: Mittwoch, 26. April 2017 04:14
An: OSGi Developer Mail List <osgi-dev@mail.osgi.org>
Betreff: Re: [osgi-dev] handling optional/dynamic imports in DS

My understanding is as well that this is exactly how DS works.

 But I think Rays question goes further into supporting situations in a way 
that a component activates and registers dynamically depending on what service 
interface is actually available.

I think this does not work with plain DS but requires additional logic to check 
for wires and/or trying to load classes. The Apache Felix 
ScrServiceServiceFactory does this being registered as a ServiceFactory by the 
BundleActivator ScrConfiguration. The latter could be a component (here it is a 
BundleActivator because this is the DS implementation itself).

Yet this is really a special case of a situation which is not covered by DS and 
which probably is outside of the scope of DS' charter.

Regards
Felix

--
Creative typing support courtesy of my iPhone

Am 25.04.2017 um 15:47 schrieb BJ Hargrave 
<hargr...@us.ibm.com<mailto:hargr...@us.ibm.com>>:
So why isn't this just the case already? SCR processes the XML, cannot load the 
impl class and logs that in the log. End of story. When bundle resolves again 
later and can access the class, when SCR processes the XML, it can load the 
impl class and thus the component is good to go.
--

BJ Hargrave
Senior Technical Staff Member, IBM // office: +1 386 848 1781
OSGi Fellow and CTO of the OSGi Alliance // mobile: +1 386 848 3788
hargr...@us.ibm.com<mailto:hargr...@us.ibm.com>


----- Original message -----
From: Raymond Auge <raymond.a...@liferay.com<mailto:raymond.a...@liferay.com>>
Sent by: osgi-dev-boun...@mail.osgi.org<mailto:osgi-dev-boun...@mail.osgi.org>
To: OSGi Developer Mail List 
<osgi-dev@mail.osgi.org<mailto:osgi-dev@mail.osgi.org>>
Cc:
Subject: Re: [osgi-dev] handling optional/dynamic imports in DS
Date: Tue, Apr 25, 2017 6:20 PM



On Tue, Apr 25, 2017 at 6:16 PM, Christian Schneider 
<ch...@die-schneider.net<mailto:ch...@die-schneider.net>> wrote:
Not sure if that is possible...

I think it would be awesome if the DS runtime could try to load the component 
class and if it fails because of an unwired package
it could simply choose to not instantiate the component. It could also report 
this problem when you look into the components from the shell.

When the bundle is then refreshed later it could try the same again and maybe 
succeed if the package is wired now.
The big advantage would be that the user would not have to code anything to 
make this work.
Currently handling optional imports using an Activator is quite difficult and 
error prone.

Does that make sense?

I totally agree!

- Ray


Christian



On 26.04.2017 00:06, Raymond Auge wrote:
You're not far off,

but clearly the component could not be implementing the missing package...

Let's say we have an API:

interface com.foo.Provider {
    public void provide();
}

a bundle wants to provide an implementation of this API:

@Component
class FancyProviderImpl implements com.foo.Provider { ... }

However the goal of FancyProviderImpl is to deliver functionality by using 
fancy-lib.jar which is a second bundle.

e.g.

import fancy.lib.Thing;
@Component
class FancyProviderImpl implements com.foo.Provider {
    public void provide() {
        new Thing().doSomethingFancy();
    }
}

I'd like for the bundle containing FancyProviderImpl to have an optional import 
on `fancy.lib`, and not blow up when `fancy-lib.jar` is not deployed. Exactly 
the same scenario you mentioned with configAdmin, metatype and SCR.

I hope that makes sense,
- Ray


On Tue, Apr 25, 2017 at 5:51 PM, Felix Meschberger 
<fmesc...@adobe.com<mailto:fmesc...@adobe.com>> wrote:
Hi Ray

I am not sure, I understand the question.

Are you asking that the component dynamically decides to register as a certain 
service depending on the whether a certain package is wired ?

I think that does not work as the component implements an interface which is 
the service name and the component class can only be loaded if the class object 
representing the interface being implemented is accessible, otherwise a Linkage 
error occurrs.

Or may I am on the wrong track alltogether.

Regards
Felix

Am 25.04.2017 um 14:46 schrieb Raymond Auge 
<raymond.a...@liferay.com<mailto:raymond.a...@liferay.com>>:

Thank you Felix, I agree and understand all of what you are saying.

However, what I'm wondering though is if anyone has come up with a design 
pattern where a DS component can determine programmatically whether it (or a 
peer component it controls) should be provided as a service based on the check 
for some optional package.

Sincerely,
- Ray

On Tue, Apr 25, 2017 at 5:33 PM, Felix Meschberger 
<fmesc...@adobe.com<mailto:fmesc...@adobe.com>> wrote:
Hi

You mean dynamic imports due to optional dependencies ?

I think the key is to limit them. If I remember correctly I have (or had) some 
of this in the Apache Felix SCR implementation around the Metatype and 
Configuration Admin dependencies.

What I do is I hand-craft a DynamicImport-Package statement for the exact 
package along with the packages import version range. Then, unless the service 
is provided, the package may not be resolved.

I generally also have fields, but as long as I don’t access that field other 
than checking for null, the dependency is not needed either.

This works great, but I try to reduce such uses to the absolute minimum because 
it involves manual work.

Hope this helps

Regards
Felix

Am 25.04.2017 um 14:10 schrieb Raymond Auge 
<raymond.a...@liferay.com<mailto:raymond.a...@liferay.com>>:
I'm wondering if there is a reasonable model for handling optional or dynamic 
package imports in DS.

While optionality at the package level is not an ideal model, sometimes it 
can't be avoided.

I'd like to know if others have come across a "reasonable" way to model this in 
DS.

Sincerely,
--
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<mailto:osgi-dev@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<mailto: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<mailto:osgi-dev@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<mailto: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<mailto:osgi-dev@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev



--
Christian Schneider
http://www.liquid-reality.de

Open Source Architect
http://www.talend.com

_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<mailto: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<mailto:osgi-dev@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev


_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<mailto: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

Reply via email to