private void initDependencyManagers() { if (m_dependencyManagersInitialized) { return; } final Bundle bundle = getBundle(); if (bundle == null) { log( LogService.LOG_ERROR, "bundle shut down while trying to load implementation object class", null); throw new IllegalStateException( "bundle shut down while trying to load implementation object class"); } Class<?> implementationObjectClass; try { implementationObjectClass = bundle.loadClass(getComponentMetadata().getImplementationClassName()); } catch (ClassNotFoundException e) { log(LogService.LOG_ERROR, "Could not load implementation object class", e); throw new IllegalStateException("Could not load implementation object class"); } m_componentMethods.initComponentMethods(m_componentMetadata, implementationObjectClass); for (DependencyManager dependencyManager : m_dependencyManagers) { dependencyManager.initBindingMethods( m_componentMethods.getBindMethods(dependencyManager.getName())); } m_dependencyManagersInitialized = true; }
/** * Collect and store in m_dependencies_map all the services for dependencies, outside of any * locks. Throwing IllegalStateException on failure to collect all the dependencies is needed so * getService can know to return null. * * @return true if this thread collected the dependencies; false if some other thread successfully * collected the dependencies; * @throws IllegalStateException if some dependency is no longer available. */ protected boolean collectDependencies() throws IllegalStateException { if (m_dependenciesCollected) { log( LogService.LOG_DEBUG, "dependencies already collected, do not collect dependencies", null); return false; } initDependencyManagers(); for (DependencyManager<S, ?> dependencyManager : m_dependencyManagers) { if (!dependencyManager.prebind()) { // not actually satisfied any longer deactivateDependencyManagers(); log( LogService.LOG_DEBUG, "Could not get required dependency for dependency manager: {0}", new Object[] {dependencyManager.getName()}, null); throw new IllegalStateException("Missing dependencies, not satisfied"); } } m_dependenciesCollected = true; log(LogService.LOG_DEBUG, "This thread collected dependencies", null); return true; }
protected boolean verifyDependencyManagers() { // indicates whether all dependencies are satisfied boolean satisfied = true; for (DependencyManager<S, ?> dm : getDependencyManagers()) { if (!dm.hasGetPermission()) { // bundle has no service get permission if (dm.isOptional()) { log( LogService.LOG_DEBUG, "No permission to get optional dependency: {0}; assuming satisfied", new Object[] {dm.getName()}, null); } else { log( LogService.LOG_DEBUG, "No permission to get mandatory dependency: {0}; assuming unsatisfied", new Object[] {dm.getName()}, null); satisfied = false; } } else if (!dm.isSatisfied()) { // bundle would have permission but there are not enough services log( LogService.LOG_DEBUG, "Dependency not satisfied: {0}", new Object[] {dm.getName()}, null); satisfied = false; } } return satisfied; }
/** * We effectively maintain the set of completely processed service event tracking counts. This * method waits for all events prior to the parameter tracking count to complete, then returns. * See further documentation in EdgeInfo. * * @param trackingCount */ void waitForTracked(int trackingCount) { m_missingLock.lock(); try { while (m_ceiling < trackingCount || (!m_missing.isEmpty() && m_missing.iterator().next() < trackingCount)) { log( LogService.LOG_DEBUG, "waitForTracked trackingCount: {0} ceiling: {1} missing: {2}", new Object[] {trackingCount, m_ceiling, m_missing}, null); try { if (!doMissingWait()) { return; } } catch (InterruptedException e) { try { if (!doMissingWait()) { return; } } catch (InterruptedException e1) { log( LogService.LOG_ERROR, "waitForTracked interrupted twice: {0} ceiling: {1} missing: {2}, Expect further errors", new Object[] {trackingCount, m_ceiling, m_missing}, e1); } Thread.currentThread().interrupt(); } } } finally { m_missingLock.unlock(); } }
final void dumpThreads() { try { String dump = new ThreadDump().call(); log(LogService.LOG_DEBUG, dump, null); } catch (Throwable t) { log(LogService.LOG_DEBUG, "Could not dump threads", t); } }
protected AbstractComponentManager( BundleComponentActivator activator, ComponentMetadata metadata, ComponentMethods componentMethods, boolean factoryInstance) { m_factoryInstance = factoryInstance; m_activator = activator; m_componentMetadata = metadata; this.m_componentMethods = componentMethods; m_componentId = -1; m_dependencyManagers = loadDependencyManagers(metadata); m_stateLock = new ReentrantLock(true); // dump component details if (isLogEnabled(LogService.LOG_DEBUG)) { log( LogService.LOG_DEBUG, "Component {0} created: DS={1}, implementation={2}, immediate={3}, default-enabled={4}, factory={5}, configuration-policy={6}, activate={7}, deactivate={8}, modified={9} configuration-pid={10}", new Object[] { metadata.getName(), metadata.getNamespaceCode(), metadata.getImplementationClassName(), metadata.isImmediate(), metadata.isEnabled(), metadata.getFactoryIdentifier(), metadata.getConfigurationPolicy(), metadata.getActivate(), metadata.getDeactivate(), metadata.getModified(), metadata.getConfigurationPid() }, null); if (metadata.getServiceMetadata() != null) { log( LogService.LOG_DEBUG, "Component {0} Services: servicefactory={1}, services={2}", new Object[] { metadata.getName(), Boolean.valueOf(metadata.getServiceMetadata().isServiceFactory()), Arrays.asList(metadata.getServiceMetadata().getProvides()) }, null); } if (metadata.getProperties() != null) { log( LogService.LOG_DEBUG, "Component {0} Properties: {1}", new Object[] {metadata.getName(), metadata.getProperties()}, null); } } }
private void disableDependencyManagers() { log(LogService.LOG_DEBUG, "Disabling dependency managers", null); AtomicInteger trackingCount = new AtomicInteger(); for (DependencyManager<S, ?> dm : getDependencyManagers()) { dm.unregisterServiceListener(trackingCount); } }
private boolean hasServiceRegistrationPermissions() { boolean allowed = true; if (System.getSecurityManager() != null) { final ServiceMetadata serviceMetadata = getComponentMetadata().getServiceMetadata(); if (serviceMetadata != null) { final String[] services = serviceMetadata.getProvides(); if (services != null && services.length > 0) { final Bundle bundle = getBundle(); for (String service : services) { final Permission perm = new ServicePermission(service, ServicePermission.REGISTER); if (!bundle.hasPermission(perm)) { log( LogService.LOG_DEBUG, "Permission to register service {0} is denied", new Object[] {service}, null); allowed = false; } } } } } // no security manager or no services to register return allowed; }
private boolean doMissingWait() throws InterruptedException { if (!m_missingCondition.await(getLockTimeout(), TimeUnit.MILLISECONDS)) { log( LogService.LOG_ERROR, "waitForTracked timed out: {0} ceiling: {1} missing: {2}, Expect further errors", new Object[] {m_trackingCount, m_ceiling, m_missing}, null); dumpThreads(); m_missing.clear(); return false; } return true; }
final void doDeactivate(int reason, boolean disable) { try { if (!unregisterService()) { log(LogService.LOG_DEBUG, "Component deactivation occuring on another thread", null); } obtainStateLock("AbstractComponentManager.State.doDeactivate.1"); try { if (m_activated) { m_activated = false; deleteComponent(reason); deactivateDependencyManagers(); if (disable) { disableDependencyManagers(); } unsetDependenciesCollected(); } } finally { releaseStateLock("AbstractComponentManager.State.doDeactivate.1"); } } catch (Throwable t) { log(LogService.LOG_WARNING, "Component deactivation threw an exception", t); } }
final void enableInternal() { if (m_disposed) { throw new IllegalStateException("enable: " + this); } if (!isActivatorActive()) { log( LogService.LOG_DEBUG, "Bundle's component activator is not active; not enabling component", null); return; } registerComponentId(); // Before creating the implementation object, we are going to // test if we have configuration if such is required if (hasConfiguration() || !getComponentMetadata().isConfigurationRequired()) { // Update our target filters. log(LogService.LOG_DEBUG, "Updating target filters", null); updateTargets(getProperties()); } m_internalEnabled = true; log(LogService.LOG_DEBUG, "Component enabled", null); }
final void deactivateInternal(int reason, boolean disable, int trackingCount) { if (m_disposed) { return; } if (m_factoryInstance) { disposeInternal(reason); return; } log(LogService.LOG_DEBUG, "Deactivating component", null); // catch any problems from deleting the component to prevent the // component to remain in the deactivating state ! obtainActivationReadLock("deactivateInternal"); try { doDeactivate(reason, disable); } finally { releaseActivationReadLock("deactivateInternal"); } if (isFactory()) { clear(); } }
/** * Disposes off this component deactivating and disabling it first as required. After disposing * off the component, it may not be used anymore. * * <p>This method unlike the other state change methods immediately takes action and disposes the * component. The reason for this is, that this method has to actually complete before other * actions like bundle stopping may continue. */ final void disposeInternal(int reason) { log(LogService.LOG_DEBUG, "Disposing component (reason: " + reason + ")", null); doDeactivate(reason, true); clear(); }
final void activateInternal(int trackingCount) { log(LogService.LOG_DEBUG, "ActivateInternal", null); if (m_disposed) { log(LogService.LOG_DEBUG, "ActivateInternal: disposed", null); return; } if (m_activated) { log(LogService.LOG_DEBUG, "ActivateInternal: already activated", null); return; } if (!isEnabled()) { log(LogService.LOG_DEBUG, "Component is not enabled; not activating component", null); return; } if (!isActivatorActive()) { log( LogService.LOG_DEBUG, "Bundle's component activator is not active; not activating component", null); return; } log( LogService.LOG_DEBUG, "Activating component from state {0}", new Object[] {getState()}, null); // Before creating the implementation object, we are going to // test if we have configuration if such is required if (!hasConfiguration() && getComponentMetadata().isConfigurationRequired()) { log(LogService.LOG_DEBUG, "Missing required configuration, cannot activate", null); return; } // Before creating the implementation object, we are going to // test that the bundle has enough permissions to register services if (!hasServiceRegistrationPermissions()) { log( LogService.LOG_DEBUG, "Component is not permitted to register all services, cannot activate", null); return; } obtainActivationReadLock("activateInternal"); try { // Before creating the implementation object, we are going to // test if all the mandatory dependencies are satisfied if (!verifyDependencyManagers()) { log(LogService.LOG_DEBUG, "Not all dependencies satisfied, cannot activate", null); return; } if (!registerService()) { // some other thread is activating us, or we got concurrently deactivated. return; } if ((isImmediate() || getComponentMetadata().isFactory())) { getServiceInternal(); } } finally { releaseActivationReadLock("activateInternal"); } }
private void deactivateDependencyManagers() { log(LogService.LOG_DEBUG, "Deactivating dependency managers", null); for (DependencyManager<S, ?> dm : getDependencyManagers()) { dm.deactivate(); } }