aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Ross2012-10-05 16:49:09 (EDT)
committerThomas Watson2012-10-17 16:41:42 (EDT)
commit16268836e26106a5d2355955089a90fc25c5104d (patch)
treea38648dc82e202e59175feeb10bec805d7a0d000
parent52dbb846c9aad917ea6ec65ca9ca8bedd74919c5 (diff)
downloadrt.equinox.framework-16268836e26106a5d2355955089a90fc25c5104d.zip
rt.equinox.framework-16268836e26106a5d2355955089a90fc25c5104d.tar.gz
rt.equinox.framework-16268836e26106a5d2355955089a90fc25c5104d.tar.bz2
Bug 391275 - Initial implementation of RFC 191: Weaving Hook Enhancements.
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WeavingHookConfigurator.java2
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WovenClassImpl.java73
2 files changed, 72 insertions, 3 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WeavingHookConfigurator.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WeavingHookConfigurator.java
index 00740bd..54a7a9b 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WeavingHookConfigurator.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WeavingHookConfigurator.java
@@ -44,7 +44,7 @@ public class WeavingHookConfigurator extends ClassLoaderHook {
ModuleClassLoader classLoader = manager.getClassLoader();
BundleLoader loader = classLoader.getBundleLoader();
// create a woven class object and add it to the thread local stack
- WovenClassImpl wovenClass = new WovenClassImpl(name, classbytes, entry, classpathEntry.getDomain(), loader, registry, blackList);
+ WovenClassImpl wovenClass = new WovenClassImpl(name, classbytes, entry, classpathEntry.getDomain(), loader, container, blackList);
List<WovenClassImpl> wovenClasses = wovenClassStack.get();
if (wovenClasses == null) {
wovenClasses = new ArrayList<WovenClassImpl>(6);
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WovenClassImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WovenClassImpl.java
index d7404e8..b79398e 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WovenClassImpl.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WovenClassImpl.java
@@ -12,6 +12,7 @@ package org.eclipse.osgi.internal.weaving;
import java.security.*;
import java.util.*;
+import org.eclipse.osgi.internal.framework.EquinoxContainer;
import org.eclipse.osgi.internal.loader.BundleLoader;
import org.eclipse.osgi.internal.serviceregistry.HookContext;
import org.eclipse.osgi.internal.serviceregistry.ServiceRegistry;
@@ -40,8 +41,9 @@ public final class WovenClassImpl implements WovenClass, HookContext {
private Throwable error;
private ServiceRegistration<?> errorHook;
private Class<?> clazz;
+ final EquinoxContainer container;
- public WovenClassImpl(String className, byte[] bytes, BundleEntry entry, ProtectionDomain domain, BundleLoader loader, ServiceRegistry registry, Map<ServiceRegistration<?>, Boolean> blacklist) {
+ public WovenClassImpl(String className, byte[] bytes, BundleEntry entry, ProtectionDomain domain, BundleLoader loader, EquinoxContainer container, Map<ServiceRegistration<?>, Boolean> blacklist) {
super();
this.className = className;
this.validBytes = this.resultBytes = bytes;
@@ -49,8 +51,10 @@ public final class WovenClassImpl implements WovenClass, HookContext {
this.dynamicImports = new DynamicImportList(this);
this.domain = domain;
this.loader = loader;
- this.registry = registry;
+ this.registry = container.getServiceRegistry();
+ this.container = container;
this.blackList = blacklist;
+ setState(TRANSFORMING);
}
public byte[] getBytes() {
@@ -105,6 +109,16 @@ public final class WovenClassImpl implements WovenClass, HookContext {
// weaving has completed; save the class and mark complete
this.clazz = clazz;
hookFlags |= FLAG_WEAVINGCOMPLETE;
+ // Only notify listeners if weaving hooks were called.
+ if ((hookFlags & FLAG_HOOKCALLED) == 0)
+ return;
+ // Only notify listeners if they haven't already been notified of
+ // the terminal TRANSFORMING_FAILED state.
+ if (error != null)
+ return;
+ // If clazz is null, a class definition failure occurred.
+ setState(clazz == null ? DEFINE_FAILED : DEFINED);
+ notifyWovenClassListeners();
}
public String getClassName() {
@@ -173,6 +187,45 @@ public final class WovenClassImpl implements WovenClass, HookContext {
return weavingHookName;
}
+ private void notifyWovenClassListeners() {
+ final HookContext context = new HookContext() {
+ @Override
+ public void call(Object hook, ServiceRegistration<?> hookRegistration) throws Exception {
+ if (!(hook instanceof WovenClassListener))
+ return;
+ try {
+ ((WovenClassListener) hook).modified(WovenClassImpl.this);
+ } catch (Exception e) {
+ WovenClassImpl.this.container.getEventPublisher().publishFrameworkEvent(FrameworkEvent.ERROR, hookRegistration.getReference().getBundle(), e);
+ }
+ }
+
+ @Override
+ public String getHookClassName() {
+ return WovenClassListener.class.getName();
+ }
+
+ @Override
+ public String getHookMethodName() {
+ return "modified"; //$NON-NLS-1$
+ }
+ };
+ if (System.getSecurityManager() == null)
+ registry.notifyHooksPrivileged(context);
+ else {
+ try {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
+ public Object run() {
+ registry.notifyHooksPrivileged(context);
+ return null;
+ }
+ });
+ } catch (PrivilegedActionException e) {
+ throw (RuntimeException) e.getException();
+ }
+ }
+ }
+
byte[] callHooks() throws Throwable {
SecurityManager sm = System.getSecurityManager();
byte[] wovenBytes = null;
@@ -197,6 +250,11 @@ public final class WovenClassImpl implements WovenClass, HookContext {
wovenBytes = resultBytes;
newImports = dynamicImports;
setHooksComplete();
+ // Make sure setHooksComplete() has been called. The woven class
+ // must be immutable in TRANSFORMED or TRANSFORMING_FAILED.
+ // If error is not null, a weaving hook threw an exception.
+ setState(error == null ? TRANSFORMED : TRANSFORMING_FAILED);
+ notifyWovenClassListeners();
}
}
@@ -225,4 +283,15 @@ public final class WovenClassImpl implements WovenClass, HookContext {
public ServiceRegistration<?> getErrorHook() {
return errorHook;
}
+
+ private int state;
+
+ @Override
+ public int getState() {
+ return state;
+ }
+
+ private void setState(int value) {
+ state = value;
+ }
}