Search in sources :

Example 1 with Content

use of org.apache.felix.framework.cache.Content 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 Content

use of org.apache.felix.framework.cache.Content 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)

Example 3 with Content

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

the class BundleRevisionImpl method getResourcesLocal.

Enumeration getResourcesLocal(String name) {
    List l = new ArrayList();
    // Special case "/" so that it returns a root URLs for
    // each bundle class path entry...this isn't very
    // clean or meaningful, but the Spring guys want it.
    final List<Content> contentPath = getContentPath();
    if (contentPath == null)
        return Collections.enumeration(Collections.emptyList());
    if (name.equals("/")) {
        for (int i = 0; i < contentPath.size(); i++) {
            l.add(createURL(i + 1, name));
        }
    } else {
        // Remove leading slash, if present.
        if (name.startsWith("/")) {
            name = name.substring(1);
        }
        // Check the module class path.
        for (int i = 0; i < contentPath.size(); i++) {
            if (contentPath.get(i).hasEntry(name)) {
                // Use the class path index + 1 for creating the path so
                // that we can differentiate between module content URLs
                // (where the path will start with 0) and module class
                // path URLs.
                l.add(createURL(i + 1, name));
            }
        }
    }
    return Collections.enumeration(l);
}
Also used : MultiReleaseContent(org.apache.felix.framework.util.MultiReleaseContent) Content(org.apache.felix.framework.cache.Content) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List)

Example 4 with Content

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

the class BundleWiringImplTest method testFindClassBadWeave.

@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testFindClassBadWeave() throws Exception {
    Felix mockFramework = mock(Felix.class);
    Content mockContent = mock(Content.class);
    ServiceReference<WeavingHook> mockServiceReferenceWeavingHook = mock(ServiceReference.class);
    ServiceReference<WovenClassListener> mockServiceReferenceWovenClassListener = mock(ServiceReference.class);
    Set<ServiceReference<WeavingHook>> hooks = new HashSet<ServiceReference<WeavingHook>>();
    hooks.add(mockServiceReferenceWeavingHook);
    DummyWovenClassListener dummyWovenClassListener = new DummyWovenClassListener();
    Set<ServiceReference<WovenClassListener>> listeners = new HashSet<ServiceReference<WovenClassListener>>();
    listeners.add(mockServiceReferenceWovenClassListener);
    Class testClass = TestClass.class;
    String testClassName = testClass.getName();
    String testClassAsPath = testClassName.replace('.', '/') + ".class";
    byte[] testClassBytes = createTestClassBytes(testClass, testClassAsPath);
    List<Content> contentPath = new ArrayList<Content>();
    contentPath.add(mockContent);
    initializeSimpleBundleWiring();
    when(mockBundle.getFramework()).thenReturn(mockFramework);
    when(mockFramework.getBootPackages()).thenReturn(new String[0]);
    when(mockRevisionImpl.getContentPath()).thenReturn(contentPath);
    when(mockContent.getEntryAsBytes(testClassAsPath)).thenReturn(testClassBytes);
    HookRegistry hReg = mock(HookRegistry.class);
    when(hReg.getHooks(WeavingHook.class)).thenReturn(hooks);
    when(mockFramework.getHookRegistry()).thenReturn(hReg);
    when(mockFramework.getService(mockFramework, mockServiceReferenceWeavingHook, false)).thenReturn(new BadDummyWovenHook());
    when(hReg.getHooks(WovenClassListener.class)).thenReturn(listeners);
    when(mockFramework.getService(mockFramework, mockServiceReferenceWovenClassListener, false)).thenReturn(dummyWovenClassListener);
    BundleClassLoader bundleClassLoader = createBundleClassLoader(BundleClassLoader.class, bundleWiring);
    assertNotNull(bundleClassLoader);
    try {
        bundleClassLoader.findClass(TestClass.class.getName());
        fail("Class should throw exception");
    } catch (Error e) {
    // This is expected
    }
    assertEquals("There should be 1 state changes fired by the weaving", 1, dummyWovenClassListener.stateList.size());
    assertEquals("The only state change should be a failed transform on the class", (Object) WovenClass.TRANSFORMING_FAILED, dummyWovenClassListener.stateList.get(0));
}
Also used : BundleClassLoader(org.apache.felix.framework.BundleWiringImpl.BundleClassLoader) ArrayList(java.util.ArrayList) WovenClassListener(org.osgi.framework.hooks.weaving.WovenClassListener) ServiceReference(org.osgi.framework.ServiceReference) Content(org.apache.felix.framework.cache.Content) WovenClass(org.osgi.framework.hooks.weaving.WovenClass) WeavingHook(org.osgi.framework.hooks.weaving.WeavingHook) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 5 with Content

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

