Search in sources :

Example 1 with JarContent

use of org.apache.felix.framework.cache.JarContent in project felix by apache.

the class ExtensionManager method resolveExtensionBundles.

public List<Bundle> resolveExtensionBundles(Felix felix) {
    if (m_unresolvedExtensions.isEmpty()) {
        return Collections.emptyList();
    }
    // Collect the highest version of unresolved that are not already resolved by bsn
    List<BundleRevisionImpl> extensions = new ArrayList<BundleRevisionImpl>();
    // Collect the unresolved that where filtered out as alternatives in case the highest version doesn't resolve
    List<BundleRevisionImpl> alt = new ArrayList<BundleRevisionImpl>();
    outer: for (BundleRevisionImpl revision : m_unresolvedExtensions) {
        // Already resolved by bsn?
        for (BundleRevisionImpl existing : m_resolvedExtensions) {
            if (existing.getSymbolicName().equals(revision.getSymbolicName())) {
                // Then ignore it
                continue outer;
            }
        }
        // Otherwise, does a higher version exist by bsn?
        for (BundleRevisionImpl other : m_unresolvedExtensions) {
            if ((revision != other) && (revision.getSymbolicName().equals(other.getSymbolicName())) && revision.getVersion().compareTo(other.getVersion()) < 0) {
                // Add this one to alternatives and filter it
                alt.add(revision);
                continue outer;
            }
        }
        // no higher version and not resolved yet by bsn - try to resolve it
        extensions.add(revision);
    }
    // This will return all resolvable revisions with the wires they need
    Map<BundleRevisionImpl, List<BundleWire>> wirings = findResolvableExtensions(extensions, alt);
    List<Bundle> result = new ArrayList<Bundle>();
    for (Map.Entry<BundleRevisionImpl, List<BundleWire>> entry : wirings.entrySet()) {
        BundleRevisionImpl revision = entry.getKey();
        // move this revision from unresolved to resolved
        m_unresolvedExtensions.remove(revision);
        m_resolvedExtensions.add(revision);
        BundleWire wire = new BundleWireImpl(revision, revision.getDeclaredRequirements(BundleRevision.HOST_NAMESPACE).get(0), m_systemBundleRevision, getCapabilities(BundleRevision.HOST_NAMESPACE).get(0));
        try {
            revision.resolve(new BundleWiringImpl(m_logger, m_configMap, null, revision, null, Collections.singletonList(wire), Collections.EMPTY_MAP, Collections.EMPTY_MAP));
        } catch (Exception ex) {
            m_logger.log(revision.getBundle(), Logger.LOG_ERROR, "Error resolving extension bundle : " + revision.getBundle(), ex);
        }
        felix.getDependencies().addDependent(wire);
        appendCapabilities(entry.getKey().getDeclaredExtensionCapabilities(null));
        for (BundleWire w : entry.getValue()) {
            if (!w.getRequirement().getNamespace().equals(BundleRevision.HOST_NAMESPACE) && !w.getRequirement().getNamespace().equals(BundleRevision.PACKAGE_NAMESPACE)) {
                ((BundleWiringImpl) w.getRequirer().getWiring()).addDynamicWire(w);
                felix.getDependencies().addDependent(w);
            }
        }
        final File f;
        Content revisionContent = revision.getContent();
        if (revisionContent instanceof JarContent) {
            f = ((JarContent) revisionContent).getFile();
        } else {
            f = ((DirectoryContent) revisionContent).getFile();
        }
        try {
            AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() {

                @Override
                public Void run() throws Exception {
                    m_extenderFramework.add(f);
                    return null;
                }
            });
        } catch (Exception ex) {
            m_logger.log(revision.getBundle(), Logger.LOG_ERROR, "Error adding extension bundle to framework classloader: " + revision.getBundle(), ex);
        }
        felix.setBundleStateAndNotify(revision.getBundle(), Bundle.RESOLVED);
        result.add(revision.getBundle());
    }
    // at this point, all revisions left in unresolved are not resolvable
    m_failedExtensions.addAll(m_unresolvedExtensions);
    m_unresolvedExtensions.clear();
    if (!wirings.isEmpty()) {
        felix.getResolver().addRevision(getRevision());
    }
    return result;
}
Also used : JarContent(org.apache.felix.framework.cache.JarContent) BundleWireImpl(org.apache.felix.framework.wiring.BundleWireImpl) Bundle(org.osgi.framework.Bundle) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) BundleWire(org.osgi.framework.wiring.BundleWire) BundleException(org.osgi.framework.BundleException) NoSuchElementException(java.util.NoSuchElementException) IOException(java.io.IOException) JarContent(org.apache.felix.framework.cache.JarContent) Content(org.apache.felix.framework.cache.Content) DirectoryContent(org.apache.felix.framework.cache.DirectoryContent) List(java.util.List) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ImmutableList(org.apache.felix.framework.util.ImmutableList) ArrayList(java.util.ArrayList) Map(java.util.Map) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) StringMap(org.apache.felix.framework.util.StringMap) File(java.io.File)

