Example #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);
      }
    }
  }
 // TODO: SECURITY - This should probably take a module, not a bundle.
 BundleProtectionDomain(Felix felix, BundleImpl bundle) throws MalformedURLException {
   super(
       new CodeSource(
           Felix.m_secureAction.createURL(
               Felix.m_secureAction.createURL(null, "location:", new FakeURLStreamHandler()),
               bundle._getLocation(),
               new FakeURLStreamHandler()),
           (Certificate[]) null),
       null);
   m_felix = new WeakReference(felix);
   m_bundle = new WeakReference(bundle);
   m_module = new WeakReference(bundle.getCurrentModule());
   m_hashCode = bundle.hashCode();
   m_toString = "[" + bundle + "]";
 }
  /**
   * 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);
      }
    }
  }
Example #4
0
  private void checkValidity() {
    if (m_valid) {
      switch (m_bundle.getState()) {
        case Bundle.ACTIVE:
        case Bundle.STARTING:
        case Bundle.STOPPING:
          return;
      }
    }

    throw new IllegalStateException("Invalid BundleContext.");
  }
    public void setStartLevel(int startlevel) {
      Object sm = System.getSecurityManager();

      if (sm != null) {
        ((SecurityManager) sm)
            .checkPermission(new AdminPermission(m_bundle, AdminPermission.EXECUTE));
      }

      if (m_bundle.getBundleId() == 0) {
        throw new IllegalArgumentException("Cannot change system bundle start level.");
      } else if (startlevel <= 0) {
        throw new IllegalArgumentException("Start level must be greater than zero.");
      }
      synchronized (m_requests) {
        // Start thread if necessary.
        startThread();
        // Synchronously persists the start level.
        m_bundle.setStartLevel(startlevel);
        // Queue request.
        m_requestListeners.add(null);
        m_requests.add(new Object[] {m_bundle, new Integer(startlevel)});
        m_requests.notifyAll();
      }
    }
 public boolean isAssignableTo(Bundle bundle, String className) {
   final BundleImpl sBundle = registration.bundle;
   if (sBundle == null) {
     throw new IllegalStateException("Service is unregistered");
   }
   final FrameworkContext fwCtx = sBundle.fwCtx;
   if (((BundleImpl) bundle).fwCtx != fwCtx) {
     throw new IllegalArgumentException("Bundle is not from same framework as service");
   }
   // Check if bootdelegated
   if (fwCtx.isBootDelegated(className)) {
     return true;
   }
   final int pos = className.lastIndexOf('.');
   if (pos != -1) {
     final String name = className.substring(0, pos);
     final Pkg p = fwCtx.resolver.getPkg(name);
     // Is package exported by a bundle
     if (p != null) {
       final BundlePackages rbp = sBundle.current().bpkgs;
       final BundlePackages pkgExporter = rbp.getProviderBundlePackages(name);
       List<BundleGeneration> pkgProvider;
       if (pkgExporter == null) {
         // Package not imported by provide, is it required
         pkgProvider = rbp.getRequiredBundleGenerations(name);
       } else {
         pkgProvider = new ArrayList<BundleGeneration>(1);
         pkgProvider.add(pkgExporter.bg);
       }
       final BundlePackages bb = ((BundleImpl) bundle).current().bpkgs;
       final BundlePackages bbp = bb.getProviderBundlePackages(name);
       List<BundleGeneration> pkgConsumer;
       if (bbp == null) {
         // Package not imported by bundle, is it required
         pkgConsumer = bb.getRequiredBundleGenerations(name);
       } else {
         pkgConsumer = new ArrayList<BundleGeneration>(1);
         pkgConsumer.add(bbp.bg);
       }
       if (pkgConsumer == null) {
         // NYI! Check dynamic import?
         if (bb.isExported(name)) {
           // If bundle only exports package, then return true if
           // bundle is provider.
           return pkgProvider != null ? pkgProvider.contains(bb.bg) : true;
         } else {
           // If bundle doesn't import or export package, then return true and
           // assume that the bundle only uses reflection to access service.
           return true;
         }
       } else if (pkgProvider == null) {
         // Package not imported by registrar. E.g. proxy registration.
         final Object sService = registration.service;
         if (sService == null) {
           throw new IllegalStateException("Service is unregistered");
         }
         if (p.providers.size() == 1) {
           // Only one version available, allow.
           return true;
         } else if (sService instanceof ServiceFactory) {
           // Factory, allow.
           return true;
         } else {
           // Use the classloader of bundle to load the class, then check
           // if the service's class is assignable.
           final ClassLoader bCL = bb.getClassLoader();
           if (bCL != null) {
             try {
               final Class<?> bCls = bCL.loadClass(className);
               // NYI, Handle Service Factories.
               return bCls.isAssignableFrom(sService.getClass());
             } catch (final Exception e) {
               // If we can not load, assume that we are just a proxy.
               return true;
             }
           }
         }
         // Fallback: Always OK when singleton provider of the package
       } else { // Package imported by both parties
         // Return true if we have same provider as service.
         for (final Object element : pkgProvider) {
           if (pkgConsumer.contains(element)) {
             return true;
           }
         }
       }
     } else {
       // Not a package under package control. System package?
       if (name.startsWith("java.") || sBundle == bundle) {
         return true;
       } else {
         // NYI! We have a private service, check if bundle can use it.
         // Now, allow it to handle reflection of service.
         return true;
       }
     }
   }
   return false;
 }
Example #7
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);
  }