After thinking about class loading I modified the SimpleServiceImpl so the not available class is loaded at instantiation time (sometimes I need to remember classloading mechanics)
@Component public class SimpleServiceImpl implements SimpleService { SimpleHelper helper = new SimpleHelper(); @Override public String calculateSomething(String input) { helper.doSomething(); return "SimpleServiceImpl calculated something with " + input; } } This leads to a ClassNotFoundException at activation time. But the command is executing with the one correct service. Consecutive calls to the command lead to a NoClassDefFoundError. So in that case the command execution is not avoided and the runtime does not stop. Only thing that is not nice is that the exception is raised all the time. But probably that could be avoided with a proper design. 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 Fauth Dirk (AA-AS/EIS2-EU) Gesendet: Mittwoch, 26. April 2017 08:47 An: OSGi Developer Mail List <osgi-dev@mail.osgi.org> Betreff: Re: [osgi-dev] handling optional/dynamic imports in DS 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> [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<mailto: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