diff options
author | Stephan Herrmann | 2018-06-12 12:37:36 +0000 |
---|---|---|
committer | Stephan Herrmann | 2018-06-12 12:37:36 +0000 |
commit | f1eaac55b3cb3ec434cbac7fb1b9867919972ebe (patch) | |
tree | 44edea71f35f6a34cfad8d7f2aa0f83df3b46e4b | |
parent | b99a8e323f1ee0e88f10697d2d60478488170deb (diff) | |
download | org.eclipse.objectteams-f1eaac55b3cb3ec434cbac7fb1b9867919972ebe.tar.gz org.eclipse.objectteams-f1eaac55b3cb3ec434cbac7fb1b9867919972ebe.tar.xz org.eclipse.objectteams-f1eaac55b3cb3ec434cbac7fb1b9867919972ebe.zip |
Bug 535804 - More gracefully handle the case of incomplete restart wrt
OT/Equinox agent
6 files changed, 61 insertions, 14 deletions
diff --git a/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/BundleContext.eea b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/BundleContext.eea index 5b8b11bdb..6f9f3e314 100644 --- a/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/BundleContext.eea +++ b/plugins/org.eclipse.objectteams.otequinox/annotations/plugins/org/osgi/framework/BundleContext.eea @@ -3,3 +3,7 @@ class org/osgi/framework/BundleContext getBundle ()Lorg/osgi/framework/Bundle; ()L1org/osgi/framework/Bundle; + +registerService + ([Ljava/lang/String;Ljava/lang/Object;Ljava/util/Dictionary<Ljava/lang/String;*>;)Lorg/osgi/framework/ServiceRegistration<*>; + ([Ljava/lang/String;Ljava/lang/Object;Ljava/util/Dictionary<Ljava/lang/String;*>;)L1org/osgi/framework/ServiceRegistration<*>; diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java index 86039a1a6..6e7b0af77 100644 --- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java +++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBinding.java @@ -33,6 +33,7 @@ import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; +import org.eclipse.objectteams.internal.osgi.weaving.DelegatingTransformer.OTAgentNotInstalled; import org.eclipse.objectteams.internal.osgi.weaving.OTWeavingHook.WeavingScheme; import org.eclipse.objectteams.internal.osgi.weaving.Util.ProfileKind; import org.eclipse.objectteams.otequinox.ActivationKind; @@ -296,7 +297,7 @@ public class AspectBinding { } /** Create an initial (unconnected) resolved team binding. */ - public TeamBinding createResolvedTeam(int count, String teamName, @Nullable String activationSpecifier, @Nullable String superTeamName) { + public TeamBinding createResolvedTeam(int count, String teamName, @Nullable String activationSpecifier, @Nullable String superTeamName) throws OTAgentNotInstalled { @NonNull ActivationKind kind = ActivationKind.NONE; try { if (activationSpecifier != null) @@ -308,7 +309,7 @@ public class AspectBinding { return this.teams[count] = new TeamBinding(teamName, kind, superTeamName); } - private void checkWeavingScheme(String className) { + private void checkWeavingScheme(String className) throws OTAgentNotInstalled { if (this.weavingScheme != WeavingScheme.Unknown) return; Bundle bundle = this.aspectBundle; @@ -319,7 +320,8 @@ public class AspectBinding { this.weavingScheme = ASMByteCodeAnalyzer.determineWeavingScheme(classStream, className); if (OTWeavingHook.DEFAULT_WEAVING_SCHEME == WeavingScheme.Unknown) { OTWeavingHook.DEFAULT_WEAVING_SCHEME = this.weavingScheme; - TransformerPlugin.doLog(IStatus.INFO, "Using weaving scheme "+this.weavingScheme+" as detected from class "+className); + TransformerPlugin.doLog(IStatus.INFO, "Using weaving scheme "+this.weavingScheme+" as detected from class "+className); + DelegatingTransformer.checkAgentAvailability(this.weavingScheme); } TransformerPlugin.log(IStatus.INFO, "use weaving scheme "+this.weavingScheme+" for aspectBinding "+this.aspectPlugin+"<-"+this.basePluginName); } catch (IOException e) { diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java index 184ccd266..cf9590395 100644 --- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java +++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java @@ -48,6 +48,7 @@ import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.BaseBundle; import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.TeamBinding; +import org.eclipse.objectteams.internal.osgi.weaving.DelegatingTransformer.OTAgentNotInstalled; import org.eclipse.objectteams.otequinox.Constants; import org.osgi.framework.Bundle; import org.osgi.framework.wiring.BundleWiring; @@ -89,7 +90,7 @@ public class AspectBindingRegistry { public void loadAspectBindings( IExtensionRegistry extensionRegistry, @SuppressWarnings("deprecation") @Nullable org.osgi.service.packageadmin.PackageAdmin packageAdmin, - OTWeavingHook hook) + OTWeavingHook hook) throws OTAgentNotInstalled { IConfigurationElement[] aspectBindingConfigs = extensionRegistry .getConfigurationElementsFor(TRANSFORMER_PLUGIN_ID, ASPECT_BINDING_EXTPOINT_ID); @@ -167,6 +168,8 @@ public class AspectBindingRegistry { hook.setBaseTripWire(packageAdmin, realBaseBundleId, baseBundle); log(IStatus.INFO, "registered:\n"+binding); + } catch (OTAgentNotInstalled otani) { + throw otani; } catch (Throwable t) { log(t, "Invalid aspectBinding extension"); } @@ -191,7 +194,7 @@ public class AspectBindingRegistry { private AspectBinding addSuperBase(IConfigurationElement superBase, String aspectBundleId, @Nullable Bundle aspectBundle, BaseBundle baseBundle, TeamBinding teamBinding, @SuppressWarnings("deprecation") @Nullable org.osgi.service.packageadmin.PackageAdmin packageAdmin, - OTWeavingHook hook) + OTWeavingHook hook) throws OTAgentNotInstalled { String superBaseClass = superBase.getAttribute(SUPER_BASE_CLASS); String superBasePlugin = superBase.getAttribute(SUPER_BASE_PLUGIN); diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java index 68f199480..ce2379a3f 100644 --- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java +++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/DelegatingTransformer.java @@ -42,6 +42,26 @@ import org.osgi.framework.wiring.BundleWiring; */ public abstract class DelegatingTransformer { + static final String OT_EQUINOX_DEBUG_AGENT = "org.eclipse.objectteams.otequinox.OTEquinoxAgent"; + + @SuppressWarnings("serial") + public static class OTAgentNotInstalled extends Exception { + OTAgentNotInstalled() { + super("Agent class "+DelegatingTransformer.OT_EQUINOX_DEBUG_AGENT+" was not installed. OT/Equinox will be desabled.\n" + + "If this happens during the restart after installing OT/Equinox, please exit Eclipse and perform a fresh start."); + } + } + + static void checkAgentAvailability(WeavingScheme weavingScheme) throws OTAgentNotInstalled { + if (weavingScheme == WeavingScheme.OTDRE) { + try { + ClassLoader.getSystemClassLoader().loadClass(DelegatingTransformer.OT_EQUINOX_DEBUG_AGENT); + } catch (ClassNotFoundException cnfe) { + throw new OTAgentNotInstalled(); + } + } + } + /** Factory method for a fresh transformer. */ static @NonNull DelegatingTransformer newTransformer(WeavingScheme weavingScheme, OTWeavingHook hook, BundleWiring wiring) { switch (weavingScheme) { @@ -90,9 +110,8 @@ public abstract class DelegatingTransformer { } } - /** Enable OTDRE to use the OTEquinoxDebugAgent, if present, for class redefinition. */ + /** Enable OTDRE to use the OTEquinoxAgent, if present, for class redefinition. */ private static class OTEquinoxRedefineStrategy implements IRedefineStrategy { - private static final String OT_EQUINOX_DEBUG_AGENT = "org.eclipse.objectteams.otequinox.OTEquinoxAgent"; public void redefine(Class<?> clazz, byte[] bytecode) throws ClassNotFoundException, UnmodifiableClassException { ClassDefinition arr_cd[] = { new ClassDefinition(clazz, bytecode) }; diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java index a952a2db5..bc348cf15 100644 --- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java +++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java @@ -44,6 +44,7 @@ import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.BaseBundle; import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding.TeamBinding; import org.eclipse.objectteams.internal.osgi.weaving.Util.ProfileKind; import org.eclipse.objectteams.internal.osgi.weaving.AspectPermissionManager; +import org.eclipse.objectteams.internal.osgi.weaving.DelegatingTransformer.OTAgentNotInstalled; import org.eclipse.objectteams.otequinox.Constants; import org.eclipse.objectteams.otequinox.TransformerPlugin; import org.eclipse.objectteams.runtime.IReweavingTask; @@ -143,7 +144,7 @@ public class OTWeavingHook implements WeavingHook, WovenClassListener { private @Nullable Class<?> ooTeam; /** Call-back once the extension registry is up and running. */ - public void activate(@NonNull BundleContext bundleContext, ServiceReference<IExtensionRegistry> serviceReference) { + public void activate(@NonNull BundleContext bundleContext, ServiceReference<IExtensionRegistry> serviceReference) throws OTAgentNotInstalled { loadAspectBindingRegistry(bundleContext, serviceReference); TransformerPlugin.initialize(bundleContext, this.aspectBindingRegistry, this.permissionManager); } @@ -151,7 +152,7 @@ public class OTWeavingHook implements WeavingHook, WovenClassListener { // ====== Aspect Bindings & Permissions: ====== @SuppressWarnings("deprecation") - private void loadAspectBindingRegistry(BundleContext context, ServiceReference<IExtensionRegistry> serviceReference) { + private void loadAspectBindingRegistry(BundleContext context, ServiceReference<IExtensionRegistry> serviceReference) throws OTAgentNotInstalled { org.osgi.service.packageadmin.PackageAdmin packageAdmin = null; ServiceReference<?> ref= context.getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName()); diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java index 73052a551..e926da279 100644 --- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java +++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/otequinox/TransformerPlugin.java @@ -32,11 +32,13 @@ import org.eclipse.equinox.log.ExtendedLogReaderService; import org.eclipse.equinox.log.ExtendedLogService; import org.eclipse.equinox.log.LogFilter; import org.eclipse.equinox.log.Logger; +import org.eclipse.jdt.annotation.NonNull; import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.Nullable; import org.eclipse.objectteams.internal.osgi.weaving.AspectBinding; import org.eclipse.objectteams.internal.osgi.weaving.AspectBindingRegistry; import org.eclipse.objectteams.internal.osgi.weaving.AspectPermissionManager; +import org.eclipse.objectteams.internal.osgi.weaving.DelegatingTransformer.OTAgentNotInstalled; import org.eclipse.objectteams.internal.osgi.weaving.OTWeavingHook; import org.eclipse.objectteams.otre.ClassLoaderAccess; import org.objectteams.Team; @@ -47,6 +49,7 @@ import org.osgi.framework.InvalidSyntaxException; import org.osgi.framework.ServiceEvent; import org.osgi.framework.ServiceListener; import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; import org.osgi.framework.hooks.weaving.WeavingHook; import org.osgi.framework.hooks.weaving.WovenClassListener; import org.osgi.service.log.LogEntry; @@ -146,20 +149,22 @@ public class TransformerPlugin implements BundleActivator, IAspectRegistry { // register our weaving service: final OTWeavingHook otWeavingHook = new OTWeavingHook(); - bundleContext.registerService(new String[] { WeavingHook.class.getName(), WovenClassListener.class.getName() }, + final ServiceRegistration<?> registration = bundleContext.registerService(new String[] { WeavingHook.class.getName(), WovenClassListener.class.getName() }, otWeavingHook, null); // but wait until the extension registry is available for reading aspectBindings: try { ServiceReference<IExtensionRegistry> reference = bundleContext.getServiceReference(IExtensionRegistry.class); if (reference != null) { - otWeavingHook.activate(bundleContext, reference); + safeActivateHook(otWeavingHook, bundleContext, reference, registration); } else { bundleContext.addServiceListener( - new ServiceListener() { + new ServiceListener() { public void serviceChanged(ServiceEvent event) { - if(event.getType() == ServiceEvent.REGISTERED) - otWeavingHook.activate(bundleContext, bundleContext.getServiceReference(IExtensionRegistry.class)); + if(event.getType() == ServiceEvent.REGISTERED) { + ServiceReference<IExtensionRegistry> extensionService = bundleContext.getServiceReference(IExtensionRegistry.class); + safeActivateHook(otWeavingHook, bundleContext, extensionService, registration); + } } }, "(objectclass="+IExtensionRegistry.class.getName()+")"); //$NON-NLS-1$ //$NON-NLS-2$ @@ -173,6 +178,19 @@ public class TransformerPlugin implements BundleActivator, IAspectRegistry { log(IStatus.INFO, "agentURL="+agentURL); } + private void safeActivateHook(OTWeavingHook otWeavingHook, BundleContext bundleContext, + @Nullable ServiceReference<IExtensionRegistry> extensionService, ServiceRegistration<?> registration) { + try { + otWeavingHook.activate(bundleContext, extensionService); + } catch (OTAgentNotInstalled e) { + registration.unregister(); + ILog log = acquireLog(bundleContext); + log.log(new Status(IStatus.ERROR, + bundleContext.getBundle().getSymbolicName(), + "Error activating OT/Equinox: "+e.getMessage())); + } + } + @SuppressWarnings("restriction") private static ILog acquireLog(BundleContext bundleContext) { ServiceTracker<ExtendedLogService,ExtendedLogService> tracker |