Bug 462968 - [otdre] callback needed to determine superclass weavability
diff --git a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java
index 27ba96a..f5c4a08 100644
--- a/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java
+++ b/plugins/org.eclipse.objectteams.otequinox/src/org/eclipse/objectteams/internal/osgi/weaving/BaseBundleLoadTrigger.java
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
- * Copyright 2013, 2014 GK Software AG
+ * Copyright 2013, 2015 GK Software AG
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -97,7 +97,7 @@
}
// (2) scan all teams in affecting aspect bindings:
if (!aspectBinding.hasScannedTeams)
- aspectBinding.scanTeamClasses(aspectBundle, DelegatingTransformer.newTransformer(useDynamicWeaver));
+ aspectBinding.scanTeamClasses(aspectBundle, DelegatingTransformer.newTransformer(useDynamicWeaver, hook, baseClass.getBundleWiring()));
// TODO: record adapted base classes?
// (3) add dependencies to the base bundle:
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 b0c11d2..dde7653 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
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
- * Copyright 2014 GK Software AG
+ * Copyright 2015 GK Software AG
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -21,13 +21,18 @@
import java.lang.instrument.IllegalClassFormatException;
import java.lang.instrument.UnmodifiableClassException;
import java.lang.reflect.InvocationTargetException;
+import java.net.URL;
import java.security.ProtectionDomain;
import java.util.Collection;
+import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.objectteams.internal.osgi.weaving.OTWeavingHook.WeavingReason;
import org.eclipse.objectteams.otredyn.bytecode.IRedefineStrategy;
import org.eclipse.objectteams.otredyn.bytecode.RedefineStrategyFactory;
+import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;
import org.osgi.framework.Bundle;
+import org.osgi.framework.wiring.BundleWiring;
/**
* Generalization over the transformers of OTRE and OTDRE.
@@ -35,9 +40,9 @@
public abstract class DelegatingTransformer {
/** Factory method for a fresh transformer. */
- static @NonNull DelegatingTransformer newTransformer(boolean useDynamicWeaver) {
+ static @NonNull DelegatingTransformer newTransformer(boolean useDynamicWeaver, OTWeavingHook hook, BundleWiring wiring) {
if (useDynamicWeaver)
- return new OTDRETransformer();
+ return new OTDRETransformer(getWeavingContext(hook, wiring));
else
return new OTRETransformer();
}
@@ -59,10 +64,10 @@
}
private static class OTDRETransformer extends DelegatingTransformer {
- org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer transformer =
- new org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer();
- public OTDRETransformer() {
+ org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer transformer;
+ public OTDRETransformer(IWeavingContext weavingContext) {
RedefineStrategyFactory.setRedefineStrategy(new OTEquinoxRedefineStrategy());
+ transformer = new org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer(weavingContext);
}
@Override
public void readOTAttributes(String className, InputStream inputStream, String fileName, Bundle bundle) throws ClassFormatError, IOException {
@@ -120,6 +125,23 @@
}
};
}
+
+ static IWeavingContext getWeavingContext(final OTWeavingHook hook, final BundleWiring bundleWiring) {
+ return new IWeavingContext() {
+ @Override
+ public boolean isWeavable(String className) {
+ // currently, we don't support implicit crossing of bundle boundaries,
+ // so check if the requested class is provided by the current bundle:
+ int lastDot = className.lastIndexOf('.');
+ String path = className.substring(0, lastDot).replace('.', '/');
+ String filePattern = className.substring(lastDot+1)+".class";
+ List<URL> entry = bundleWiring.findEntries(path, filePattern, 0);
+ if (entry == null || entry.isEmpty())
+ return false;
+ return hook.requiresWeaving(bundleWiring, className, null) != WeavingReason.None;
+ }
+ };
+ }
public abstract void readOTAttributes(String className, InputStream inputStream, String fileName, Bundle bundle) throws ClassFormatError, IOException;
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 b973667..d5e67bb 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
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Development Tooling"-Software
*
- * Copyright 2013, 2014 GK Software AG
+ * Copyright 2013, 2015 GK Software AG
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -236,7 +236,7 @@
long time = 0;
- DelegatingTransformer transformer = DelegatingTransformer.newTransformer(useDynamicWeaver);
+ DelegatingTransformer transformer = DelegatingTransformer.newTransformer(useDynamicWeaver, this, bundleWiring);
Class<?> classBeingRedefined = null; // TODO prepare for otre-dyn
try {
log(IStatus.OK, "About to transform class "+className);
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
index 5d461e9..5bf069b 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/AbstractBoundClass.java
@@ -31,6 +31,7 @@
import org.eclipse.objectteams.otredyn.runtime.IMethod;
import org.eclipse.objectteams.otredyn.runtime.TeamManager;
import org.eclipse.objectteams.otredyn.runtime.ISubclassWiringTask;
+import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;
import org.eclipse.objectteams.otredyn.transformer.jplis.ObjectTeamsTransformer;
import org.objectweb.asm.Opcodes;
@@ -175,6 +176,8 @@
protected ClassLoader loader;
+ // callback
+ protected IWeavingContext weavingContext;
@@ -331,7 +334,8 @@
* Add the empty method accessStatic
* Add the empty method callAllBindings
*/
- public void transformAtLoadTime() {
+ public void transformAtLoadTime(IWeavingContext weavingContext) {
+ this.weavingContext = weavingContext;
handleTaskList();
}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
index 7762e40..45374f0 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/AsmWritableBoundClass.java
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Dynamic Runtime Environment"
*
- * Copyright 2009, 2014 Oliver Frank and others.
+ * Copyright 2009, 2015 Oliver Frank and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -229,7 +229,7 @@
protected void moveCodeToCallOrig(Method boundMethod, int boundMethodId) {
if (boundMethod.getName().equals("<init>")) return; // don't move constructor code
assert (isTransformationActive) : "No transformation active";
- nodes.add(new MoveCodeToCallOrigAdapter(this, boundMethod, boundMethodId));
+ nodes.add(new MoveCodeToCallOrigAdapter(this, boundMethod, boundMethodId, this.weavingContext));
}
/**
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java
index 409d51b..1c51220 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/asm/MoveCodeToCallOrigAdapter.java
@@ -21,6 +21,7 @@
import java.util.ListIterator;
import org.eclipse.objectteams.otredyn.bytecode.Method;
+import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;
import org.eclipse.objectteams.otredyn.transformer.names.ConstantMembers;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
@@ -44,8 +45,9 @@
private int firstArgIndex; // slot index of the first argument (0 (static) or 1 (non-static))
private int argOffset; // used to skip synth args if the callOrig method itself is a statid role method
private Method callOrig;
+ private boolean superIsWeavable = true;
- public MoveCodeToCallOrigAdapter(AsmWritableBoundClass clazz, Method method, int boundMethodId) {
+ public MoveCodeToCallOrigAdapter(AsmWritableBoundClass clazz, Method method, int boundMethodId, IWeavingContext weavingContext) {
this.method = method;
this.boundMethodId = boundMethodId;
if (method.isStatic()) {
@@ -56,6 +58,8 @@
firstArgIndex = 1;
callOrig = ConstantMembers.callOrig;
}
+ if (weavingContext != null)
+ superIsWeavable = weavingContext.isWeavable(clazz.getSuperClassName());
}
public boolean transform() {
@@ -105,7 +109,8 @@
}
}
- adjustSuperCalls(orgMethod.instructions, orgMethod.name, args, returnType, boundMethodIdSlot);
+ if (superIsWeavable)
+ adjustSuperCalls(orgMethod.instructions, orgMethod.name, args, returnType, boundMethodIdSlot);
// replace return of the original method with areturn and box the result value if needed
replaceReturn(orgMethod.instructions, returnType);
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java
new file mode 100644
index 0000000..3057580
--- /dev/null
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/IWeavingContext.java
@@ -0,0 +1,32 @@
+/**********************************************************************
+ * This file is part of "Object Teams Dynamic Runtime Environment"
+ *
+ * Copyright 2015 GK Software AG
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Please visit http://www.eclipse.org/objectteams for updates and contact.
+ *
+ * Contributors:
+ * Stephan Herrmann - Initial API and implementation
+ */
+package org.eclipse.objectteams.otredyn.transformer;
+
+/**
+ * Callback protocol to let the transformer query its context.
+ * @since 1.1.0
+ */
+public interface IWeavingContext {
+ /**
+ * Is the given class included in load-time weaving, i.e., will
+ * the weaving context pass the class to the transformer during
+ * initial loading?
+ * @param className full qualified classname, dot-separated for packages
+ * and dollar-separated for nested classes.
+ * @return true if the given class is included in load-time weaving.
+ */
+ boolean isWeavable(String className);
+}
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
index bb57d19..cd5a5d8 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/transformer/jplis/ObjectTeamsTransformer.java
@@ -1,7 +1,7 @@
/**********************************************************************
* This file is part of "Object Teams Dynamic Runtime Environment"
*
- * Copyright 2002, 2014 Berlin Institute of Technology, Germany, and others.
+ * Copyright 2002, 2015 Berlin Institute of Technology, Germany, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
@@ -25,6 +25,7 @@
import org.eclipse.objectteams.otredyn.bytecode.AbstractBoundClass;
import org.eclipse.objectteams.otredyn.bytecode.ClassRepository;
+import org.eclipse.objectteams.otredyn.transformer.IWeavingContext;
/**
@@ -33,8 +34,16 @@
*/
public class ObjectTeamsTransformer implements ClassFileTransformer {
+ private IWeavingContext weavingContext;
+
private Set<String> boundBaseClassNames = new HashSet<String>();
+ public ObjectTeamsTransformer() { }
+
+ public ObjectTeamsTransformer(IWeavingContext weavingContext) {
+ this.weavingContext = weavingContext;
+ }
+
/* (non-Javadoc)
* @see java.lang.instrument.ClassFileTransformer#transform(java.lang.ClassLoader, java.lang.String, java.lang.Class, java.security.ProtectionDomain, byte[])
*/
@@ -63,7 +72,7 @@
if (!clazz.isInterface())
ClassRepository.getInstance().linkClassWithSuperclass(clazz);
if (!clazz.isInterface() || clazz.isRole())
- clazz.transformAtLoadTime();
+ clazz.transformAtLoadTime(this.weavingContext);
classfileBuffer = clazz.getBytecode();
clazz.dump(classfileBuffer, "initial");