use of org.osgi.service.resolver.ResolutionException in project felix by apache.
the class Felix method init.
/**
* @see org.osgi.framework.launch.Framework#init(org.osgi.framework.FrameworkListener[])
*/
@Override
public void init(final FrameworkListener... listeners) throws BundleException {
// The system bundle can only be initialized if it currently isn't started.
acquireBundleLock(this, Bundle.INSTALLED | Bundle.RESOLVED | Bundle.STARTING | Bundle.ACTIVE);
try {
if ((getState() == Bundle.INSTALLED) || (getState() == Bundle.RESOLVED)) {
String security = (String) m_configMap.get(Constants.FRAMEWORK_SECURITY);
if (security != null) {
if (System.getSecurityManager() != null) {
throw new SecurityException("SecurityManager already installed");
}
security = security.trim();
if (Constants.FRAMEWORK_SECURITY_OSGI.equalsIgnoreCase(security) || (security.length() == 0)) {
System.setSecurityManager(m_securityManager = new SecurityManager());
} else {
try {
System.setSecurityManager(m_securityManager = (SecurityManager) Class.forName(security).newInstance());
} catch (Throwable t) {
SecurityException se = new SecurityException("Unable to install custom SecurityManager: " + security);
se.initCause(t);
throw se;
}
}
}
// Generate a framework UUID.
// Spec says we get a new UUID for each invocation of init().
m_configMutableMap.put(FelixConstants.FRAMEWORK_UUID, Util.randomUUID());
// Initialize event dispatcher.
m_dispatcher.startDispatching();
// Create the bundle cache, if necessary, so that we can reload any
// installed bundles.
m_cache = (BundleCache) m_configMutableMap.get(FelixConstants.FRAMEWORK_BUNDLECACHE_IMPL);
if (m_cache == null) {
try {
m_cache = new BundleCache(m_logger, m_configMap);
} catch (Exception ex) {
m_logger.log(Logger.LOG_ERROR, "Error creating bundle cache.", ex);
throw new BundleException("Error creating bundle cache.", ex);
}
}
// we need to flush the bundle cache.
if (getState() == Bundle.INSTALLED) {
String clean = (String) m_configMap.get(Constants.FRAMEWORK_STORAGE_CLEAN);
if ((clean != null) && clean.equalsIgnoreCase(Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT)) {
try {
m_cache.delete();
} catch (Exception ex) {
throw new BundleException("Unable to flush bundle cache.", ex);
}
}
}
// Initialize installed bundle data structures.
Map[] maps = new Map[] { new HashMap<String, BundleImpl>(1), new TreeMap<Long, BundleImpl>() };
m_uninstalledBundles = new ArrayList<BundleImpl>(0);
// Add the system bundle to the set of installed bundles.
maps[LOCATION_MAP_IDX].put(_getLocation(), this);
maps[IDENTIFIER_MAP_IDX].put(new Long(0), this);
m_installedBundles = maps;
// state to be set to RESOLVED.
try {
m_resolver.resolve(Collections.singleton(adapt(BundleRevision.class)), Collections.EMPTY_SET);
} catch (ResolutionException ex) {
// This should never happen.
throw new BundleException("Unresolved constraint in System Bundle:" + ex.getUnresolvedRequirements());
}
// Reload the cached bundles before creating and starting the
// system bundle, since we want all cached bundles to be reloaded
// when we activate the system bundle and any subsequent system
// bundle activators passed into the framework constructor.
BundleArchive[] archives = null;
// First get cached bundle identifiers.
try {
archives = m_cache.getArchives();
} catch (Exception ex) {
m_logger.log(Logger.LOG_ERROR, "Unable to list saved bundles.", ex);
archives = null;
}
// Create system bundle activator and bundle context so we can activate it.
setActivator(new SystemBundleActivator());
setBundleContext(new BundleContextImpl(m_logger, this, this));
boolean javaVersionChanged = handleJavaVersionChange();
// Now load all cached bundles.
for (int i = 0; (archives != null) && (i < archives.length); i++) {
try {
// Keep track of the max bundle ID currently in use since we
// will need to use this as our next bundle ID value if the
// persisted value cannot be read.
m_nextId = Math.max(m_nextId, archives[i].getId() + 1);
// it now.
if (archives[i].getPersistentState() == Bundle.UNINSTALLED) {
archives[i].closeAndDelete();
} else // Otherwise re-install the cached bundle.
{
// Install the cached bundle.
reloadBundle(archives[i], javaVersionChanged);
}
} catch (Exception ex) {
fireFrameworkEvent(FrameworkEvent.ERROR, this, ex);
try {
m_logger.log(Logger.LOG_ERROR, "Unable to re-install " + archives[i].getLocation(), ex);
} catch (Exception ex2) {
m_logger.log(Logger.LOG_ERROR, "Unable to re-install cached bundle.", ex);
}
// TODO: FRAMEWORK - Perhaps we should remove the cached bundle?
}
}
for (Bundle extension : m_extensionManager.resolveExtensionBundles(this)) {
m_extensionManager.startExtensionBundle(this, (BundleImpl) extension);
}
// Now that we have loaded all cached bundles and have determined the
// max bundle ID of cached bundles, we need to try to load the next
// bundle ID from persistent storage. In case of failure, we should
// keep the max value.
m_nextId = Math.max(m_nextId, loadNextId());
// The framework is now in its startup sequence.
setBundleStateAndNotify(this, Bundle.STARTING);
// Now it is possible for threads to wait for the framework to stop,
// so create a gate for that purpose.
m_shutdownGate = new ThreadGate();
// add framework listeners
if (listeners != null) {
for (final FrameworkListener fl : listeners) {
addFrameworkListener(this, fl);
}
}
// Start services
m_resolver.start();
m_fwkWiring.start();
m_fwkStartLevel.start();
try {
Felix.m_secureAction.startActivator(getActivator(), _getBundleContext());
} catch (Throwable ex) {
m_dispatcher.stopDispatching();
m_logger.log(Logger.LOG_ERROR, "Unable to start system bundle.", ex);
throw new RuntimeException("Unable to start system bundle.");
}
// We have to check with the security provider (if there is one).
// This is to avoid having bundles in the cache that have been tampered with
SecurityProvider sp = getFramework().getSecurityProvider();
if ((sp != null) && (System.getSecurityManager() != null)) {
boolean locked = acquireGlobalLock();
if (!locked) {
throw new BundleException("Unable to acquire the global lock to check the bundle.");
}
try {
for (Object bundle : m_installedBundles[IDENTIFIER_MAP_IDX].values()) {
try {
if (bundle != this) {
setBundleProtectionDomain(((BundleImpl) bundle).adapt(BundleRevisionImpl.class));
}
} catch (Exception ex) {
((BundleImpl) bundle).close();
maps = new Map[] { new HashMap<String, BundleImpl>(m_installedBundles[LOCATION_MAP_IDX]), new TreeMap<Long, BundleImpl>(m_installedBundles[IDENTIFIER_MAP_IDX]) };
maps[LOCATION_MAP_IDX].remove(((BundleImpl) bundle)._getLocation());
maps[IDENTIFIER_MAP_IDX].remove(new Long(((BundleImpl) bundle).getBundleId()));
m_installedBundles = maps;
m_logger.log(Logger.LOG_ERROR, "Bundle in cache doesn't pass security check anymore.", ex);
}
}
} finally {
// Always release the global lock.
releaseGlobalLock();
}
}
m_extensionManager.startPendingExtensionBundles(Felix.this);
m_fwkWiring.refreshBundles(null);
// up class lookup for the system bundle.
synchronized (m_systemBundleClassCache) {
m_systemBundleClassCache.clear();
}
}
} finally {
releaseBundleLock(this);
if (listeners != null) {
for (final FrameworkListener fl : listeners) {
removeFrameworkListener(this, fl);
}
}
}
}
use of org.osgi.service.resolver.ResolutionException in project felix by apache.
the class Felix method resolveBundles.
boolean resolveBundles(Collection<Bundle> targets) {
// Acquire global lock.
boolean locked = acquireGlobalLock();
if (!locked) {
m_logger.log(Logger.LOG_WARNING, "Unable to acquire global lock to perform resolve.", null);
return false;
}
try {
// Remember original targets.
Collection<Bundle> originalTargets = targets;
// specified bundles or all bundles if null.
if (targets == null) {
// Add all bundles to the list.
targets = m_installedBundles[LOCATION_MAP_IDX].values();
}
// Now resolve each target bundle.
boolean result = true;
// If there are targets, then resolve each one.
if (!targets.isEmpty()) {
// Get bundle revisions for bundles in INSTALLED state.
Set<BundleRevision> revisions = new HashSet<BundleRevision>(targets.size());
for (Bundle b : targets) {
if (b.getState() != Bundle.UNINSTALLED) {
revisions.add(b.adapt(BundleRevision.class));
}
}
// the return result will be false regardless.
if ((originalTargets != null) && (originalTargets.size() != revisions.size())) {
result = false;
}
try {
m_resolver.resolve(Collections.EMPTY_SET, revisions);
if (result) {
for (BundleRevision br : revisions) {
if (br.getWiring() == null) {
result = false;
break;
}
}
}
} catch (ResolutionException ex) {
result = false;
} catch (BundleException ex) {
result = false;
}
}
return result;
} finally {
// Always release the global lock.
releaseGlobalLock();
}
}
use of org.osgi.service.resolver.ResolutionException in project felix by apache.
the class StatefulResolver method resolve.
BundleRevision resolve(BundleRevision revision, String pkgName) throws ResolutionException, BundleException {
BundleRevision provider = null;
// acquired the global lock below.
if ((revision.getWiring() != null) && isAllowedDynamicImport(revision, pkgName)) {
// Acquire global lock.
boolean locked = m_felix.acquireGlobalLock();
if (!locked) {
throw new ResolveException("Unable to acquire global lock for resolve.", revision, null);
}
// the case if a resolver hook does something bad.
if (m_isResolving) {
m_felix.releaseGlobalLock();
throw new IllegalStateException("Nested resolve operations not allowed.");
}
m_isResolving = true;
Map<Resource, List<Wire>> wireMap = null;
try {
// Double check to make sure that someone hasn't beaten us to
// dynamically importing the package, which can happen if two
// threads are racing to do so. If we have an existing wire,
// then just return it instead.
provider = ((BundleWiringImpl) revision.getWiring()).getImportedPackageSource(pkgName);
if (provider == null) {
// Prepare resolver hooks, if any.
ResolverHookRecord record = prepareResolverHooks(Collections.singleton(revision), Collections.EMPTY_SET);
// Select any singletons in the resolver state.
selectSingletons(record);
// Catch any resolve exception to rethrow later because
// we may need to call end() on resolver hooks.
ResolutionException rethrow = null;
try {
List<BundleRequirement> dynamics = Util.getDynamicRequirements(revision.getWiring().getRequirements(null));
// Loop through the importer's dynamic requirements to determine if
// there is a matching one for the package from which we want to
// load a class.
Map<String, Object> attrs = Collections.singletonMap(BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
BundleRequirementImpl req = new BundleRequirementImpl(revision, BundleRevision.PACKAGE_NAMESPACE, Collections.EMPTY_MAP, attrs);
final List<BundleCapability> candidates = findProvidersInternal(record, req, false, true);
// Try to find a dynamic requirement that matches the capabilities.
BundleRequirementImpl dynReq = null;
for (int dynIdx = 0; (candidates.size() > 0) && (dynReq == null) && (dynIdx < dynamics.size()); dynIdx++) {
for (Iterator<BundleCapability> itCand = candidates.iterator(); (dynReq == null) && itCand.hasNext(); ) {
Capability cap = itCand.next();
if (CapabilitySet.matches(cap, ((BundleRequirementImpl) dynamics.get(dynIdx)).getFilter())) {
dynReq = (BundleRequirementImpl) dynamics.get(dynIdx);
}
}
}
// any candidates that do not match it.
if (dynReq != null) {
for (Iterator<BundleCapability> itCand = candidates.iterator(); itCand.hasNext(); ) {
Capability cap = itCand.next();
if (!CapabilitySet.matches(cap, dynReq.getFilter())) {
itCand.remove();
}
}
} else {
candidates.clear();
}
Map<Resource, Wiring> wirings = getWirings();
wireMap = wirings.containsKey(revision) ? m_resolver.resolveDynamic(new ResolveContextImpl(this, wirings, record, Collections.<BundleRevision>emptyList(), Collections.<BundleRevision>emptyList(), getFragments()) {
@Override
public List<Capability> findProviders(Requirement br) {
return (List) candidates;
}
}, revision.getWiring(), dynReq) : Collections.<Resource, List<Wire>>emptyMap();
} catch (ResolutionException ex) {
rethrow = ex;
}
// Release resolver hooks, if any.
releaseResolverHooks(record);
// If the resolve failed, rethrow the exception.
if (rethrow != null) {
throw rethrow;
}
if ((wireMap != null) && wireMap.containsKey(revision)) {
List<Wire> dynamicWires = wireMap.remove(revision);
Wire dynamicWire = dynamicWires.get(0);
// Mark all revisions as resolved.
markResolvedRevisions(wireMap);
// Dynamically add new wire to importing revision.
if (dynamicWire != null) {
// TODO can we optimize this?
if (dynamicWire.getRequirer() instanceof BundleRevision && dynamicWire.getRequirement() instanceof BundleRequirement && dynamicWire.getProvider() instanceof BundleRevision && dynamicWire.getCapability() instanceof BundleCapability) {
BundleRevision dwRequirer = (BundleRevision) dynamicWire.getRequirer();
BundleRequirement dwRequirement = (BundleRequirement) dynamicWire.getRequirement();
BundleRevision dwProvider = (BundleRevision) dynamicWire.getProvider();
BundleCapability dwCapability = (BundleCapability) dynamicWire.getCapability();
BundleWire bw = new BundleWireImpl(dwRequirer, dwRequirement, dwProvider, dwCapability);
m_felix.getDependencies().addDependent(bw);
((BundleWiringImpl) revision.getWiring()).addDynamicWire(bw);
m_felix.getLogger().log(Logger.LOG_DEBUG, "DYNAMIC WIRE: " + dynamicWire);
provider = ((BundleWiringImpl) revision.getWiring()).getImportedPackageSource(pkgName);
}
}
}
}
} finally {
// Clear resolving flag.
m_isResolving = false;
// Always release the global lock.
m_felix.releaseGlobalLock();
}
fireResolvedEvents(wireMap);
}
return provider;
}
use of org.osgi.service.resolver.ResolutionException in project bnd by bndtools.
the class ResolveProcess method augment.
private static ResolutionException augment(Collection<Requirement> unresolved, ResolveContext context, ResolutionException re) {
if (unresolved.isEmpty()) {
return re;
}
long deadline = System.currentTimeMillis() + 1000L;
Set<Requirement> list = new HashSet<>(unresolved);
Set<Resource> resources = new HashSet<>();
try {
for (Requirement r : unresolved) {
Requirement find = missing(context, r, resources, deadline);
if (find != null) {
list.add(find);
}
}
} catch (TimeoutException toe) {
}
return new ResolutionException(re.getMessage(), re.getCause(), list);
}
use of org.osgi.service.resolver.ResolutionException in project bnd by bndtools.
the class JpmRepoTest method testSimpleResolve.
// public void testResolveProviderWithRunpath() throws Exception {
// try {
// Project provider = ws.getProject("provider");
// provider.build();
// assertTrue(provider.check());
//
// Project requirer = ws.getProject("requirer");
// requirer.build();
// assertTrue(requirer.check());
//
// BndEditModel model = new BndEditModel();
// model.setProject(requirer);
// BndrunResolveContext context = new BndrunResolveContext(model, ws, log);
//
// Resolver resolver = new ResolverImpl(new
// org.apache.felix.resolver.Logger(4), null);
//
// Map<Resource,List<Wire>> resolved = resolver.resolve(context);
// Set<Resource> resources = resolved.keySet();
// Resource resource = getResource(resources, "requirer", "0");
// assertNotNull(resource);
// }
// catch (ResolutionException e) {
// fail("Resolve failed " + e);
// }
// }
public void testSimpleResolve() {
Repository repo = ws.getPlugin(Repository.class);
BndEditModel model = new BndEditModel();
model.setRunFw("org.apache.felix.framework");
List<Requirement> requires = new ArrayList<Requirement>();
CapReqBuilder capReq = CapReqBuilder.createBundleRequirement("org.apache.felix.gogo.shell", "[0,1)");
requires.add(capReq.buildSyntheticRequirement());
Map<Requirement, Collection<Capability>> shell = repo.findProviders(requires);
assertNotNull(shell);
assertEquals(1, shell.size());
model.setRunRequires(requires);
BndrunResolveContext context = new BndrunResolveContext(model, ws, log);
Resolver resolver = new BndResolver(new org.apache.felix.resolver.Logger(4));
try {
Map<Resource, List<Wire>> resolved = resolver.resolve(context);
Set<Resource> resources = resolved.keySet();
Resource resource = getResource(resources, "org.apache.felix.gogo.runtime", "0.12");
assertNotNull(resource);
} catch (ResolutionException e) {
fail("Resolve failed");
}
}
Aggregations