Many thanks to Mike Keith
- * for his assistance.
- *
- * @author Costin Leau
- * @since 2.0
- */
-class OC4JClassPreprocessorAdapter implements ClassPreprocessor {
-
- private final ClassFileTransformer transformer;
-
-
- /**
- * Creates a new instance of the {@link OC4JClassPreprocessorAdapter} class.
- * @param transformer the {@link ClassFileTransformer} to be adapted (must not be null
)
- * @throws IllegalArgumentException if the supplied transformer
is null
- */
- public OC4JClassPreprocessorAdapter(ClassFileTransformer transformer) {
- Assert.notNull(transformer, "Transformer must not be null");
- this.transformer = transformer;
- }
-
-
- public ClassPreprocessor initialize(ClassLoader loader) {
- return this;
- }
-
- public byte[] processClass(String className, byte origClassBytes[], int offset, int length, ProtectionDomain pd,
- ClassLoader loader) {
- try {
- byte[] tempArray = new byte[length];
- System.arraycopy(origClassBytes, offset, tempArray, 0, length);
-
- // NB: OC4J passes className as "." without class while the
- // transformer expects a VM, "/" format
- byte[] result = this.transformer.transform(loader, className.replace('.', '/'), null, pd, tempArray);
- return (result != null ? result : origClassBytes);
- }
- catch (IllegalClassFormatException ex) {
- throw new IllegalStateException("Cannot transform because of illegal class format", ex);
- }
- }
-
-
- @Override
- public String toString() {
- StringBuilder builder = new StringBuilder(getClass().getName());
- builder.append(" for transformer: ");
- builder.append(this.transformer);
- return builder.toString();
- }
-
-}
+/*
+ * Copyright 2006-2009 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.springframework.instrument.classloading.oc4j;
+
+import java.lang.instrument.ClassFileTransformer;
+import java.lang.instrument.IllegalClassFormatException;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.security.ProtectionDomain;
+
+/**
+ * Adapter that implements OC4J ClassPreProcessor interface, delegating to a
+ * standard JDK {@link ClassFileTransformer} underneath.
+ *
+ *
To avoid compile time checks again the vendor API, a dynamic proxy is
+ * being used.
+ *
+ * @author Costin Leau
+ */
+class OC4JClassPreProcessorAdapter implements InvocationHandler {
+
+ private final ClassFileTransformer transformer;
+
+ /**
+ * Creates a new {@link OC4JClassPreProcessorAdapter}.
+ * @param transformer the {@link ClassFileTransformer} to be adapted (must
+ * not be null
)
+ */
+ public OC4JClassPreProcessorAdapter(ClassFileTransformer transformer) {
+ this.transformer = transformer;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
+ String name = method.getName();
+
+ if ("equals".equals(name)) {
+ return (Boolean.valueOf(proxy == args[0]));
+ } else if ("hashCode".equals(name)) {
+ return hashCode();
+ } else if ("toString".equals(name)) {
+ return toString();
+ } else if ("initialize".equals(name)) {
+ initialize(proxy, (ClassLoader) args[0]);
+ return null;
+ } else if ("processClass".equals(name)) {
+ return processClass((String) args[0], (byte[]) args[1], (Integer) args[2], (Integer) args[3],
+ (ProtectionDomain) args[4], (ClassLoader) args[5]);
+ } else {
+ throw new IllegalArgumentException("Unknown method: " + method);
+ }
+ }
+
+ // maps to oracle.classloader.util.ClassPreprocessor#initialize
+ // the proxy is passed since it implements the Oracle interface which
+ // is asked as a return type
+ public Object initialize(Object proxy, ClassLoader loader) {
+ return proxy;
+ }
+
+ public byte[] processClass(String className, byte origClassBytes[], int offset, int length, ProtectionDomain pd,
+ ClassLoader loader) {
+ try {
+ byte[] tempArray = new byte[length];
+ System.arraycopy(origClassBytes, offset, tempArray, 0, length);
+
+ // NB: OC4J passes className as "." without class while the
+ // transformer expects a VM, "/" format
+ byte[] result = this.transformer.transform(loader, className.replace('.', '/'), null, pd, tempArray);
+ return (result != null ? result : origClassBytes);
+ } catch (IllegalClassFormatException ex) {
+ throw new IllegalStateException("Cannot transform because of illegal class format", ex);
+ }
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder(getClass().getName());
+ builder.append(" for transformer: ");
+ builder.append(this.transformer);
+ return builder.toString();
+ }
+}
\ No newline at end of file
diff --git a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JLoadTimeWeaver.java b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JLoadTimeWeaver.java
index 656debd767373297e650b865456da008ed4419d2..4a6dd449d7738e50e2d844cd3ea69402f1612f95 100644
--- a/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JLoadTimeWeaver.java
+++ b/org.springframework.context/src/main/java/org/springframework/instrument/classloading/oc4j/OC4JLoadTimeWeaver.java
@@ -18,8 +18,6 @@ package org.springframework.instrument.classloading.oc4j;
import java.lang.instrument.ClassFileTransformer;
-import oracle.classloader.util.ClassLoaderUtilities;
-
import org.springframework.instrument.classloading.LoadTimeWeaver;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
@@ -38,8 +36,7 @@ import org.springframework.util.ClassUtils;
*/
public class OC4JLoadTimeWeaver implements LoadTimeWeaver {
- private final ClassLoader classLoader;
-
+ private final OC4JClassLoaderAdapter classLoader;
/**
* Creates a new instance of thie {@link OC4JLoadTimeWeaver} class
@@ -49,7 +46,7 @@ public class OC4JLoadTimeWeaver implements LoadTimeWeaver {
public OC4JLoadTimeWeaver() {
this(ClassUtils.getDefaultClassLoader());
}
-
+
/**
* Creates a new instance of the {@link OC4JLoadTimeWeaver} class
* using the supplied {@link ClassLoader}.
@@ -57,23 +54,21 @@ public class OC4JLoadTimeWeaver implements LoadTimeWeaver {
*/
public OC4JLoadTimeWeaver(ClassLoader classLoader) {
Assert.notNull(classLoader, "ClassLoader must not be null");
- this.classLoader = classLoader;
+ this.classLoader = new OC4JClassLoaderAdapter(classLoader);
}
-
public void addTransformer(ClassFileTransformer transformer) {
Assert.notNull(transformer, "Transformer must not be null");
// Since OC4J 10.1.3's PolicyClassLoader is going to be removed,
// we rely on the ClassLoaderUtilities API instead.
- OC4JClassPreprocessorAdapter processor = new OC4JClassPreprocessorAdapter(transformer);
- ClassLoaderUtilities.addPreprocessor(this.classLoader, processor);
+ classLoader.addTransformer(transformer);
}
public ClassLoader getInstrumentableClassLoader() {
- return this.classLoader;
+ return classLoader.getClassLoader();
}
public ClassLoader getThrowawayClassLoader() {
- return ClassLoaderUtilities.copy(this.classLoader);
+ return classLoader.getThrowawayClassLoader();
}
}
\ No newline at end of file