diff options
author | Thomas Watson | 2006-03-17 20:34:34 +0000 |
---|---|---|
committer | Thomas Watson | 2006-03-17 20:34:34 +0000 |
commit | 4a5fa3cc9116a49b55db7f9296fe24dd0d29d72c (patch) | |
tree | b6165fef95e9b972e8f4f1949baf87325c4b732b | |
parent | ae17b137d9a857e925149f706498edcd1b63ba5b (diff) | |
download | rt.equinox.framework-4a5fa3cc9116a49b55db7f9296fe24dd0d29d72c.tar.gz rt.equinox.framework-4a5fa3cc9116a49b55db7f9296fe24dd0d29d72c.tar.xz rt.equinox.framework-4a5fa3cc9116a49b55db7f9296fe24dd0d29d72c.zip |
Bug 131846 Explicitly started bundles should be persistently started even if they are marked for lazy startv20060317
3 files changed, 68 insertions, 33 deletions
diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/BundleStopper.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/BundleStopper.java index a3d70895e..56a5a5de3 100644 --- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/BundleStopper.java +++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/BundleStopper.java @@ -14,8 +14,7 @@ import java.util.Hashtable; import org.eclipse.osgi.baseadaptor.BaseData; import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor; import org.eclipse.osgi.framework.debug.Debug; -import org.eclipse.osgi.framework.internal.core.AbstractBundle; -import org.eclipse.osgi.framework.internal.core.BundleHost; +import org.eclipse.osgi.framework.internal.core.*; import org.eclipse.osgi.framework.log.FrameworkLogEntry; import org.eclipse.osgi.service.resolver.BundleDescription; import org.eclipse.osgi.service.resolver.StateHelper; @@ -36,6 +35,7 @@ public class BundleStopper { private BundleDescription[] allToStop = null; private BundleContext context; private FrameworkAdaptor adaptor; + private boolean stopping; public BundleStopper(BundleContext context, FrameworkAdaptor adaptor) { this.context = context; @@ -74,6 +74,7 @@ public class BundleStopper { } private void basicStopBundles() { + stopping = true; // stop all active bundles in the reverse order of Require-Bundle for (int stoppingIndex = allToStop.length - 1; stoppingIndex >= 0; stoppingIndex--) { AbstractBundle toStop = (AbstractBundle) context.getBundle(allToStop[stoppingIndex].getBundleId()); @@ -81,8 +82,13 @@ public class BundleStopper { EclipseStorageHook storageHook = (EclipseStorageHook) bundledata.getStorageHook(EclipseStorageHook.KEY); if (toStop.getBundleId() != 0 && storageHook != null && storageHook.isAutoStartable()) { try { - if ((toStop.getState() == Bundle.ACTIVE) && (toStop instanceof BundleHost)) + if ((toStop.getState() == Bundle.ACTIVE) && (toStop instanceof BundleHost)) { toStop.stop(); + // if a lazy started bundle was explicitly started, + // then make sure it keeps the persistenly started bit + if (!storageHook.isActivatedOnClassLoad()) + bundledata.setStatus(Constants.BUNDLE_STARTED); + } } catch (Exception e) { String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_BUNDLESTOPPER_ERROR_STOPPING_BUNDLE, allToStop[stoppingIndex].toString()); FrameworkLogEntry entry = new FrameworkLogEntry(FrameworkAdaptor.FRAMEWORK_SYMBOLICNAME, FrameworkLogEntry.ERROR, 0, message, 0, e, null); @@ -92,6 +98,7 @@ public class BundleStopper { } } } + stopping = false; } public boolean isStopped(Bundle bundle) { @@ -99,4 +106,8 @@ public class BundleStopper { return false; return stoppedBundles.get(bundle) != null; } + + public boolean isStopping() { + return stopping; + } } diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLazyStarter.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLazyStarter.java index a1a5190a3..cc2a31f4f 100644 --- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLazyStarter.java +++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseLazyStarter.java @@ -15,7 +15,6 @@ import java.net.URL; import org.eclipse.core.runtime.internal.stats.StatsManager; import org.eclipse.osgi.baseadaptor.*; import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry; -import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook; import org.eclipse.osgi.baseadaptor.hooks.ClassLoadingStatsHook; import org.eclipse.osgi.baseadaptor.loader.ClasspathEntry; import org.eclipse.osgi.baseadaptor.loader.ClasspathManager; @@ -35,8 +34,9 @@ public class EclipseLazyStarter implements ClassLoadingStatsHook, HookConfigurat if ((bundle.getState() & (Bundle.ACTIVE | Bundle.UNINSTALLED | Bundle.STOPPING)) != 0) return; + EclipseStorageHook storageHook = (EclipseStorageHook) manager.getBaseData().getStorageHook(EclipseStorageHook.KEY); // The bundle is not active and does not require activation, just return the class - if (!shouldActivateFor(name, manager.getBaseData())) + if (!shouldActivateFor(name, manager.getBaseData(), storageHook)) return; // The bundle is starting. Note that if the state changed between the tests @@ -80,6 +80,9 @@ public class EclipseLazyStarter implements ClassLoadingStatsHook, HookConfigurat //The bundle must be started. try { + // mark this bundle as lazy activated by class load + if (storageHook != null) + storageHook.setActivatedOnClassLoad(true); bundle.start(); } catch (BundleException e) { String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_ACTIVATION, bundle.getSymbolicName(), Long.toString(bundle.getBundleId())); @@ -105,12 +108,12 @@ public class EclipseLazyStarter implements ClassLoadingStatsHook, HookConfigurat // do nothing } - private boolean shouldActivateFor(String className, BaseData bundledata) throws ClassNotFoundException { - if (!isAutoStartable(className, bundledata)) + private boolean shouldActivateFor(String className, BaseData bundledata, EclipseStorageHook storageHook) throws ClassNotFoundException { + if (!isAutoStartable(className, bundledata, storageHook)) return false; //Don't reactivate on shut down if (bundledata.getAdaptor().isStopping()) { - BundleStopper stopper = getBundleStopper(bundledata); + BundleStopper stopper = EclipseStorageHook.getBundleStopper(bundledata); if (stopper != null && stopper.isStopped(bundledata.getBundle())) { String message = NLS.bind(EclipseAdaptorMsg.ECLIPSE_CLASSLOADER_ALREADY_STOPPED, className, bundledata.getSymbolicName()); throw new ClassNotFoundException(message); @@ -119,8 +122,7 @@ public class EclipseLazyStarter implements ClassLoadingStatsHook, HookConfigurat return true; } - private boolean isAutoStartable(String className, BaseData bundledata) { - EclipseStorageHook storageHook = (EclipseStorageHook) bundledata.getStorageHook(EclipseStorageHook.KEY); + private boolean isAutoStartable(String className, BaseData bundledata, EclipseStorageHook storageHook) { if (storageHook == null) return false; boolean autoStart = storageHook.isAutoStart(); @@ -145,14 +147,6 @@ public class EclipseLazyStarter implements ClassLoadingStatsHook, HookConfigurat return false; } - private BundleStopper getBundleStopper(BaseData bundledata) { - AdaptorHook[] adaptorhooks = bundledata.getAdaptor().getHookRegistry().getAdaptorHooks(); - for (int i = 0; i < adaptorhooks.length; i++) - if (adaptorhooks[i] instanceof EclipseAdaptorHook) - return ((EclipseAdaptorHook) adaptorhooks[i]).getBundleStopper(); - return null; - } - public void addHooks(HookRegistry hookRegistry) { hookRegistry.addClassLoadingStatsHook(this); } diff --git a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseStorageHook.java b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseStorageHook.java index e619b67ea..d416c6e0e 100644 --- a/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseStorageHook.java +++ b/bundles/org.eclipse.osgi/eclipseAdaptor/src/org/eclipse/core/runtime/internal/adaptor/EclipseStorageHook.java @@ -16,6 +16,7 @@ import java.net.URL; import java.util.*; import org.eclipse.core.runtime.adaptor.LocationManager; import org.eclipse.osgi.baseadaptor.*; +import org.eclipse.osgi.baseadaptor.hooks.AdaptorHook; import org.eclipse.osgi.baseadaptor.hooks.StorageHook; import org.eclipse.osgi.framework.adaptor.FrameworkAdaptor; import org.eclipse.osgi.framework.internal.core.Constants; @@ -34,11 +35,15 @@ import org.osgi.framework.Version; public final class EclipseStorageHook implements StorageHook, HookConfigurator { // System property used to check timestamps of the bundles in the configuration private static final String PROP_CHECK_CONFIG = "osgi.checkConfiguration"; //$NON-NLS-1$ - private static final int STORAGE_VERION = 1; + private static final int STORAGE_VERION = 2; public static final String KEY = EclipseStorageHook.class.getName(); public static final int HASHCODE = KEY.hashCode(); + private static final byte FLAG_AUTO_START = 0x01; + private static final byte FLAG_HAS_PACKAGE_INFO = 0x02; + private static final byte FLAG_ACTIVATE_ON_CLASSLOAD = 0x04; + /** data to detect modification made in the manifest */ private long manifestTimeStamp = 0; private byte manifestType = PluginConverterImpl.MANIFEST_TYPE_UNKNOWN; @@ -48,14 +53,12 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { /** the Plugin-Class header */ private String pluginClass = null; /** Eclipse-LazyStart header */ - private boolean autoStart; private String[] autoStartExceptions; /** shortcut to know if a bundle has a buddy */ private String buddyList; /** shortcut to know if a bundle is a registrant to a registered policy */ private String registeredBuddyList; - /** shortcut to know if the bundle manifest has package info */ - private boolean hasPackageInfo; + private byte flags = 0; public int getStorageVersion() { return STORAGE_VERION; @@ -75,7 +78,8 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { pluginClass = (String) manifest.get(Constants.PLUGIN_CLASS); buddyList = (String) manifest.get(Constants.BUDDY_LOADER); registeredBuddyList = (String) manifest.get(Constants.REGISTERED_POLICY); - hasPackageInfo = hasPackageInfo(bundledata.getEntry(Constants.OSGI_BUNDLE_MANIFEST)); + if (hasPackageInfo(bundledata.getEntry(Constants.OSGI_BUNDLE_MANIFEST))) + flags |= FLAG_HAS_PACKAGE_INFO; String genFrom = (String) manifest.get(PluginConverterImpl.GENERATED_FROM); if (genFrom != null) { ManifestElement generatedFrom = ManifestElement.parseHeader(PluginConverterImpl.GENERATED_FROM, genFrom)[0]; @@ -89,12 +93,11 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { public StorageHook load(BaseData target, DataInputStream in) throws IOException { EclipseStorageHook storageHook = new EclipseStorageHook(); storageHook.bundledata = target; - storageHook.autoStart = in.readBoolean(); + storageHook.flags = in.readByte(); int exceptionsCount = in.readInt(); storageHook.autoStartExceptions = exceptionsCount > 0 ? new String[exceptionsCount] : null; for (int i = 0; i < exceptionsCount; i++) storageHook.autoStartExceptions[i] = in.readUTF(); - storageHook.hasPackageInfo = in.readBoolean(); storageHook.buddyList = AdaptorUtil.readString(in, false); storageHook.registeredBuddyList = AdaptorUtil.readString(in, false); storageHook.pluginClass = AdaptorUtil.readString(in, false); @@ -106,7 +109,8 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { public void save(DataOutputStream out) throws IOException { if (bundledata == null) throw new IllegalStateException(); - out.writeBoolean(isAutoStart()); + // do not write the activate on classload bit; this should be reset each startup + out.writeByte(flags & ~FLAG_ACTIVATE_ON_CLASSLOAD); String[] autoStartExceptions = getAutoStartExceptions(); if (autoStartExceptions == null) out.writeInt(0); @@ -115,7 +119,6 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { for (int i = 0; i < autoStartExceptions.length; i++) out.writeUTF(autoStartExceptions[i]); } - out.writeBoolean(hasPackageInfo()); AdaptorUtil.writeStringOrNull(out, getBuddyList()); AdaptorUtil.writeStringOrNull(out, getRegisteredBuddyList()); AdaptorUtil.writeStringOrNull(out, getPluginClass()); @@ -136,7 +139,7 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { } public boolean isAutoStart() { - return autoStart; + return (flags & FLAG_AUTO_START) == FLAG_AUTO_START; } public String[] getAutoStartExceptions() { @@ -148,7 +151,7 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { } public boolean hasPackageInfo() { - return hasPackageInfo; + return (flags & FLAG_HAS_PACKAGE_INFO) == FLAG_HAS_PACKAGE_INFO; } public String getPluginClass() { @@ -173,11 +176,10 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { * @return true if the bundle is auto started; false otherwise */ public boolean isAutoStartable() { - return autoStart || (autoStartExceptions != null && autoStartExceptions.length > 0); + return isAutoStart() || (autoStartExceptions != null && autoStartExceptions.length > 0); } private void parseLazyStart(EclipseStorageHook storageHook, String headerValue) { - storageHook.autoStart = false; storageHook.autoStartExceptions = null; ManifestElement[] allElements = null; try { @@ -191,7 +193,8 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { if (allElements == null) return; // the single value for this element should be true|false - storageHook.autoStart = "true".equalsIgnoreCase(allElements[0].getValue()); //$NON-NLS-1$ + if ("true".equalsIgnoreCase(allElements[0].getValue())) //$NON-NLS-1$ + flags |= FLAG_AUTO_START; // look for any exceptions (the attribute) to the autoActivate setting String exceptionsValue = allElements[0].getAttribute(Constants.ECLIPSE_LAZYSTART_EXCEPTIONS); if (exceptionsValue == null) @@ -393,7 +396,15 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { } public boolean forgetStatusChange(int status) { - return isAutoStartable(); + if (!isAutoStartable()) + return false; + if (!isActivatedOnClassLoad()) { + // want to persistenly start/stop lazy started bundles which were explicitely started/stopped + // we only want to do this if the framework is not in the process of being stopped + BundleStopper stopper = getBundleStopper(bundledata); + return stopper == null ? false : stopper.isStopping(); + } + return true; } public boolean forgetStartLevelChange(int startlevel) { @@ -403,4 +414,23 @@ public final class EclipseStorageHook implements StorageHook, HookConfigurator { public boolean matchDNChain(String pattern) { return false; } + + void setActivatedOnClassLoad(boolean classLoadActivate) { + if (classLoadActivate) + flags |= FLAG_ACTIVATE_ON_CLASSLOAD; + else + flags &= ~FLAG_ACTIVATE_ON_CLASSLOAD; + } + + boolean isActivatedOnClassLoad() { + return (flags & FLAG_ACTIVATE_ON_CLASSLOAD) == FLAG_ACTIVATE_ON_CLASSLOAD; + } + + static BundleStopper getBundleStopper(BaseData bundledata) { + AdaptorHook[] adaptorhooks = bundledata.getAdaptor().getHookRegistry().getAdaptorHooks(); + for (int i = 0; i < adaptorhooks.length; i++) + if (adaptorhooks[i] instanceof EclipseAdaptorHook) + return ((EclipseAdaptorHook) adaptorhooks[i]).getBundleStopper(); + return null; + } } |