the class BundleWiringImplTest method testFindClassWeaveDefineError.

@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testFindClassWeaveDefineError() throws Exception {
    Felix mockFramework = mock(Felix.class);
    Content mockContent = mock(Content.class);
    ServiceReference<WeavingHook> mockServiceReferenceWeavingHook = mock(ServiceReference.class);
    ServiceReference<WovenClassListener> mockServiceReferenceWovenClassListener = mock(ServiceReference.class);
    Set<ServiceReference<WeavingHook>> hooks = new HashSet<ServiceReference<WeavingHook>>();
    hooks.add(mockServiceReferenceWeavingHook);
    DummyWovenClassListener dummyWovenClassListener = new DummyWovenClassListener();
    Set<ServiceReference<WovenClassListener>> listeners = new HashSet<ServiceReference<WovenClassListener>>();
    listeners.add(mockServiceReferenceWovenClassListener);
    Class testClass = TestClass.class;
    String testClassName = testClass.getName();
    String testClassAsPath = testClassName.replace('.', '/') + ".class";
    byte[] testClassBytes = createTestClassBytes(testClass, testClassAsPath);
    List<Content> contentPath = new ArrayList<Content>();
    contentPath.add(mockContent);
    initializeSimpleBundleWiring();
    when(mockBundle.getFramework()).thenReturn(mockFramework);
    when(mockFramework.getBootPackages()).thenReturn(new String[0]);
    when(mockRevisionImpl.getContentPath()).thenReturn(contentPath);
    when(mockContent.getEntryAsBytes(testClassAsPath)).thenReturn(testClassBytes);
    HookRegistry hReg = mock(HookRegistry.class);
    when(hReg.getHooks(WeavingHook.class)).thenReturn(hooks);
    when(mockFramework.getHookRegistry()).thenReturn(hReg);
    when(mockFramework.getService(mockFramework, mockServiceReferenceWeavingHook, false)).thenReturn(new BadDefineWovenHook());
    when(hReg.getHooks(WovenClassListener.class)).thenReturn(listeners);
    when(mockFramework.getService(mockFramework, mockServiceReferenceWovenClassListener, false)).thenReturn(dummyWovenClassListener);
    BundleClassLoader bundleClassLoader = createBundleClassLoader(BundleClassLoader.class, bundleWiring);
    assertNotNull(bundleClassLoader);
    try {
        bundleClassLoader.findClass(TestClass.class.getName());
        fail("Class should throw exception");
    } catch (Throwable e) {
    }
    assertEquals("There should be 2 state changes fired by the weaving", 2, dummyWovenClassListener.stateList.size());
    assertEquals("The first state change should transform the class", (Object) WovenClass.TRANSFORMED, dummyWovenClassListener.stateList.get(0));
    assertEquals("The second state change failed the define on the class", (Object) WovenClass.DEFINE_FAILED, dummyWovenClassListener.stateList.get(1));
}
Also used : BundleClassLoader(org.apache.felix.framework.BundleWiringImpl.BundleClassLoader) ArrayList(java.util.ArrayList) WovenClassListener(org.osgi.framework.hooks.weaving.WovenClassListener) ServiceReference(org.osgi.framework.ServiceReference) Content(org.apache.felix.framework.cache.Content) WovenClass(org.osgi.framework.hooks.weaving.WovenClass) WeavingHook(org.osgi.framework.hooks.weaving.WeavingHook) HashSet(java.util.HashSet) Test(org.junit.Test)

Aggregations

Content (org.apache.felix.framework.cache.Content)11 ArrayList (java.util.ArrayList)8 HashSet (java.util.HashSet)4 List (java.util.List)4 BundleClassLoader (org.apache.felix.framework.BundleWiringImpl.BundleClassLoader)4 JarContent (org.apache.felix.framework.cache.JarContent)4 Test (org.junit.Test)4 WovenClass (org.osgi.framework.hooks.weaving.WovenClass)4 MultiReleaseContent (org.apache.felix.framework.util.MultiReleaseContent)3 ServiceReference (org.osgi.framework.ServiceReference)3 WeavingHook (org.osgi.framework.hooks.weaving.WeavingHook)3 WovenClassListener (org.osgi.framework.hooks.weaving.WovenClassListener)3 File (java.io.File)2 DirectoryContent (org.apache.felix.framework.cache.DirectoryContent)2 ImmutableList (org.apache.felix.framework.util.ImmutableList)2 BundleException (org.osgi.framework.BundleException)2 BundleWire (org.osgi.framework.wiring.BundleWire)2 IOException (java.io.IOException)1 URL (java.net.URL)1 AllPermission (java.security.AllPermission)1