예제 #1
0
  /**
   * This is a Felix specific extension mechanism that allows extension bundles to have activators
   * and be started via this method.
   *
   * @param felix the framework instance the extension bundle is installed in.
   * @param bundle the extension bundle to start if it has a Felix specific activator.
   */
  void startExtensionBundle(Felix felix, BundleImpl bundle) {
    String activatorClass =
        (String)
            ((BundleRevisionImpl) bundle.adapt(BundleRevision.class))
                .getHeaders()
                .get(FelixConstants.FELIX_EXTENSION_ACTIVATOR);

    if (activatorClass != null) {
      try {
        // TODO: SECURITY - Should this consider security?
        BundleActivator activator =
            (BundleActivator)
                felix.getClass().getClassLoader().loadClass(activatorClass.trim()).newInstance();

        // TODO: EXTENSIONMANAGER - This is kind of hacky, can we improve it?
        felix.m_activatorList.add(activator);

        BundleContext context = felix._getBundleContext();

        bundle.setBundleContext(context);

        if ((felix.getState() == Bundle.ACTIVE) || (felix.getState() == Bundle.STARTING)) {
          Felix.m_secureAction.startActivator(activator, context);
        }
      } catch (Throwable ex) {
        m_logger.log(bundle, Logger.LOG_WARNING, "Unable to start Felix Extension Activator", ex);
      }
    }
  }
  /**
   * This is a Felix specific extension mechanism that allows extension bundles to have activators
   * and be started via this method.
   *
   * @param felix the framework instance the extension bundle is installed in.
   * @param bundle the extension bundle to start if it has a Felix specific activator.
   */
  void startExtensionBundle(Felix felix, BundleImpl bundle) {
    Map<?, ?> headers = bundle.adapt(BundleRevisionImpl.class).getHeaders();
    String activatorClass = (String) headers.get(Constants.EXTENSION_BUNDLE_ACTIVATOR);
    boolean felixExtension = false;
    if (activatorClass == null) {
      felixExtension = true;
      activatorClass = (String) headers.get(FelixConstants.FELIX_EXTENSION_ACTIVATOR);
    }

    if (activatorClass != null) {
      ExtensionTuple tuple = null;
      try {
        // TODO: SECURITY - Should this consider security?
        BundleActivator activator =
            (BundleActivator)
                felix.getClass().getClassLoader().loadClass(activatorClass.trim()).newInstance();

        BundleContext context = felix._getBundleContext();

        bundle.setBundleContext(context);

        // TODO: EXTENSIONMANAGER - This is kind of hacky, can we improve it?
        if (!felixExtension) {
          tuple = new ExtensionTuple(activator, bundle);
          m_extensionTuples.add(tuple);
        } else {
          felix.m_activatorList.add(activator);
        }

        if ((felix.getState() == Bundle.ACTIVE) || (felix.getState() == Bundle.STARTING)) {
          if (tuple != null) {
            tuple.m_started = true;
          }
          Felix.m_secureAction.startActivator(activator, context);
        }
      } catch (Throwable ex) {
        if (tuple != null) {
          tuple.m_failed = true;
        }
        felix.fireFrameworkEvent(
            FrameworkEvent.ERROR, bundle, new BundleException("Unable to start Bundle", ex));

        m_logger.log(bundle, Logger.LOG_WARNING, "Unable to start Extension Activator", ex);
      }
    }
  }
예제 #3
0
  /**
   * 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 SecurityException, BundleException, 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));

    // We only support classpath extensions (not bootclasspath).
    if (!Constants.EXTENSION_FRAMEWORK.equals(directive)) {
      throw new BundleException(
          "Unsupported Extension Bundle type: " + directive,
          new UnsupportedOperationException("Unsupported Extension Bundle type!"));
    }

    try {
      // Merge the exported packages with the exported packages of the systembundle.
      List<BundleCapability> exports = null;
      try {
        exports =
            ManifestParser.parseExportHeader(
                m_logger,
                m_systemBundleRevision,
                (String)
                    ((BundleRevisionImpl) bundle.adapt(BundleRevision.class))
                        .getHeaders()
                        .get(Constants.EXPORT_PACKAGE),
                m_systemBundleRevision.getSymbolicName(),
                m_systemBundleRevision.getVersion());
        exports = aliasSymbolicName(exports);
      } catch (Exception ex) {
        m_logger.log(
            bundle,
            Logger.LOG_ERROR,
            "Error parsing extension bundle export statement: "
                + ((BundleRevisionImpl) bundle.adapt(BundleRevision.class))
                    .getHeaders()
                    .get(Constants.EXPORT_PACKAGE),
            ex);
        return;
      }

      // Add the bundle as extension if we support extensions
      if (m_extensionManager != null) {
        // This needs to be the private instance.
        m_extensionManager.addExtension(felix, bundle);
      } else {
        // We don't support extensions (i.e., the parent is not an URLClassLoader).
        m_logger.log(
            bundle,
            Logger.LOG_WARNING,
            "Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?");
        throw new UnsupportedOperationException(
            "Unable to add extension bundle to FrameworkClassLoader - Maybe not an URLClassLoader?");
      }
      appendCapabilities(exports);
    } catch (Exception ex) {
      throw ex;
    }

    BundleRevisionImpl bri = (BundleRevisionImpl) bundle.adapt(BundleRevision.class);
    List<BundleRequirement> reqs = bri.getDeclaredRequirements(BundleRevision.HOST_NAMESPACE);
    List<BundleCapability> caps = getCapabilities(BundleRevision.HOST_NAMESPACE);
    BundleWire bw = new BundleWireImpl(bri, reqs.get(0), m_systemBundleRevision, caps.get(0));
    bri.resolve(
        new BundleWiringImpl(
            m_logger,
            m_configMap,
            null,
            bri,
            null,
            Collections.singletonList(bw),
            Collections.EMPTY_MAP,
            Collections.EMPTY_MAP));
    felix.getDependencies().addDependent(bw);
    felix.setBundleStateAndNotify(bundle, Bundle.RESOLVED);
  }