public void init()

in framework/src/main/java/org/apache/felix/framework/Felix.java [656:991]


    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("true".equalsIgnoreCase(_getProperty(FelixConstants.FRAMEWORK_UUID_SECURE))));

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

                // If this is the first time init is called, check to see if
                // 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);
                        }
                    }
                    if (m_connectFramework != null)
                    {
                        m_connectFramework.initialize(m_cache.getCacheDir(), (Map) m_configMap);
                    }
                }

                // Initialize installed bundle data structures.
                Map[] maps = new Map[] {
                    new HashMap<String, BundleImpl>(1),
                    new TreeMap<Long, BundleImpl>()
                };
                m_uninstalledBundles = new ArrayList<>(0);

                // Add the system bundle to the set of installed bundles.
                maps[LOCATION_MAP_IDX].put(_getLocation(), this);
                maps[IDENTIFIER_MAP_IDX].put(0L, this);
                m_installedBundles = maps;


                try
                {
                    getResolver().removeRevision(m_extensionManager.getRevision());
                    m_extensionManager.removeExtensionBundles();
                    m_extensionManager.updateRevision(this, m_configMap);
                    if (!m_configMutableMap.containsKey(Constants.FRAMEWORK_SYSTEMPACKAGES))
                    {
                        m_configMutableMap.put(Constants.FRAMEWORK_SYSTEMPACKAGES, m_extensionManager.getRevision().getHeaders().get(Constants.EXPORT_PACKAGE));
                    }
                    getResolver().addRevision(m_extensionManager.getRevision());
                }
                catch (Exception ex)
                {
                    // This should not throw an exception, but if so, lets convert it to
                    // a runtime exception.
                    throw new BundleException("Exception creating system bundle revision", ex);
                }

                // Manually resolve the system bundle, which will cause its
                // state to be set to RESOLVED.
                try
                {
                    m_resolver.resolve(
                        Collections.singleton(adapt(BundleRevision.class)),
                        Collections.emptySet());
                }
                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(m_connectFramework);
                }
                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 is possible that a bundle in the cache was previously
                        // uninstalled, but not completely deleted (perhaps because
                        // of a crash or a locked file), so if we see an archive
                        // with an UNINSTALLED persistent state, then try to remove
                        // it now.
                        if (archives[i].getPersistentState() == Bundle.UNINSTALLED)
                        {
                            archives[i].closeAndDelete();
                        }
                        // Otherwise re-install the cached bundle.
                        else
                        {
                            // 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);
                }


                if (m_connectFramework != null)
                {
                    m_connectFramework.newBundleActivator().ifPresent(m_activatorList::add);
                }

                // 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_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(Long.valueOf(((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);

                // Clear the cache of classes coming from the system bundle.
                // This is only used for Felix.getBundle(Class clazz) to speed
                // up class lookup for the system bundle.
                synchronized (m_systemBundleClassCache)
                {
                    m_systemBundleClassCache.clear();
                }
            }
        }
        catch (Throwable t)
        {
            stopBundle(this, false);
            if (m_cache != null)
            {
                m_cache.release();
                m_cache = null;
            }
            __setState(Bundle.INSTALLED);
            throw t;
        }
        finally
        {
            releaseBundleLock(this);

            if ( listeners != null )
            {
                for(final FrameworkListener fl : listeners)
                {
                    removeFrameworkListener(this, fl);
                }
            }
        }
    }