Bug 480808 - [otdre] if intermediate super class is unweavable,
_OT$callOrig fails to dispatch
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 6dcde3c..20cf7ff 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
@@ -173,6 +173,7 @@
 	// Is the java class, that was represented by the AbstractBoundClass
 	// already loaded by a class loader or not
 	private boolean isLoaded;
+	protected boolean isUnweavable;
 	
 	private int modifiers;
 
@@ -605,6 +606,9 @@
 	public synchronized void handleTaskList(Class<?> definedClass) {
 		if (isTransformationActive()) return;
 
+		if (this.isUnweavable)
+			new LinkageError("Class "+this.name+" is requested to be woven, but it is marked as unweavable.").printStackTrace();
+
 		Set<Map.Entry<Method, WeavingTask>> bindingEntrySet = openBindingTasks
 				.entrySet();
 
@@ -1139,4 +1143,12 @@
 			this.wiringTasks.clear();
 		}
 	}
+
+	public boolean needsWeaving() {
+		return !this.openAccessTasks.isEmpty() || !this.openBindingTasks.isEmpty();
+	}
+
+	public void markAsUnweavable() {
+		this.isUnweavable = true;
+	}
 }
diff --git a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/ClassRepository.java b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/ClassRepository.java
index 48bff21..c4c40b9 100644
--- a/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/ClassRepository.java
+++ b/plugins/org.eclipse.objectteams.otredyn/src/org/eclipse/objectteams/otredyn/bytecode/ClassRepository.java
@@ -1,7 +1,7 @@
 /**********************************************************************
  * This file is part of "Object Teams Dynamic Runtime Environment"
  * 
- * Copyright 2009, 2012 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
@@ -78,7 +78,16 @@
 		
 		return clazz;
 	}
-	
+
+	/**
+	 * Similar to {@link getBoundClass(String, String, ClassLoader)},
+	 * but don't create a new bound class if none has been registered before.
+	 * @param id a globally unique identifier for the class 
+	 */
+	public synchronized AbstractBoundClass peekBoundClass(String id) {
+		return boundClassMap.get(id);
+	}
+
 	/**
 	 * Returns a instance of AbstractBoundClass for the
 	 * given FQN and id and sets the bytecode for this class. 
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 e75875e..8174c0b 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
@@ -73,13 +73,23 @@
 			loader = ClassLoader.getSystemClassLoader();
 
 		ClassRepository classRepo = ClassRepository.getInstance();
+		AbstractBoundClass clazz = classRepo.peekBoundClass(classId);
 		String sourceClassName = className.replace('/','.');
 
 		if (!weavingContext.isWeavable(sourceClassName) || loader == null) {
+			if (clazz != null) {
+				if (isWeavable(className) && clazz.needsWeaving()) {
+					// only print out for now, exceptions thrown by us are silently caught by TransformerManager.
+					new LinkageError("Classs "+className+" requires weaving, but is not weavable!").printStackTrace();
+				} else {
+					clazz.markAsUnweavable(); // mark in case we'll try to weave later
+				}
+			}
 			return null;
 		}
 
-		AbstractBoundClass clazz = classRepo.getBoundClass(sourceClassName, classId, loader);
+		if (clazz == null)
+			clazz = classRepo.getBoundClass(sourceClassName, classId, loader);
 		if (classBeingRedefined == null && !clazz.isFirstTransformation()) {
 			return clazz.getBytecode(); // FIXME: re-loading existing class?? Investigate classloader, check classId strategy etc.pp.
 		}