Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStephan Herrmann2013-04-25 16:05:25 +0000
committerStephan Herrmann2013-04-25 16:08:22 +0000
commit3771169b139cded7ad5a574c120359a50c1f0993 (patch)
treea00f7b86e5beb17543bdd83ecf0cebd9614515dd
parentced29e7c82bdf2ab6232e92f4db23a09f7862b0c (diff)
downloadorg.eclipse.objectteams-3771169b139cded7ad5a574c120359a50c1f0993.tar.gz
org.eclipse.objectteams-3771169b139cded7ad5a574c120359a50c1f0993.tar.xz
org.eclipse.objectteams-3771169b139cded7ad5a574c120359a50c1f0993.zip
Bug 406518 - migrate OT/Equinox to the standard OSGi WeavingHooksherrmann/osgi.WeavingHook
- register also as a WovenClassListener to instantiate deferred teams
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF1
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/OSGI-INF/weavinghook.xml1
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java45
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java54
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/TeamLoader.java8
-rw-r--r--plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java15
6 files changed, 72 insertions, 52 deletions
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF b/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF
index 46c0025ea..6657733b5 100644
--- a/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/META-INF/MANIFEST.MF
@@ -9,6 +9,7 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.objectteams.runtime;bundle-version="2.1.0",
org.eclipse.osgi,
org.eclipse.equinox.ds;bundle-version="1.4.100"
+Import-Package: org.osgi.service.component;version="1.2.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
Bundle-ActivationPolicy: lazy
Service-Component: OSGI-INF/weavinghook.xml
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/OSGI-INF/weavinghook.xml b/plugins/org.eclipse.objectteams.osgi.weaving/OSGI-INF/weavinghook.xml
index 31f3c9de4..9253e2645 100644
--- a/plugins/org.eclipse.objectteams.osgi.weaving/OSGI-INF/weavinghook.xml
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/OSGI-INF/weavinghook.xml
@@ -3,5 +3,6 @@
<implementation class="org.eclipse.objectteams.internal.osgi.weaving.OTWeavingHook"/>
<service>
<provide interface="org.osgi.framework.hooks.weaving.WeavingHook"/>
+ <provide interface="org.osgi.framework.hooks.weaving.WovenClassListener"/>
</service>
</component> \ No newline at end of file
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java
index 3cb24f9cf..295bca944 100644
--- a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/AspectBindingRegistry.java
@@ -110,8 +110,6 @@ public class AspectBindingRegistry {
}
// records of teams that have been deferred due to unresolved class dependencies:
private List<WaitingTeamRecord> deferredTeams = new ArrayList<>();
- // records of teams whose class dependencies should/could be unblocked by now:
- private List<WaitingTeamRecord> scheduledTeams = new ArrayList<>();
public static boolean IS_OTDT = false;
@@ -323,37 +321,32 @@ public class AspectBindingRegistry {
}
/** Record the given team classes as waiting for instantiation/activation. */
- public synchronized void addDeferredTeamClasses(List<WaitingTeamRecord> teamClasses) {
- deferredTeams.addAll(teamClasses);
- }
-
- /**
- * Check if the given class has been recorded as not-found before,
- * If so, unblock the team class(es) that depend on this class
- */
- public synchronized void scheduleTeamClassesFor(@Nullable String className) {
- List<WaitingTeamRecord> currentList = deferredTeams;
- deferredTeams = new ArrayList<>();
- for (WaitingTeamRecord record : currentList) {
- if (record.notFoundClass.equals(className))
- scheduledTeams.add(record);
- else
- deferredTeams.add(record);
+ public void addDeferredTeamClasses(List<WaitingTeamRecord> teamClasses) {
+ synchronized (deferredTeams) {
+ deferredTeams.addAll(teamClasses);
}
}
/**
- * Try to instantiate/activate any deferred teams that have been unblocked by now.
+ * Try to instantiate/activate any deferred teams that may be unblocked
+ * by the definition of the given trigger class.
*/
- public void instantiateScheduledTeams() {
- List<WaitingTeamRecord> currentList;
- synchronized (this) {
- currentList = scheduledTeams;
- scheduledTeams = new ArrayList<>();
+ public void instantiateScheduledTeams(String triggerClassName) {
+ List<WaitingTeamRecord> scheduledTeams = null;
+ synchronized(deferredTeams) {
+ for (WaitingTeamRecord record : new ArrayList<>(deferredTeams)) {
+ if (record.notFoundClass.equals(triggerClassName)) {
+ if (scheduledTeams == null)
+ scheduledTeams = new ArrayList<>();
+ if (deferredTeams.remove(record))
+ scheduledTeams.add(record);
+ }
+ }
}
- for(WaitingTeamRecord record : currentList) {
+ if (scheduledTeams == null) return;
+ for(WaitingTeamRecord record : scheduledTeams) {
try {
- new TeamLoader(deferredTeams).instantiateWaitingTeam(record);
+ new TeamLoader(deferredTeams).instantiateWaitingTeam(record); // may re-insert to deferredTeams
} catch (Exception e) {
log(e, "Failed to instantiate team "+record.getTeamName());
continue;
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
index 3371dfc59..18dde181e 100644
--- a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/OTWeavingHook.java
@@ -23,32 +23,62 @@ import java.security.ProtectionDomain;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.objectteams.osgi.weaving.Activator;
+import org.eclipse.objectteams.otequinox.hook.ILogger;
import org.eclipse.objectteams.otre.jplis.ObjectTeamsTransformer;
import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.osgi.framework.hooks.weaving.WeavingHook;
import org.osgi.framework.hooks.weaving.WovenClass;
+import org.osgi.framework.hooks.weaving.WovenClassListener;
import org.osgi.framework.wiring.BundleWiring;
+import org.osgi.service.component.ComponentContext;
+
/**
* This class integrates the OT/J weaver into OSGi using the standard API {@link WeavingHook}.
+ * <p>
+ * Additionally, we listen to events of woven classes changing to state {@link WovenClass#DEFINED}:
+ * </p>
+ * <ul>
+ * <li>Given that {@link AspectBindingRegistry#addDeferredTeamClasses} was used to record
+ * teams that could not be instantiated due to some required class being reported
+ * as {@link NoClassDefFoundError}.</li>
+ * <li>Assuming further that this error happened because the required class was in the process
+ * of being loaded further down the call stack.</li>
+ * <li>If later one of the not-found classes has been defined we use that trigger to
+ * re-attempt instantiating the dependent team(s).</li>
+ * </ul>
*/
-public class OTWeavingHook implements WeavingHook {
+public class OTWeavingHook implements WeavingHook, WovenClassListener {
private AspectBindingRegistry aspectBindingRegistry;
private ObjectTeamsTransformer objectTeamsTransformer;
- public OTWeavingHook() {
- this.aspectBindingRegistry = Activator.loadAspectBindingRegistry();
+ /** Call-back from DS framework. */
+ public void activate(ComponentContext context) {
+ this.aspectBindingRegistry = loadAspectBindingRegistry(context.getBundleContext());
this.objectTeamsTransformer = new ObjectTeamsTransformer();
}
+ @SuppressWarnings("deprecation")
+ private AspectBindingRegistry loadAspectBindingRegistry(BundleContext context) {
+ org.osgi.service.packageadmin.PackageAdmin packageAdmin = null;;
+
+ ServiceReference<?> ref= context.getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName());
+ if (ref!=null)
+ packageAdmin = (org.osgi.service.packageadmin.PackageAdmin)context.getService(ref);
+ else
+ log(ILogger.ERROR, "Failed to load PackageAdmin service. Will not be able to handle fragments.");
+
+ AspectBindingRegistry aspectBindingRegistry = new AspectBindingRegistry();
+ aspectBindingRegistry.loadAspectBindings(packageAdmin);
+ return aspectBindingRegistry;
+ }
+
@Override
public void weave(WovenClass wovenClass) {
try {
- // TODO(SH): ideally this trigger would be inserted into the previous woven class
- // do whatever left-overs we find from previous invocations:
- aspectBindingRegistry.instantiateScheduledTeams();
-
BundleWiring bundleWiring = wovenClass.getBundleWiring();
String bundleName = bundleWiring.getBundle().getSymbolicName();
String className = wovenClass.getClassName();
@@ -70,12 +100,18 @@ public class OTWeavingHook implements WeavingHook {
log(e, "Failed to transform class "+className);
}
}
- // unblock any waiting teams depending on this class:
- aspectBindingRegistry.scheduleTeamClassesFor(className);
} catch (ClassCircularityError cce) {
log(cce, "Weaver encountered a circular class dependency");
}
}
+
+ @Override
+ public void modified(WovenClass wovenClass) {
+ if (wovenClass.getState() == WovenClass.DEFINED) {
+ @SuppressWarnings("null") @NonNull String className = wovenClass.getClassName();
+ aspectBindingRegistry.instantiateScheduledTeams(className);
+ }
+ }
private boolean requiresWeaving(BundleWiring bundleWiring) {
@SuppressWarnings("null")@NonNull
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/TeamLoader.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/TeamLoader.java
index 794d7289c..fc21590ca 100644
--- a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/TeamLoader.java
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/internal/osgi/weaving/TeamLoader.java
@@ -101,7 +101,9 @@ public class TeamLoader {
return instance;
} catch (NoClassDefFoundError ncdfe) {
needDeferring = true;
- deferredTeams.add(new WaitingTeamRecord(teamClass, aspectBinding, ncdfe.getMessage().replace('/','.')));
+ synchronized(deferredTeams) {
+ deferredTeams.add(new WaitingTeamRecord(teamClass, aspectBinding, ncdfe.getMessage().replace('/','.')));
+ }
} catch (Throwable e) {
// application error during constructor execution?
log(e, "Failed to instantiate team "+teamName);
@@ -124,7 +126,9 @@ public class TeamLoader {
break;
}
} catch (NoClassDefFoundError e) {
- deferredTeams.add(new WaitingTeamRecord(teamInstance, aspectBinding, e.getMessage().replace('/','.'))); // TODO(SH): synchronization
+ synchronized (deferredTeams) {
+ deferredTeams.add(new WaitingTeamRecord(teamInstance, aspectBinding, e.getMessage().replace('/','.'))); // TODO(SH): synchronization
+ }
} catch (Throwable t) {
// application errors during activation
log(t, "Failed to activate team "+teamName);
diff --git a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java
index bd2224623..2dd0029c1 100644
--- a/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java
+++ b/plugins/org.eclipse.objectteams.osgi.weaving/src/org/eclipse/objectteams/osgi/weaving/Activator.java
@@ -35,21 +35,6 @@ public class Activator implements BundleActivator {
OTREInit();
}
- @SuppressWarnings("deprecation")
- public static AspectBindingRegistry loadAspectBindingRegistry() {
- org.osgi.service.packageadmin.PackageAdmin packageAdmin = null;;
-
- ServiceReference<?> ref= context.getServiceReference(org.osgi.service.packageadmin.PackageAdmin.class.getName());
- if (ref!=null)
- packageAdmin = (org.osgi.service.packageadmin.PackageAdmin)context.getService(ref);
- else
- log(ILogger.ERROR, "Failed to load PackageAdmin service. Will not be able to handle fragments.");
-
- AspectBindingRegistry aspectBindingRegistry = new AspectBindingRegistry();
- aspectBindingRegistry.loadAspectBindings(packageAdmin);
- return aspectBindingRegistry;
- }
-
@SuppressWarnings("restriction")
private void acquireLog(BundleContext bundleContext) {
try {

Back to the top