/** * 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); } } }
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; }
/** * 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); }