Search in sources :

Example 1 with ThreadGate

use of org.apache.felix.framework.util.ThreadGate in project felix by apache.

the class Felix method init.

/**
 * @see org.osgi.framework.launch.Framework#init(org.osgi.framework.FrameworkListener[])
 */
@Override
public void init(final FrameworkListener... listeners) throws BundleException {
    // The system bundle can only be initialized if it currently isn't started.
    acquireBundleLock(this, Bundle.INSTALLED | Bundle.RESOLVED | Bundle.STARTING | Bundle.ACTIVE);
    try {
        if ((getState() == Bundle.INSTALLED) || (getState() == Bundle.RESOLVED)) {
            String security = (String) m_configMap.get(Constants.FRAMEWORK_SECURITY);
            if (security != null) {
                if (System.getSecurityManager() != null) {
                    throw new SecurityException("SecurityManager already installed");
                }
                security = security.trim();
                if (Constants.FRAMEWORK_SECURITY_OSGI.equalsIgnoreCase(security) || (security.length() == 0)) {
                    System.setSecurityManager(m_securityManager = new SecurityManager());
                } else {
                    try {
                        System.setSecurityManager(m_securityManager = (SecurityManager) Class.forName(security).newInstance());
                    } catch (Throwable t) {
                        SecurityException se = new SecurityException("Unable to install custom SecurityManager: " + security);
                        se.initCause(t);
                        throw se;
                    }
                }
            }
            // Generate a framework UUID.
            // Spec says we get a new UUID for each invocation of init().
            m_configMutableMap.put(FelixConstants.FRAMEWORK_UUID, Util.randomUUID());
            // Initialize event dispatcher.
            m_dispatcher.startDispatching();
            // Create the bundle cache, if necessary, so that we can reload any
            // installed bundles.
            m_cache = (BundleCache) m_configMutableMap.get(FelixConstants.FRAMEWORK_BUNDLECACHE_IMPL);
            if (m_cache == null) {
                try {
                    m_cache = new BundleCache(m_logger, m_configMap);
                } catch (Exception ex) {
                    m_logger.log(Logger.LOG_ERROR, "Error creating bundle cache.", ex);
                    throw new BundleException("Error creating bundle cache.", ex);
                }
            }
            // we need to flush the bundle cache.
            if (getState() == Bundle.INSTALLED) {
                String clean = (String) m_configMap.get(Constants.FRAMEWORK_STORAGE_CLEAN);
                if ((clean != null) && clean.equalsIgnoreCase(Constants.FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT)) {
                    try {
                        m_cache.delete();
                    } catch (Exception ex) {
                        throw new BundleException("Unable to flush bundle cache.", ex);
                    }
                }
            }
            // Initialize installed bundle data structures.
            Map[] maps = new Map[] { new HashMap<String, BundleImpl>(1), new TreeMap<Long, BundleImpl>() };
            m_uninstalledBundles = new ArrayList<BundleImpl>(0);
            // Add the system bundle to the set of installed bundles.
            maps[LOCATION_MAP_IDX].put(_getLocation(), this);
            maps[IDENTIFIER_MAP_IDX].put(new Long(0), this);
            m_installedBundles = maps;
            // state to be set to RESOLVED.
            try {
                m_resolver.resolve(Collections.singleton(adapt(BundleRevision.class)), Collections.EMPTY_SET);
            } catch (ResolutionException ex) {
                // This should never happen.
                throw new BundleException("Unresolved constraint in System Bundle:" + ex.getUnresolvedRequirements());
            }
            // Reload the cached bundles before creating and starting the
            // system bundle, since we want all cached bundles to be reloaded
            // when we activate the system bundle and any subsequent system
            // bundle activators passed into the framework constructor.
            BundleArchive[] archives = null;
            // First get cached bundle identifiers.
            try {
                archives = m_cache.getArchives();
            } catch (Exception ex) {
                m_logger.log(Logger.LOG_ERROR, "Unable to list saved bundles.", ex);
                archives = null;
            }
            // Create system bundle activator and bundle context so we can activate it.
            setActivator(new SystemBundleActivator());
            setBundleContext(new BundleContextImpl(m_logger, this, this));
            boolean javaVersionChanged = handleJavaVersionChange();
            // Now load all cached bundles.
            for (int i = 0; (archives != null) && (i < archives.length); i++) {
                try {
                    // Keep track of the max bundle ID currently in use since we
                    // will need to use this as our next bundle ID value if the
                    // persisted value cannot be read.
                    m_nextId = Math.max(m_nextId, archives[i].getId() + 1);
                    // it now.
                    if (archives[i].getPersistentState() == Bundle.UNINSTALLED) {
                        archives[i].closeAndDelete();
                    } else // Otherwise re-install the cached bundle.
                    {
                        // Install the cached bundle.
                        reloadBundle(archives[i], javaVersionChanged);
                    }
                } catch (Exception ex) {
                    fireFrameworkEvent(FrameworkEvent.ERROR, this, ex);
                    try {
                        m_logger.log(Logger.LOG_ERROR, "Unable to re-install " + archives[i].getLocation(), ex);
                    } catch (Exception ex2) {
                        m_logger.log(Logger.LOG_ERROR, "Unable to re-install cached bundle.", ex);
                    }
                // TODO: FRAMEWORK - Perhaps we should remove the cached bundle?
                }
            }
            for (Bundle extension : m_extensionManager.resolveExtensionBundles(this)) {
                m_extensionManager.startExtensionBundle(this, (BundleImpl) extension);
            }
            // Now that we have loaded all cached bundles and have determined the
            // max bundle ID of cached bundles, we need to try to load the next
            // bundle ID from persistent storage. In case of failure, we should
            // keep the max value.
            m_nextId = Math.max(m_nextId, loadNextId());
            // The framework is now in its startup sequence.
            setBundleStateAndNotify(this, Bundle.STARTING);
            // Now it is possible for threads to wait for the framework to stop,
            // so create a gate for that purpose.
            m_shutdownGate = new ThreadGate();
            // add framework listeners
            if (listeners != null) {
                for (final FrameworkListener fl : listeners) {
                    addFrameworkListener(this, fl);
                }
            }
            // Start services
            m_resolver.start();
            m_fwkWiring.start();
            m_fwkStartLevel.start();
            try {
                Felix.m_secureAction.startActivator(getActivator(), _getBundleContext());
            } catch (Throwable ex) {
                m_dispatcher.stopDispatching();
                m_logger.log(Logger.LOG_ERROR, "Unable to start system bundle.", ex);
                throw new RuntimeException("Unable to start system bundle.");
            }
            // We have to check with the security provider (if there is one).
            // This is to avoid having bundles in the cache that have been tampered with
            SecurityProvider sp = getFramework().getSecurityProvider();
            if ((sp != null) && (System.getSecurityManager() != null)) {
                boolean locked = acquireGlobalLock();
                if (!locked) {
                    throw new BundleException("Unable to acquire the global lock to check the bundle.");
                }
                try {
                    for (Object bundle : m_installedBundles[IDENTIFIER_MAP_IDX].values()) {
                        try {
                            if (bundle != this) {
                                setBundleProtectionDomain(((BundleImpl) bundle).adapt(BundleRevisionImpl.class));
                            }
                        } catch (Exception ex) {
                            ((BundleImpl) bundle).close();
                            maps = new Map[] { new HashMap<String, BundleImpl>(m_installedBundles[LOCATION_MAP_IDX]), new TreeMap<Long, BundleImpl>(m_installedBundles[IDENTIFIER_MAP_IDX]) };
                            maps[LOCATION_MAP_IDX].remove(((BundleImpl) bundle)._getLocation());
                            maps[IDENTIFIER_MAP_IDX].remove(new Long(((BundleImpl) bundle).getBundleId()));
                            m_installedBundles = maps;
                            m_logger.log(Logger.LOG_ERROR, "Bundle in cache doesn't pass security check anymore.", ex);
                        }
                    }
                } finally {
                    // Always release the global lock.
                    releaseGlobalLock();
                }
            }
            m_extensionManager.startPendingExtensionBundles(Felix.this);
            m_fwkWiring.refreshBundles(null);
            // up class lookup for the system bundle.
            synchronized (m_systemBundleClassCache) {
                m_systemBundleClassCache.clear();
            }
        }
    } finally {
        releaseBundleLock(this);
        if (listeners != null) {
            for (final FrameworkListener fl : listeners) {
                removeFrameworkListener(this, fl);
            }
        }
    }
}
Also used : BundleArchive(org.apache.felix.framework.cache.BundleArchive) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) BundleException(org.osgi.framework.BundleException) Bundle(org.osgi.framework.Bundle) TreeMap(java.util.TreeMap) ServiceException(org.osgi.framework.ServiceException) BundleException(org.osgi.framework.BundleException) InvalidSyntaxException(org.osgi.framework.InvalidSyntaxException) FileNotFoundException(java.io.FileNotFoundException) AccessControlException(java.security.AccessControlException) ResolutionException(org.osgi.service.resolver.ResolutionException) MalformedURLException(java.net.MalformedURLException) IOException(java.io.IOException) ResolutionException(org.osgi.service.resolver.ResolutionException) SecurityProvider(org.apache.felix.framework.ext.SecurityProvider) BundleCache(org.apache.felix.framework.cache.BundleCache) FrameworkListener(org.osgi.framework.FrameworkListener) Map(java.util.Map) HashMap(java.util.HashMap) WeakHashMap(java.util.WeakHashMap) StringMap(org.apache.felix.framework.util.StringMap) TreeMap(java.util.TreeMap) ThreadGate(org.apache.felix.framework.util.ThreadGate)

