Christian Schneider created FELIX-5749:
------------------------------------------

             Summary: 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 DS. 

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 package:

@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
(v6.4.14#64029)

Reply via email to