Search in sources :

Example 1 with State

use of org.eclipse.osgi.container.Module.State in project rt.equinox.framework by eclipse.

the class ModuleContainer method update.

/**
 * Updates the specified module with a new revision.  The specified
 * builder is used to create a new {@link ModuleRevision revision}
 * which will become the {@link Module#getCurrentRevision() current}
 * revision of the new module.
 * @param module the module to update
 * @param builder the builder used to create the revision for the update.
 * @param revisionInfo the revision info for the new revision, may be {@code null}.
 * @throws BundleException if some error occurs updating the module
 */
public void update(Module module, ModuleRevisionBuilder builder, Object revisionInfo) throws BundleException {
    long id = builder.getId();
    ModuleRevisionBuilder adaptBuilder = getAdaptor().adaptModuleRevisionBuilder(ModuleEvent.UPDATED, module, builder, revisionInfo);
    if (adaptBuilder != null) {
        // be sure to restore the id from the original builder
        adaptBuilder.setInternalId(id);
        builder = adaptBuilder;
    }
    checkAdminPermission(module.getBundle(), AdminPermission.LIFECYCLE);
    String name = builder.getSymbolicName();
    boolean nameLocked = false;
    try {
        // Attempt to lock the name
        try {
            if (name != null && !(nameLocked = nameLocks.tryLock(name, 5, TimeUnit.SECONDS))) {
                // $NON-NLS-1$
                throw new BundleException("Failed to obtain id locks for installation.", BundleException.STATECHANGE_ERROR);
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            // $NON-NLS-1$
            throw new BundleException("Failed to obtain id locks for installation.", BundleException.STATECHANGE_ERROR, e);
        }
        Collection<Module> collisionCandidates = Collections.emptyList();
        moduleDatabase.readLock();
        try {
            // Collect existing bundles with the same name and version as the bundle we want to install
            // This is to perform the collision check below
            List<ModuleCapability> sameIdentity = moduleDatabase.findCapabilities(getIdentityRequirement(name, builder.getVersion()));
            if (!sameIdentity.isEmpty()) {
                collisionCandidates = new ArrayList<>(1);
                for (ModuleCapability identity : sameIdentity) {
                    ModuleRevision equinoxRevision = identity.getRevision();
                    if (!equinoxRevision.isCurrent())
                        continue;
                    Module m = equinoxRevision.getRevisions().getModule();
                    if (m.equals(module))
                        // don't worry about the updating modules revisions
                        continue;
                    // need to prevent duplicates here; this is in case a revisions object contains multiple revision objects.
                    if (!collisionCandidates.contains(m))
                        collisionCandidates.add(m);
                }
            }
        } finally {
            moduleDatabase.readUnlock();
        }
        // This is from the perspective of the module being updated
        if (module != null && !collisionCandidates.isEmpty()) {
            adaptor.getModuleCollisionHook().filterCollisions(ModuleCollisionHook.UPDATING, module, collisionCandidates);
        }
        if (!collisionCandidates.isEmpty()) {
            throw new BundleException(NLS.bind(Msg.ModuleContainer_NameCollision, name, builder.getVersion()), BundleException.DUPLICATE_BUNDLE_ERROR);
        }
        module.lockStateChange(ModuleEvent.UPDATED);
        State previousState;
        try {
            module.checkValid();
            previousState = module.getState();
            if (Module.ACTIVE_SET.contains(previousState)) {
                // throwing an exception from stop terminates update
                module.stop(StopOptions.TRANSIENT);
            }
            if (Module.RESOLVED_SET.contains(previousState)) {
                // set the state to installed and publish unresolved event
                module.setState(State.INSTALLED);
                adaptor.publishModuleEvent(ModuleEvent.UNRESOLVED, module, module);
            }
            moduleDatabase.update(module, builder, revisionInfo);
        } finally {
            module.unlockStateChange(ModuleEvent.UPDATED);
        }
        // only publish updated event on success
        adaptor.publishModuleEvent(ModuleEvent.UPDATED, module, module);
        if (Module.ACTIVE_SET.contains(previousState)) {
            try {
                // restart the module if necessary
                module.start(StartOptions.TRANSIENT_RESUME);
            } catch (BundleException e) {
                getAdaptor().publishContainerEvent(ContainerEvent.ERROR, module, e);
            }
        }
    } finally {
        if (nameLocked)
            nameLocks.unlock(name);
    }
}
Also used : State(org.eclipse.osgi.container.Module.State) BundleException(org.osgi.framework.BundleException)

Example 2 with State

use of org.eclipse.osgi.container.Module.State in project rt.equinox.framework by eclipse.

the class TestModuleContainer method doTestStartOnResolve.

private void doTestStartOnResolve(boolean enabled) throws BundleException, IOException {
    Map<String, String> configuration = new HashMap<String, String>();
    if (!enabled) {
        configuration.put(EquinoxConfiguration.PROP_MODULE_AUTO_START_ON_RESOLVE, Boolean.toString(false));
    }
    DummyContainerAdaptor adaptor = new DummyContainerAdaptor(new DummyCollisionHook(false), configuration);
    ModuleContainer container = adaptor.getContainer();
    // install the system.bundle
    Module systemBundle = installDummyModule("system.bundle.MF", Constants.SYSTEM_BUNDLE_LOCATION, Constants.SYSTEM_BUNDLE_SYMBOLICNAME, null, null, container);
    ResolutionReport report = container.resolve(Arrays.asList(systemBundle), true);
    Assert.assertNull("Failed to resolve system.bundle.", report.getResolutionException());
    systemBundle.start();
    // install a bunch of modules
    Map<String, String> manifest = new HashMap<String, String>();
    List<Module> modules = new ArrayList<Module>();
    for (int i = 0; i < 5; i++) {
        manifest.clear();
        manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
        manifest.put(Constants.BUNDLE_SYMBOLICNAME, "module." + i);
        manifest.put(Constants.IMPORT_PACKAGE, "export");
        Module module = installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
        try {
            module.start();
            fail("expected a bundle exception.");
        } catch (BundleException e) {
        // do nothing
        }
        modules.add(module);
    }
    manifest.clear();
    manifest.put(Constants.BUNDLE_MANIFESTVERSION, "2");
    manifest.put(Constants.BUNDLE_SYMBOLICNAME, "exporter");
    manifest.put(Constants.EXPORT_PACKAGE, "export");
    installDummyModule(manifest, manifest.get(Constants.BUNDLE_SYMBOLICNAME), container);
    report = container.resolve(Collections.<Module>emptySet(), false);
    Assert.assertNull("Found a error.", report.getResolutionException());
    State expectedState = enabled ? State.ACTIVE : State.RESOLVED;
    for (Module module : modules) {
        Assert.assertEquals("Wrong state.", expectedState, module.getState());
    }
}
Also used : HashMap(java.util.HashMap) DummyCollisionHook(org.eclipse.osgi.tests.container.dummys.DummyCollisionHook) ModuleContainer(org.eclipse.osgi.container.ModuleContainer) ArrayList(java.util.ArrayList) ResolutionReport(org.eclipse.osgi.report.resolution.ResolutionReport) DummyContainerAdaptor(org.eclipse.osgi.tests.container.dummys.DummyContainerAdaptor) State(org.eclipse.osgi.container.Module.State) BundleException(org.osgi.framework.BundleException) Module(org.eclipse.osgi.container.Module)

Example 3 with State

use of org.eclipse.osgi.container.Module.State in project rt.equinox.framework by eclipse.

the class ModuleContainer method uninstall.

/**
 * Uninstalls the specified module.
 * @param module the module to uninstall
 * @throws BundleException if some error occurs uninstalling the module
 */
public void uninstall(Module module) throws BundleException {
    checkAdminPermission(module.getBundle(), AdminPermission.LIFECYCLE);
    module.lockStateChange(ModuleEvent.UNINSTALLED);
    State previousState;
    try {
        module.checkValid();
        previousState = module.getState();
        if (Module.ACTIVE_SET.contains(module.getState())) {
            try {
                module.stop(StopOptions.TRANSIENT);
            } catch (BundleException e) {
                adaptor.publishContainerEvent(ContainerEvent.ERROR, module, e);
            }
        }
        if (Module.RESOLVED_SET.contains(previousState)) {
            // set the state to installed and publish unresolved event
            module.setState(State.INSTALLED);
            adaptor.publishModuleEvent(ModuleEvent.UNRESOLVED, module, module);
        }
        moduleDatabase.uninstall(module);
        module.setState(State.UNINSTALLED);
    } finally {
        module.unlockStateChange(ModuleEvent.UNINSTALLED);
    }
    adaptor.publishModuleEvent(ModuleEvent.UNINSTALLED, module, module);
}
Also used : State(org.eclipse.osgi.container.Module.State) BundleException(org.osgi.framework.BundleException)

Example 4 with State

use of org.eclipse.osgi.container.Module.State in project rt.equinox.framework by eclipse.

the class ModuleContainer method unresolve0.

private Collection<Module> unresolve0(Collection<Module> initial) {
    Map<ModuleRevision, ModuleWiring> wiringCopy;
    List<Module> refreshTriggers;
    Collection<ModuleRevision> toRemoveRevisions;
    Collection<ModuleWiring> toRemoveWirings;
    Map<ModuleWiring, Collection<ModuleWire>> toRemoveWireLists;
    long timestamp;
    moduleDatabase.readLock();
    try {
        checkSystemExtensionRefresh(initial);
        timestamp = moduleDatabase.getRevisionsTimestamp();
        wiringCopy = moduleDatabase.getWiringsCopy();
        refreshTriggers = new ArrayList<>(getRefreshClosure(initial, wiringCopy));
        toRemoveRevisions = new ArrayList<>();
        toRemoveWirings = new ArrayList<>();
        toRemoveWireLists = new HashMap<>();
        for (Iterator<Module> iTriggers = refreshTriggers.iterator(); iTriggers.hasNext(); ) {
            Module module = iTriggers.next();
            boolean first = true;
            for (ModuleRevision revision : module.getRevisions().getModuleRevisions()) {
                ModuleWiring removedWiring = wiringCopy.remove(revision);
                if (removedWiring != null) {
                    toRemoveWirings.add(removedWiring);
                    List<ModuleWire> removedWires = removedWiring.getRequiredModuleWires(null);
                    for (ModuleWire wire : removedWires) {
                        Collection<ModuleWire> providerWires = toRemoveWireLists.get(wire.getProviderWiring());
                        if (providerWires == null) {
                            providerWires = new ArrayList<>();
                            toRemoveWireLists.put(wire.getProviderWiring(), providerWires);
                        }
                        providerWires.add(wire);
                    }
                }
                if (!first || revision.getRevisions().isUninstalled()) {
                    toRemoveRevisions.add(revision);
                }
                first = false;
            }
            if (module.getState().equals(State.UNINSTALLED)) {
                iTriggers.remove();
            }
        }
        moduleDatabase.sortModules(refreshTriggers, Sort.BY_START_LEVEL, Sort.BY_DEPENDENCY);
    } finally {
        moduleDatabase.readUnlock();
    }
    Module systemModule = moduleDatabase.getModule(0);
    if (refreshTriggers.contains(systemModule) && Module.ACTIVE_SET.contains(systemModule.getState())) {
        refreshSystemModule();
        return Collections.emptyList();
    }
    Collection<Module> modulesLocked = new ArrayList<>(refreshTriggers.size());
    Collection<Module> modulesUnresolved = new ArrayList<>();
    try {
        // lock.
        synchronized (stateLockMonitor) {
            try {
                // go in reverse order
                for (ListIterator<Module> iTriggers = refreshTriggers.listIterator(refreshTriggers.size()); iTriggers.hasPrevious(); ) {
                    Module refreshModule = iTriggers.previous();
                    refreshModule.lockStateChange(ModuleEvent.UNRESOLVED);
                    modulesLocked.add(refreshModule);
                }
            } catch (BundleException e) {
                // TODO throw some appropriate exception
                throw new IllegalStateException(Msg.ModuleContainer_StateLockError, e);
            }
        }
        // Stop any active bundles and remove non-active modules from the refreshTriggers
        for (ListIterator<Module> iTriggers = refreshTriggers.listIterator(refreshTriggers.size()); iTriggers.hasPrevious(); ) {
            Module refreshModule = iTriggers.previous();
            State previousState = refreshModule.getState();
            if (Module.ACTIVE_SET.contains(previousState)) {
                try {
                    refreshModule.stop(StopOptions.TRANSIENT);
                } catch (BundleException e) {
                    adaptor.publishContainerEvent(ContainerEvent.ERROR, refreshModule, e);
                }
            } else {
                iTriggers.remove();
            }
        }
        // do a sanity check on states of the modules, they must be INSTALLED, RESOLVED or UNINSTALLED
        for (Module module : modulesLocked) {
            if (Module.ACTIVE_SET.contains(module.getState())) {
                // $NON-NLS-1$ //$NON-NLS-2$
                throw new IllegalStateException("Module is in the wrong state: " + module + ": " + module.getState());
            }
        }
        // finally apply the unresolve to the database
        moduleDatabase.writeLock();
        try {
            if (timestamp != moduleDatabase.getRevisionsTimestamp())
                // need to try again
                return null;
            // remove any wires from unresolved wirings that got removed
            for (Map.Entry<ModuleWiring, Collection<ModuleWire>> entry : toRemoveWireLists.entrySet()) {
                List<ModuleWire> provided = entry.getKey().getProvidedModuleWires(null);
                provided.removeAll(entry.getValue());
                entry.getKey().setProvidedWires(provided);
                for (ModuleWire removedWire : entry.getValue()) {
                    // invalidate the wire
                    removedWire.invalidate();
                }
            }
            // remove any revisions that got removed as part of the refresh
            for (ModuleRevision removed : toRemoveRevisions) {
                removed.getRevisions().removeRevision(removed);
                moduleDatabase.removeCapabilities(removed);
            }
            // invalidate any removed wiring objects
            for (ModuleWiring moduleWiring : toRemoveWirings) {
                moduleWiring.invalidate();
            }
            moduleDatabase.setWiring(wiringCopy);
            // check for any removal pendings
            moduleDatabase.cleanupRemovalPending();
        } finally {
            moduleDatabase.writeUnlock();
        }
        // set the state of modules to unresolved
        for (Module module : modulesLocked) {
            if (State.RESOLVED.equals(module.getState())) {
                module.setState(State.INSTALLED);
                modulesUnresolved.add(module);
            }
        }
    } finally {
        for (Module module : modulesLocked) {
            module.unlockStateChange(ModuleEvent.UNRESOLVED);
        }
    }
    // publish unresolved events after giving up all locks
    for (Module module : modulesUnresolved) {
        adaptor.publishModuleEvent(ModuleEvent.UNRESOLVED, module, module);
    }
    return refreshTriggers;
}
Also used : ArrayList(java.util.ArrayList) BundleException(org.osgi.framework.BundleException) State(org.eclipse.osgi.container.Module.State) Collection(java.util.Collection) Map(java.util.Map) HashMap(java.util.HashMap) CopyOnWriteIdentityMap(org.eclipse.osgi.framework.eventmgr.CopyOnWriteIdentityMap)

Aggregations

State (org.eclipse.osgi.container.Module.State)4 BundleException (org.osgi.framework.BundleException)4 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 Collection (java.util.Collection)1 Map (java.util.Map)1 Module (org.eclipse.osgi.container.Module)1 ModuleContainer (org.eclipse.osgi.container.ModuleContainer)1 CopyOnWriteIdentityMap (org.eclipse.osgi.framework.eventmgr.CopyOnWriteIdentityMap)1 ResolutionReport (org.eclipse.osgi.report.resolution.ResolutionReport)1 DummyCollisionHook (org.eclipse.osgi.tests.container.dummys.DummyCollisionHook)1 DummyContainerAdaptor (org.eclipse.osgi.tests.container.dummys.DummyContainerAdaptor)1