Search in sources :

Example 61 with BundleCapability

use of org.osgi.framework.wiring.BundleCapability in project felix by apache.

the class Util method getCapabilityByNamespace.

/**
 * Returns all the capabilities from a module that has a specified namespace.
 *
 * @param br    module providing capabilities
 * @param namespace capability namespace
 * @return array of matching capabilities or empty if none found
 */
public static List<BundleCapability> getCapabilityByNamespace(BundleRevision br, String namespace) {
    final List<BundleCapability> matching = new ArrayList();
    final List<BundleCapability> caps = (br.getWiring() != null) ? br.getWiring().getCapabilities(null) : br.getDeclaredCapabilities(null);
    if (caps != null) {
        for (BundleCapability cap : caps) {
            if (cap.getNamespace().equals(namespace)) {
                matching.add(cap);
            }
        }
    }
    return matching;
}
Also used : ArrayList(java.util.ArrayList) BundleCapability(org.osgi.framework.wiring.BundleCapability)

Example 62 with BundleCapability

use of org.osgi.framework.wiring.BundleCapability in project felix by apache.

the class BundleRevisionDependencies method getImportingBundles.

public synchronized Set<Bundle> getImportingBundles(Bundle exporter, BundleCapability exportCap) {
    // Create set for storing importing bundles.
    Set<Bundle> result = new HashSet<Bundle>();
    // Get exported package name.
    String pkgName = (String) exportCap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE);
    // The spec says that require-bundle should be returned with importers.
    for (BundleRevision revision : exporter.adapt(BundleRevisions.class).getRevisions()) {
        Map<BundleCapability, Set<BundleWire>> caps = m_dependentsMap.get(revision);
        if (caps != null) {
            for (Entry<BundleCapability, Set<BundleWire>> entry : caps.entrySet()) {
                BundleCapability cap = entry.getKey();
                if ((cap.getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE) && cap.getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).equals(pkgName)) || cap.getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE)) {
                    for (BundleWire dependentWire : entry.getValue()) {
                        result.add(dependentWire.getRequirer().getBundle());
                    }
                }
            }
        }
    }
    // Return the results.
    return result;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) Bundle(org.osgi.framework.Bundle) BundleRevision(org.osgi.framework.wiring.BundleRevision) BundleCapability(org.osgi.framework.wiring.BundleCapability) BundleWire(org.osgi.framework.wiring.BundleWire) HashSet(java.util.HashSet) BundleRevisions(org.osgi.framework.wiring.BundleRevisions)

Example 63 with BundleCapability

use of org.osgi.framework.wiring.BundleCapability in project felix by apache.

the class BundleRevisionDependencies method getDependentBundles.

public synchronized Set<Bundle> getDependentBundles(Bundle bundle) {
    Set<Bundle> result = new HashSet<Bundle>();
    List<BundleRevision> revisions = bundle.adapt(BundleRevisions.class).getRevisions();
    for (BundleRevision revision : revisions) {
        // since their dependents are their hosts.
        if (Util.isFragment(revision)) {
            BundleWiring wiring = revision.getWiring();
            if (wiring != null) {
                for (BundleWire bw : wiring.getRequiredWires(null)) {
                    if (HostNamespace.HOST_NAMESPACE.equals(bw.getCapability().getNamespace())) {
                        result.add(bw.getProvider().getBundle());
                    }
                }
            }
        } else {
            Map<BundleCapability, Set<BundleWire>> caps = m_dependentsMap.get(revision);
            if (caps != null) {
                for (Entry<BundleCapability, Set<BundleWire>> entry : caps.entrySet()) {
                    for (BundleWire dependentWire : entry.getValue()) {
                        result.add(dependentWire.getRequirer().getBundle());
                    }
                }
            }
        }
    }
    return result;
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) Bundle(org.osgi.framework.Bundle) BundleWiring(org.osgi.framework.wiring.BundleWiring) BundleRevision(org.osgi.framework.wiring.BundleRevision) BundleCapability(org.osgi.framework.wiring.BundleCapability) BundleWire(org.osgi.framework.wiring.BundleWire) HashSet(java.util.HashSet) BundleRevisions(org.osgi.framework.wiring.BundleRevisions)

Example 64 with BundleCapability

use of org.osgi.framework.wiring.BundleCapability in project felix by apache.

the class BundleWiringImpl method listResourcesInternal.

