Fix for Bug 344350 - [runtime][bcel] NPE in InstructionList.getInstructionHandles()
diff --git a/plugins/org.eclipse.objectteams.otequinox.hook/src/org/eclipse/objectteams/otequinox/internal/hook/TransformerHook.java b/plugins/org.eclipse.objectteams.otequinox.hook/src/org/eclipse/objectteams/otequinox/internal/hook/TransformerHook.java
index 31834fd..43d463f 100644
--- a/plugins/org.eclipse.objectteams.otequinox.hook/src/org/eclipse/objectteams/otequinox/internal/hook/TransformerHook.java
+++ b/plugins/org.eclipse.objectteams.otequinox.hook/src/org/eclipse/objectteams/otequinox/internal/hook/TransformerHook.java
@@ -34,6 +34,7 @@
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;
+import java.util.zip.CRC32;
import org.eclipse.osgi.baseadaptor.BaseAdaptor;
import org.eclipse.osgi.baseadaptor.BaseData;
@@ -117,6 +118,9 @@
// another non-transformable bundle:
private static final String ASM_PLUGIN_ID = "org.objectweb.asm";
+
+ // this one requires hot-fixing:
+ private static final String BCEL_PLUGIN_ID = "org.apache.bcel";
// specific action may be required when this class is loaded:
private static final String ORG_OBJECTTEAMS_TEAM = "org.objectteams.Team";
@@ -309,6 +313,8 @@
return classbytes; // don't transform the adaptor ;-)
if (ASM_PLUGIN_ID.equals(bundle.getSymbolicName())) // name comparison since multiple instances of this bundle could exist
return classbytes; // don't transform ASM
+ if (BCEL_PLUGIN_ID.equals(bundle.getSymbolicName()))
+ return fixBCEL(name, classbytes);
// SH: extra safety against recursion (see Trac #173)
if (name.equals(previousClassName)) {
@@ -385,6 +391,24 @@
return classbytes;
}
+ private byte[] fixBCEL(String name, byte[] classbytes) {
+ if ("org.apache.bcel.generic.InstructionHandle".equals(name)) {
+ CRC32 crc32 = new CRC32();
+ crc32.update(classbytes);
+ long crc = crc32.getValue();
+ if ( classbytes.length == 0x1623 // identify original class
+ && crc == 0x42132087 // --""--
+ && classbytes[0xF00] == 0x18) { // modifiers of method getInstructionHandle at "static final"
+ classbytes[0xF00] = 0x38; // add "synchronized"
+ this.logger.log(Util.INFO, "hot-patched a bug in class org.apache.bcel.generic.InstructionHandle\n"+
+ "\tsee https://bugs.eclipse.org/bugs/show_bug.cgi?id=344350");
+ } else {
+ this.logger.log(Util.WARNING, "Class org.apache.bcel.generic.InstructionHandle needs a hot-patch but has unexpected byte code.");
+ }
+ }
+ return classbytes;
+ }
+
// transform, log and profile:
private byte[] transformClass(ClassFileTransformer objectTeamsTransformer, ClassLoader resourceLoader,
String name, byte[] classbytes, ProtectionDomain domain,