Example 2 with ThreadGate

use of org.apache.felix.framework.util.ThreadGate in project felix by apache.

the class Felix method waitForStop.

/**
 * This method will cause the calling thread to block until the framework
 * shuts down.
 * @param timeout A timeout value.
 * @throws java.lang.InterruptedException If the thread was interrupted.
 */
@Override
public FrameworkEvent waitForStop(long timeout) throws InterruptedException {
    // Throw exception if timeout is negative.
    if (timeout < 0) {
        throw new IllegalArgumentException("Timeout cannot be negative.");
    }
    // If there is a gate, wait on it; otherwise, return immediately.
    // Grab a copy of the gate, since it is volatile.
    ThreadGate gate = m_shutdownGate;
    boolean open = false;
    if (gate != null) {
        open = gate.await(timeout);
    }
    FrameworkEvent event;
    if (open && (gate.getMessage() != null)) {
        event = (FrameworkEvent) gate.getMessage();
    } else if (!open && (gate != null)) {
        event = new FrameworkEvent(FrameworkEvent.WAIT_TIMEDOUT, this, null);
    } else {
        event = new FrameworkEvent(FrameworkEvent.STOPPED, this, null);
    }
    return event;
}
Also used : FrameworkEvent(org.osgi.framework.FrameworkEvent) ThreadGate(org.apache.felix.framework.util.ThreadGate)

Aggregations

ThreadGate (org.apache.felix.framework.util.ThreadGate)2 FileNotFoundException (java.io.FileNotFoundException)1 IOException (java.io.IOException)1 MalformedURLException (java.net.MalformedURLException)1 AccessControlException (java.security.AccessControlException)1 HashMap (java.util.HashMap)1 Map (java.util.Map)1 TreeMap (java.util.TreeMap)1 WeakHashMap (java.util.WeakHashMap)1 BundleArchive (org.apache.felix.framework.cache.BundleArchive)1 BundleCache (org.apache.felix.framework.cache.BundleCache)1 SecurityProvider (org.apache.felix.framework.ext.SecurityProvider)1 StringMap (org.apache.felix.framework.util.StringMap)1 Bundle (org.osgi.framework.Bundle)1 BundleException (org.osgi.framework.BundleException)1 FrameworkEvent (org.osgi.framework.FrameworkEvent)1 FrameworkListener (org.osgi.framework.FrameworkListener)1 InvalidSyntaxException (org.osgi.framework.InvalidSyntaxException)1 ServiceException (org.osgi.framework.ServiceException)1 ResolutionException (org.osgi.service.resolver.ResolutionException)1