Details
-
Bug
-
Status: Resolved
-
Minor
-
Resolution: Fixed
-
None
-
None
-
None
Description
During the activate() the FST Linking Engine Component opens an OSGI ServiceTracker for the configured SolrCore (used for FST linking).
However this activation might end in a RuntimeException in some cases (e.g. if the core is not valid or in the listing below the directory for the FST models is not existent and can not be created.
Unable to create Directory forstoring the FST files at location '/<path>/data/fst'.) java.lang.IllegalStateException: Unable to create Directory forstoring the FST files at location '/<path>/data/fst'. at org.apache.stanbol.enhancer.engines.lucenefstlinking.FstLinkingEngineComponent.getFstDirectory(FstLinkingEngineComponent.java:857) at org.apache.stanbol.enhancer.engines.lucenefstlinking.FstLinkingEngineComponent.updateEngineRegistration(FstLinkingEngineComponent.java:752) at org.apache.stanbol.enhancer.engines.lucenefstlinking.FstLinkingEngineComponent$1.addingService(FstLinkingEngineComponent.java:686) at org.apache.stanbol.enhancer.engines.lucenefstlinking.FstLinkingEngineComponent$1.addingService(FstLinkingEngineComponent.java:660) at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:932) at org.osgi.util.tracker.ServiceTracker$Tracked.customizerAdding(ServiceTracker.java:864) at org.osgi.util.tracker.AbstractTracked.trackAdding(AbstractTracked.java:256) at org.osgi.util.tracker.AbstractTracked.trackInitial(AbstractTracked.java:183) at org.osgi.util.tracker.ServiceTracker.open(ServiceTracker.java:317) at org.apache.stanbol.commons.solr.RegisteredSolrServerTracker.open(RegisteredSolrServerTracker.java:114) at org.apache.stanbol.enhancer.engines.lucenefstlinking.FstLinkingEngineComponent.applyConfig(FstLinkingEngineComponent.java:694) at org.apache.stanbol.enhancer.engines.lucenefstlinking.FstLinkingEngineComponent.activate(FstLinkingEngineComponent.java:361) [..]
Important to note is that the a SolrCore that is already registered as Service is directly added to the ServiceTracker within the thread context of the activate() call to the FstLinkingEngineComponent. So any Exception during this registration (that also triggers the configuration of the FstLinkingEngine) can still fail the activation of the FstLinkingEngineComponent.
If this happens the component is in an invalid state:
- OSGI lists the component as 'unsatisfied'
- The ServiceTracker is still open (and active)
So what can happen is that the tracked SolrCore is updated. In this case the 'unsatisfied' component processes the event and - if successful - registers a FstLinkingEngine as OSGI service.
However even so the component itself will still be in the 'unsatisfied'. So if their is an update to the FstLinkingEngineComponent configuration OSGI will NOT call deactivate().
Because of that the FstLinkingEngine service registered by the unsatisfied component will never get unregistered and one can end up with multiple Services registered for the same component configuration. For the FstLinkingEngine this means that one will have two EnhancementEngine Instances for the same configuration.
Most likely they will have the same name. In such cases the Enhancer will always use the instance with the higher service.ranking. If those are the same - expected in such a scenario - it will select the service with the lower service id. As OSGI increases the service id for every service that get registered the older service instance will get use by the enhancer.
This means that the service registered by the unsatisfied Component instance will get used as it does have the lower service id.
To solve this situation it is necessary to stop/start the FST linking bundle. This is the only possibility to cause the removal of service as OSGI keeps track what bundles do register Services.
To fix this issue it is necessary to catch any Exception thrown during the ServiceTracker.open() call. Even in case of an Exception the tracker keeps listening to further service event. So a later event might trigger the correct initialization of the FstLinkingEngine. Catching the Exception ensures that the FstLinkingEngineComponent is in the 'active' state and OSGI calls deactivate() to unregister any FstLinkingEngine service and close the ServiceTracker.