Example 2 with JarContent

use of org.apache.felix.framework.cache.JarContent in project felix by apache.

the class ExtensionManager method addExtensionBundle.

/**
 * Add an extension bundle. The bundle will be added to the parent classloader
 * and it's exported packages will be added to the module definition
 * exports of this instance. Subsequently, they are available form the
 * instance in it's role as content loader.
 *
 * @param felix the framework instance the given extension bundle comes from.
 * @param bundle the extension bundle to add.
 * @throws BundleException if extension bundles are not supported or this is
 *          not a framework extension.
 * @throws SecurityException if the caller does not have the needed
 *          AdminPermission.EXTENSIONLIFECYCLE and security is enabled.
 * @throws Exception in case something goes wrong.
 */
synchronized void addExtensionBundle(Felix felix, BundleImpl bundle) throws Exception {
    Object sm = System.getSecurityManager();
    if (sm != null) {
        ((SecurityManager) sm).checkPermission(new AdminPermission(bundle, AdminPermission.EXTENSIONLIFECYCLE));
        if (!((BundleProtectionDomain) bundle.getProtectionDomain()).impliesDirect(new AllPermission())) {
            throw new SecurityException("Extension Bundles must have AllPermission");
        }
    }
    String directive = ManifestParser.parseExtensionBundleHeader((String) ((BundleRevisionImpl) bundle.adapt(BundleRevision.class)).getHeaders().get(Constants.FRAGMENT_HOST));
    final ClassPathExtenderFactory.ClassPathExtender extender;
    if (!Constants.EXTENSION_FRAMEWORK.equals(directive)) {
        throw new BundleException("Unsupported Extension Bundle type: " + directive, new UnsupportedOperationException("Unsupported Extension Bundle type!"));
    } else if (m_extenderFramework == null) {
        // We don't support extensions
        m_logger.log(bundle, Logger.LOG_WARNING, "Unable to add extension bundle - Maybe ClassLoader is not supported (on java9, try --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED)?");
        throw new UnsupportedOperationException("Unable to add extension bundle.");
    }
    Content content = bundle.adapt(BundleRevisionImpl.class).getContent();
    final File file;
    if (content instanceof JarContent) {
        file = ((JarContent) content).getFile();
    } else if (content instanceof DirectoryContent) {
        file = ((DirectoryContent) content).getFile();
    } else {
        file = null;
    }
    if (file == null) {
        // We don't support revision type for extension
        m_logger.log(bundle, Logger.LOG_WARNING, "Unable to add extension bundle - wrong revision type?");
        throw new UnsupportedOperationException("Unable to add extension bundle.");
    }
    BundleRevisionImpl bri = bundle.adapt(BundleRevisionImpl.class);
    bri.resolve(null);
    // we have to try again for all previously failed extensions because maybe they can now resolve.
    m_unresolvedExtensions.addAll(m_failedExtensions);
    m_failedExtensions.clear();
    m_unresolvedExtensions.add(bri);
}
Also used : JarContent(org.apache.felix.framework.cache.JarContent) AdminPermission(org.osgi.framework.AdminPermission) JarContent(org.apache.felix.framework.cache.JarContent) Content(org.apache.felix.framework.cache.Content) DirectoryContent(org.apache.felix.framework.cache.DirectoryContent) AllPermission(java.security.AllPermission) DirectoryContent(org.apache.felix.framework.cache.DirectoryContent) BundleException(org.osgi.framework.BundleException) File(java.io.File) ClassPathExtenderFactory(org.apache.felix.framework.ext.ClassPathExtenderFactory)

Aggregations

File (java.io.File)2 Content (org.apache.felix.framework.cache.Content)2 DirectoryContent (org.apache.felix.framework.cache.DirectoryContent)2 JarContent (org.apache.felix.framework.cache.JarContent)2 BundleException (org.osgi.framework.BundleException)2 IOException (java.io.IOException)1 AllPermission (java.security.AllPermission)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 LinkedHashMap (java.util.LinkedHashMap)1 List (java.util.List)1 Map (java.util.Map)1 NoSuchElementException (java.util.NoSuchElementException)1 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)1 ClassPathExtenderFactory (org.apache.felix.framework.ext.ClassPathExtenderFactory)1 ImmutableList (org.apache.felix.framework.util.ImmutableList)1 StringMap (org.apache.felix.framework.util.StringMap)1 BundleWireImpl (org.apache.felix.framework.wiring.BundleWireImpl)1 AdminPermission (org.osgi.framework.AdminPermission)1 Bundle (org.osgi.framework.Bundle)1