private Collection<ResourceSource> listResourcesInternal(String path, List<String> pattern, int options) {
    if (isInUse()) {
        boolean recurse = (options & BundleWiring.LISTRESOURCES_RECURSE) > 0;
        boolean localOnly = (options & BundleWiring.LISTRESOURCES_LOCAL) > 0;
        // Check for cycles, which can happen with Require-Bundle.
        Set<String> cycles = (Set<String>) m_listResourcesCycleCheck.get();
        if (cycles == null) {
            cycles = new HashSet<String>();
            m_listResourcesCycleCheck.set(cycles);
        }
        if (cycles.contains(path)) {
            return Collections.EMPTY_LIST;
        }
        cycles.add(path);
        try {
            // Calculate set of remote resources (i.e., those either
            // imported or required).
            Collection<ResourceSource> remoteResources = new TreeSet<ResourceSource>();
            // Imported packages cannot have merged content, so we need to
            // keep track of these packages.
            Set<String> noMerging = new HashSet<String>();
            // Loop through wires to compute remote resources.
            for (BundleWire bw : m_wires) {
                if (bw.getCapability().getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)) {
                    // For imported packages, we only need to calculate
                    // the remote resources of the specific imported package.
                    remoteResources.addAll(calculateRemotePackageResources(bw, bw.getCapability(), recurse, path, pattern, noMerging));
                } else if (bw.getCapability().getNamespace().equals(BundleRevision.BUNDLE_NAMESPACE)) {
                    // For required bundles, all declared package capabilities
                    // from the required bundle will be available to requirers,
                    // so get the target required bundle's declared packages
                    // and handle them in a similar fashion to a normal import
                    // except that their content can be merged with local
                    // packages.
                    List<BundleCapability> exports = bw.getProviderWiring().getRevision().getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
                    for (BundleCapability export : exports) {
                        remoteResources.addAll(calculateRemotePackageResources(bw, export, recurse, path, pattern, null));
                    }
                    // Since required bundle may reexport bundles it requires,
                    // check its wires for this case.
                    List<BundleWire> requiredBundles = bw.getProviderWiring().getRequiredWires(BundleRevision.BUNDLE_NAMESPACE);
                    for (BundleWire rbWire : requiredBundles) {
                        String visibility = rbWire.getRequirement().getDirectives().get(Constants.VISIBILITY_DIRECTIVE);
                        if ((visibility != null) && (visibility.equals(Constants.VISIBILITY_REEXPORT))) {
                            // For each reexported required bundle, treat them
                            // in a similar fashion as a normal required bundle
                            // by including all of their declared package
                            // capabilities in the requiring bundle's class
                            // space.
                            List<BundleCapability> reexports = rbWire.getProviderWiring().getRevision().getDeclaredCapabilities(BundleRevision.PACKAGE_NAMESPACE);
                            for (BundleCapability reexport : reexports) {
                                remoteResources.addAll(calculateRemotePackageResources(bw, reexport, recurse, path, pattern, null));
                            }
                        }
                    }
                }
            }
            // Calculate set of local resources (i.e., those contained
            // in the revision or its fragments).
            Collection<ResourceSource> localResources = new TreeSet<ResourceSource>();
            // Get the revision's content path, which includes contents
            // from fragments.
            List<Content> contentPath = m_revision.getContentPath();
            for (Content content : contentPath) {
                Enumeration<String> e = content.getEntries();
                if (e != null) {
                    while (e.hasMoreElements()) {
                        String resource = e.nextElement();
                        String resourcePath = getTrailingPath(resource);
                        if (!noMerging.contains(resourcePath)) {
                            if ((!recurse && resourcePath.equals(path)) || (recurse && resourcePath.startsWith(path))) {
                                if (matchesPattern(pattern, getPathHead(resource))) {
                                    localResources.add(new ResourceSource(resource, m_revision));
                                }
                            }
                        }
                    }
                }
            }
            if (localOnly) {
                return localResources;
            } else {
                remoteResources.addAll(localResources);
                return remoteResources;
            }
        } finally {
            cycles.remove(path);
            if (cycles.isEmpty()) {
                m_listResourcesCycleCheck.set(null);
            }
        }
    }
    return null;
}
Also used : Set(java.util.Set) TreeSet(java.util.TreeSet) HashSet(java.util.HashSet) BundleWire(org.osgi.framework.wiring.BundleWire) TreeSet(java.util.TreeSet) JarContent(org.apache.felix.framework.cache.JarContent) Content(org.apache.felix.framework.cache.Content) List(java.util.List) ImmutableList(org.apache.felix.framework.util.ImmutableList) ArrayList(java.util.ArrayList) BundleCapability(org.osgi.framework.wiring.BundleCapability) HashSet(java.util.HashSet)

