use of org.apache.felix.framework.cache.BundleCache 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);
}
}
}
}
Aggregations