felix-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Robert Munteanu (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (FELIX-5749) Allow to use components that depend on optional imports
Date Tue, 21 Nov 2017 15:31:00 GMT

    [ https://issues.apache.org/jira/browse/FELIX-5749?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16260906#comment-16260906

Robert Munteanu commented on FELIX-5749:

For me the scenario is the following:

Bundle A, with an optional import on {{com.example.foo}}.

In Bundle A, declare the following component

public class Component {
   private @Reference SomeService service;
   private @Reference(cardinality = OPTIONAL_UNARY ) private com.example.foo.BarService bar;

The intention is for the component to work without a reference to {{BarService}}, even when
the optional import is not satisfied. That is not the case today, since - IIUC - a failure
in looking up any bind method results in the component not being registered - or at least
logging a WARN message.

> Allow to use components that depend on optional imports
> -------------------------------------------------------
>                 Key: FELIX-5749
>                 URL: https://issues.apache.org/jira/browse/FELIX-5749
>             Project: Felix
>          Issue Type: New Feature
>    Affects Versions: scr-2.0.12
>            Reporter: Christian Schneider
> When desigining the scope of a bundle you sometimes have an optional part that could
be externalized into its own bundle but you decide to keep it in your bundle to limit the
number of bundles. In this case you have to use an optional import and make sure the code
that depends on this import only runs when this import is wired. This code is often quite
awkward and often also buggy.
> We discussed on osgi-dev that you can make such code a lot simpler to write by using
> This is how the code would look like:
> You externalize the code that depends on the optional import into one or more components.
These components offer a service interface that is not dependent on the optional import. Inside
the component you can work freely with the optional packages. You have to make sure this component
is disabled by default. Then you write a "starter" component that enables the component if
the package is available.
> I think scr could support such "optional" components without the disabled trick. We could
load the component class and if it fails disable the component. If it works we enable it.

> So if the package is wired later and we get a refresh this approach would activate the
component without any additional effort from the developer side.
> ----
> Below I am copying a snippet from Ray that details what they did.
> Given your component which has the optional import package (doesn't matter how it's used):
> import com.liferay.demo.foo.Foo; // The optional package
> @Component(
>     enabled = false // disable by default so DS ignores it
> )
> public class OptionalPackageConsumer implements Foo {...}
> Make sure the component is disabled by default. This will prevent SCR from classloading
the component class.
> Second, you construct a "starter" component who's job it is to check for the available
> @Component
> public class OptionalPackageConsumerStarter {
>    @Activate
>     void activate(ComponentContext componentContext) {
>         try {
>             Class.forName(com.liferay.demo.foo.Foo.class.getName());
>             componentContext.enableComponent(OptionalPackageConsumer.class.getName());
>         }
>         catch (Throwable t) {
>             _log.warn("Could not find {}", t.getMessage());
>         }
>     }
> }

This message was sent by Atlassian JIRA

View raw message