Example 65 with BundleCapability

use of org.osgi.framework.wiring.BundleCapability in project felix by apache.

the class BundleWiringImpl method diagnoseClassLoadError.

private static String diagnoseClassLoadError(StatefulResolver resolver, BundleRevision revision, String name) {
    // We will try to do some diagnostics here to help the developer
    // deal with this exception.
    // Get package name.
    String pkgName = Util.getClassPackage(name);
    if (pkgName.length() == 0) {
        return null;
    }
    // First, get the bundle string of the revision doing the class loader.
    String importer = revision.getBundle().toString();
    // Next, check to see if the revision imports the package.
    List<BundleWire> wires = (revision.getWiring() == null) ? null : revision.getWiring().getProvidedWires(null);
    for (int i = 0; (wires != null) && (i < wires.size()); i++) {
        if (wires.get(i).getCapability().getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE) && wires.get(i).getCapability().getAttributes().get(BundleRevision.PACKAGE_NAMESPACE).equals(pkgName)) {
            String exporter = wires.get(i).getProviderWiring().getBundle().toString();
            StringBuffer sb = new StringBuffer("*** Package '");
            sb.append(pkgName);
            sb.append("' is imported by bundle ");
            sb.append(importer);
            sb.append(" from bundle ");
            sb.append(exporter);
            sb.append(", but the exported package from bundle ");
            sb.append(exporter);
            sb.append(" does not contain the requested class '");
            sb.append(name);
            sb.append("'. Please verify that the class name is correct in the importing bundle ");
            sb.append(importer);
            sb.append(" and/or that the exported package is correctly bundled in ");
            sb.append(exporter);
            sb.append(". ***");
            return sb.toString();
        }
    }
    // Next, check to see if the package was optionally imported and
    // whether or not there is an exporter available.
    List<BundleRequirement> reqs = revision.getWiring().getRequirements(null);
    // Next, check to see if the package is dynamically imported by the revision.
    if (resolver.isAllowedDynamicImport(revision, pkgName)) {
        // Try to see if there is an exporter available.
        Map<String, String> dirs = Collections.EMPTY_MAP;
        Map<String, Object> attrs = Collections.singletonMap(BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
        BundleRequirementImpl req = new BundleRequirementImpl(revision, BundleRevision.PACKAGE_NAMESPACE, dirs, attrs);
        List<BundleCapability> exporters = resolver.findProviders(req, false);
        BundleRevision provider = null;
        try {
            provider = resolver.resolve(revision, pkgName);
        } catch (Exception ex) {
            provider = null;
        }
        String exporter = (exporters.isEmpty()) ? null : exporters.iterator().next().toString();
        StringBuffer sb = new StringBuffer("*** Class '");
        sb.append(name);
        sb.append("' was not found, but this is likely normal since package '");
        sb.append(pkgName);
        sb.append("' is dynamically imported by bundle ");
        sb.append(importer);
        sb.append(".");
        if ((exporters.size() > 0) && (provider == null)) {
            sb.append(" However, bundle ");
            sb.append(exporter);
            sb.append(" does export this package with attributes that do not match.");
        }
        sb.append(" ***");
        return sb.toString();
    }
    // Next, check to see if there are any exporters for the package at all.
    Map<String, String> dirs = Collections.EMPTY_MAP;
    Map<String, Object> attrs = Collections.singletonMap(BundleRevision.PACKAGE_NAMESPACE, (Object) pkgName);
    BundleRequirementImpl req = new BundleRequirementImpl(revision, BundleRevision.PACKAGE_NAMESPACE, dirs, attrs);
    List<BundleCapability> exports = resolver.findProviders(req, false);
    if (exports.size() > 0) {
        boolean classpath = false;
        try {
            BundleRevisionImpl.getSecureAction().getClassLoader(BundleClassLoader.class).loadClass(name);
            classpath = true;
        } catch (NoClassDefFoundError err) {
        // Ignore
        } catch (Exception ex) {
        // Ignore
        }
        String exporter = exports.iterator().next().toString();
        StringBuffer sb = new StringBuffer("*** Class '");
        sb.append(name);
        sb.append("' was not found because bundle ");
        sb.append(importer);
        sb.append(" does not import '");
        sb.append(pkgName);
        sb.append("' even though bundle ");
        sb.append(exporter);
        sb.append(" does export it.");
        if (classpath) {
            sb.append(" Additionally, the class is also available from the system class loader. There are two fixes: 1) Add an import for '");
            sb.append(pkgName);
            sb.append("' to bundle ");
            sb.append(importer);
            sb.append("; imports are necessary for each class directly touched by bundle code or indirectly touched, such as super classes if their methods are used. ");
            sb.append("2) Add package '");
            sb.append(pkgName);
            sb.append("' to the '");
            sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
            sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
        } else {
            sb.append(" To resolve this issue, add an import for '");
            sb.append(pkgName);
            sb.append("' to bundle ");
            sb.append(importer);
            sb.append(".");
        }
        sb.append(" ***");
        return sb.toString();
    }
    // class loader.
    try {
        BundleRevisionImpl.getSecureAction().getClassLoader(BundleClassLoader.class).loadClass(name);
        StringBuffer sb = new StringBuffer("*** Package '");
        sb.append(pkgName);
        sb.append("' is not imported by bundle ");
        sb.append(importer);
        sb.append(", nor is there any bundle that exports package '");
        sb.append(pkgName);
        sb.append("'. However, the class '");
        sb.append(name);
        sb.append("' is available from the system class loader. There are two fixes: 1) Add package '");
        sb.append(pkgName);
        sb.append("' to the '");
        sb.append(Constants.FRAMEWORK_SYSTEMPACKAGES_EXTRA);
        sb.append("' property and modify bundle ");
        sb.append(importer);
        sb.append(" to import this package; this causes the system bundle to export class path packages. 2) Add package '");
        sb.append(pkgName);
        sb.append("' to the '");
        sb.append(Constants.FRAMEWORK_BOOTDELEGATION);
        sb.append("' property; a library or VM bug can cause classes to be loaded by the wrong class loader. The first approach is preferable for preserving modularity.");
        sb.append(" ***");
        return sb.toString();
    } catch (Exception ex2) {
    }
    // Finally, if there are no imports or exports for the package
    // and it is not available on the system class path, simply
    // log a message saying so.
    StringBuffer sb = new StringBuffer("*** Class '");
    sb.append(name);
    sb.append("' was not found. Bundle ");
    sb.append(importer);
    sb.append(" does not import package '");
    sb.append(pkgName);
    sb.append("', nor is the package exported by any other bundle or available from the system class loader.");
    sb.append(" ***");
    return sb.toString();
}
Also used : BundleWire(org.osgi.framework.wiring.BundleWire) BundleRequirement(org.osgi.framework.wiring.BundleRequirement) BundleRequirementImpl(org.apache.felix.framework.wiring.BundleRequirementImpl) BundleException(org.osgi.framework.BundleException) ResolutionException(org.osgi.service.resolver.ResolutionException) ResourceNotFoundException(org.apache.felix.framework.resolver.ResourceNotFoundException) WeavingException(org.osgi.framework.hooks.weaving.WeavingException) PrivilegedActionException(java.security.PrivilegedActionException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) BundleRevision(org.osgi.framework.wiring.BundleRevision) BundleCapability(org.osgi.framework.wiring.BundleCapability)

Aggregations

BundleCapability (org.osgi.framework.wiring.BundleCapability)83 ArrayList (java.util.ArrayList)30 BundleRevision (org.osgi.framework.wiring.BundleRevision)26 HashMap (java.util.HashMap)24 Bundle (org.osgi.framework.Bundle)24 BundleRequirement (org.osgi.framework.wiring.BundleRequirement)21 BundleWiring (org.osgi.framework.wiring.BundleWiring)19 BundleWire (org.osgi.framework.wiring.BundleWire)18 List (java.util.List)15 Version (org.osgi.framework.Version)12 BundleException (org.osgi.framework.BundleException)11 ResolverHook (org.osgi.framework.hooks.resolver.ResolverHook)11 Collection (java.util.Collection)10 Test (org.junit.Test)10 HashSet (java.util.HashSet)9 Set (java.util.Set)8 ResolverHookFactory (org.osgi.framework.hooks.resolver.ResolverHookFactory)8 LinkedHashMap (java.util.LinkedHashMap)6 Module (org.eclipse.osgi.container.Module)6 CompositeData (javax.management.openmbean.CompositeData)5