Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2011-11-01 20:13:00 +0000
committerThomas Watson2011-11-01 20:29:56 +0000
commit609c7b5ae81f664920ccfe09d0b8d59cab098791 (patch)
tree36b8bd1b64dbf4c5cde9e2b35d14a7d34c6957ba
parentce9ce834452337419becbdc1f895b70a34ea2c5c (diff)
downloadrt.equinox.framework-609c7b5ae81f664920ccfe09d0b8d59cab098791.tar.gz
rt.equinox.framework-609c7b5ae81f664920ccfe09d0b8d59cab098791.tar.xz
rt.equinox.framework-609c7b5ae81f664920ccfe09d0b8d59cab098791.zip
Bug 361390 - Framework should ensure weaving hooks are presented
with byte code in a class cache environment
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleEntry.java45
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorUtil.java42
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java2
-rw-r--r--bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java49
4 files changed, 84 insertions, 54 deletions
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleEntry.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleEntry.java
index 860bb9a1a..b9d48f3ae 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleEntry.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/baseadaptor/bundlefile/BundleEntry.java
@@ -11,9 +11,11 @@
package org.eclipse.osgi.baseadaptor.bundlefile;
-import java.io.*;
+import java.io.IOException;
+import java.io.InputStream;
import java.net.URL;
import org.eclipse.osgi.framework.debug.Debug;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorUtil;
/**
* A BundleEntry represents one entry of a BundleFile.
@@ -89,47 +91,8 @@ public abstract class BundleEntry {
public byte[] getBytes() throws IOException {
InputStream in = getInputStream();
int length = (int) getSize();
- byte[] classbytes;
- int bytesread = 0;
- int readcount;
if (Debug.DEBUG_LOADER)
Debug.println(" about to read " + length + " bytes from " + getName()); //$NON-NLS-1$ //$NON-NLS-2$
-
- try {
- if (length > 0) {
- classbytes = new byte[length];
- for (; bytesread < length; bytesread += readcount) {
- readcount = in.read(classbytes, bytesread, length - bytesread);
- if (readcount <= 0) /* if we didn't read anything */
- break; /* leave the loop */
- }
- } else /* BundleEntry does not know its own length! */{
- length = BUF_SIZE;
- classbytes = new byte[length];
- readloop: while (true) {
- for (; bytesread < length; bytesread += readcount) {
- readcount = in.read(classbytes, bytesread, length - bytesread);
- if (readcount <= 0) /* if we didn't read anything */
- break readloop; /* leave the loop */
- }
- byte[] oldbytes = classbytes;
- length += BUF_SIZE;
- classbytes = new byte[length];
- System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
- }
- }
- if (classbytes.length > bytesread) {
- byte[] oldbytes = classbytes;
- classbytes = new byte[bytesread];
- System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
- }
- } finally {
- try {
- in.close();
- } catch (IOException ee) {
- // nothing to do here
- }
- }
- return classbytes;
+ return AdaptorUtil.getBytes(in, length, BUF_SIZE);
}
}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorUtil.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorUtil.java
index 419850cb9..3ff383ca4 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorUtil.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/AdaptorUtil.java
@@ -235,4 +235,46 @@ public class AdaptorUtil {
// TODO should we do this by hand ourselves?
return file.toURL();
}
+
+ public static byte[] getBytes(InputStream in, int length, int BUF_SIZE) throws IOException {
+ byte[] classbytes;
+ int bytesread = 0;
+ int readcount;
+ try {
+ if (length > 0) {
+ classbytes = new byte[length];
+ for (; bytesread < length; bytesread += readcount) {
+ readcount = in.read(classbytes, bytesread, length - bytesread);
+ if (readcount <= 0) /* if we didn't read anything */
+ break; /* leave the loop */
+ }
+ } else /* does not know its own length! */{
+ length = BUF_SIZE;
+ classbytes = new byte[length];
+ readloop: while (true) {
+ for (; bytesread < length; bytesread += readcount) {
+ readcount = in.read(classbytes, bytesread, length - bytesread);
+ if (readcount <= 0) /* if we didn't read anything */
+ break readloop; /* leave the loop */
+ }
+ byte[] oldbytes = classbytes;
+ length += BUF_SIZE;
+ classbytes = new byte[length];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+ }
+ if (classbytes.length > bytesread) {
+ byte[] oldbytes = classbytes;
+ classbytes = new byte[bytesread];
+ System.arraycopy(oldbytes, 0, classbytes, 0, bytesread);
+ }
+ } finally {
+ try {
+ in.close();
+ } catch (IOException ee) {
+ // nothing to do here
+ }
+ }
+ return classbytes;
+ }
}
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java
index 43aec13e2..9f43d0ec4 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WeavingHookConfigurator.java
@@ -56,7 +56,7 @@ public class WeavingHookConfigurator implements HookConfigurator, ClassLoadingHo
return null;
}
// create a woven class object and add it to the thread local stack
- WovenClassImpl wovenClass = new WovenClassImpl(name, classbytes, classpathEntry.getDomain(), loader, registry, blackList);
+ WovenClassImpl wovenClass = new WovenClassImpl(name, classbytes, entry, classpathEntry.getDomain(), loader, registry, blackList);
List<WovenClassImpl> wovenClasses = wovenClassStack.get();
if (wovenClasses == null) {
wovenClasses = new ArrayList<WovenClassImpl>(6);
diff --git a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java
index 270f70593..e7e27a37c 100644
--- a/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java
+++ b/bundles/org.eclipse.osgi/defaultAdaptor/src/org/eclipse/osgi/internal/baseadaptor/weaving/WovenClassImpl.java
@@ -12,6 +12,8 @@ package org.eclipse.osgi.internal.baseadaptor.weaving;
import java.security.*;
import java.util.*;
+import org.eclipse.osgi.baseadaptor.bundlefile.BundleEntry;
+import org.eclipse.osgi.internal.baseadaptor.AdaptorUtil;
import org.eclipse.osgi.internal.loader.BundleLoader;
import org.eclipse.osgi.internal.serviceregistry.HookContext;
import org.eclipse.osgi.internal.serviceregistry.ServiceRegistry;
@@ -26,21 +28,24 @@ public final class WovenClassImpl implements WovenClass, HookContext {
private final static byte FLAG_WEAVINGCOMPLETE = 0x04;
private final static String weavingHookName = WeavingHook.class.getName();
private final String className;
+ private final BundleEntry entry;
private final List<String> dynamicImports;
private final ProtectionDomain domain;
private final BundleLoader loader;
final ServiceRegistry registry;
private final Map<ServiceRegistration<?>, Boolean> blackList;
- private byte[] bytes;
+ private byte[] validBytes;
+ private byte[] resultBytes;
private byte hookFlags = 0;
private Throwable error;
private ServiceRegistration<?> errorHook;
private Class<?> clazz;
- public WovenClassImpl(String className, byte[] bytes, ProtectionDomain domain, BundleLoader loader, ServiceRegistry registry, Map<ServiceRegistration<?>, Boolean> blacklist) {
+ public WovenClassImpl(String className, byte[] bytes, BundleEntry entry, ProtectionDomain domain, BundleLoader loader, ServiceRegistry registry, Map<ServiceRegistration<?>, Boolean> blacklist) {
super();
this.className = className;
- this.bytes = bytes;
+ this.validBytes = this.resultBytes = bytes;
+ this.entry = entry;
this.dynamicImports = new DynamicImportList(this);
this.domain = domain;
this.loader = loader;
@@ -51,13 +56,13 @@ public final class WovenClassImpl implements WovenClass, HookContext {
public byte[] getBytes() {
if ((hookFlags & FLAG_HOOKSCOMPLETE) == 0) {
checkPermission();
- return bytes; // return raw bytes until complete
+ return validBytes; // return raw bytes until complete
}
// we have called all hooks; someone is calling outside of weave call
// need to be safe and copy the bytes.
- byte[] current = bytes;
+ byte[] current = validBytes;
byte[] results = new byte[current.length];
- System.arraycopy(bytes, 0, results, 0, current.length);
+ System.arraycopy(current, 0, results, 0, current.length);
return results;
}
@@ -68,7 +73,7 @@ public final class WovenClassImpl implements WovenClass, HookContext {
if ((hookFlags & FLAG_HOOKSCOMPLETE) != 0)
// someone is calling this outside of weave
throw new IllegalStateException("Weaving has completed already."); //$NON-NLS-1$
- this.bytes = newBytes;
+ this.resultBytes = this.validBytes = newBytes;
}
void checkPermission() {
@@ -90,9 +95,9 @@ public final class WovenClassImpl implements WovenClass, HookContext {
private void setHooksComplete() {
// create a copy of the bytes array that noone has a reference to
- byte[] original = bytes;
- bytes = new byte[bytes.length];
- System.arraycopy(original, 0, bytes, 0, original.length);
+ byte[] original = validBytes;
+ validBytes = new byte[original.length];
+ System.arraycopy(original, 0, validBytes, 0, original.length);
hookFlags |= FLAG_HOOKSCOMPLETE;
}
@@ -124,7 +129,13 @@ public final class WovenClassImpl implements WovenClass, HookContext {
if (hook instanceof WeavingHook) {
if (blackList.containsKey(hookRegistration))
return; // black listed hook
- hookFlags |= FLAG_HOOKCALLED;
+ if ((hookFlags & FLAG_HOOKCALLED) == 0) {
+ hookFlags |= FLAG_HOOKCALLED;
+ // only do this check on the first weaving hook call
+ if (!validBytes(validBytes)) {
+ validBytes = AdaptorUtil.getBytes(entry.getInputStream(), (int) entry.getSize(), 8 * 1024);
+ }
+ }
try {
((WeavingHook) hook).weave(this);
} catch (WeavingException e) {
@@ -140,6 +151,20 @@ public final class WovenClassImpl implements WovenClass, HookContext {
}
}
+ private boolean validBytes(byte[] checkBytes) {
+ if (checkBytes == null || checkBytes.length < 4)
+ return false;
+ if ((checkBytes[0] & 0xCA) != 0xCA)
+ return false;
+ if ((checkBytes[1] & 0xFE) != 0xFE)
+ return false;
+ if ((checkBytes[2] & 0xBA) != 0xBA)
+ return false;
+ if ((checkBytes[3] & 0xBE) != 0xBE)
+ return false;
+ return true;
+ }
+
public String getHookMethodName() {
return "weave"; //$NON-NLS-1$
}
@@ -169,7 +194,7 @@ public final class WovenClassImpl implements WovenClass, HookContext {
}
} finally {
if ((hookFlags & FLAG_HOOKCALLED) != 0) {
- wovenBytes = bytes;
+ wovenBytes = resultBytes;
newImports = dynamicImports;
setHooksComplete();
}

Back to the top