aboutsummaryrefslogtreecommitdiffstats
path: root/src/main/javassist/util
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/javassist/util')
-rw-r--r--src/main/javassist/util/proxy/DefineClassHelper.java139
-rw-r--r--src/main/javassist/util/proxy/FactoryHelper.java60
-rw-r--r--src/main/javassist/util/proxy/ProxyFactory.java5
3 files changed, 145 insertions, 59 deletions
diff --git a/src/main/javassist/util/proxy/DefineClassHelper.java b/src/main/javassist/util/proxy/DefineClassHelper.java
new file mode 100644
index 00000000..c5749925
--- /dev/null
+++ b/src/main/javassist/util/proxy/DefineClassHelper.java
@@ -0,0 +1,139 @@
+/*
+ * Javassist, a Java-bytecode translator toolkit.
+ * Copyright (C) 1999- Shigeru Chiba. All Rights Reserved.
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. Alternatively, the contents of this file may be used under
+ * the terms of the GNU Lesser General Public License Version 2.1 or later,
+ * or the Apache License Version 2.0.
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ */
+
+package javassist.util.proxy;
+
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Field;
+import java.security.ProtectionDomain;
+import java.lang.invoke.MethodHandles;
+import java.lang.invoke.MethodHandles.Lookup;
+import sun.misc.Unsafe;
+
+import javassist.CannotCompileException;
+import javassist.bytecode.ClassFile;
+
+/**
+ * Helper class for invoking {@link ClassLoader#defineClass(String,byte[],int,int)}.
+ *
+ * @since 3.22
+ */
+public class DefineClassHelper {
+ private static java.lang.reflect.Method defineClass1 = null;
+ private static java.lang.reflect.Method defineClass2 = null;
+ private static Unsafe sunMiscUnsafe = null;
+
+ static {
+ if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_9)
+ try {
+ Class<?> cl = Class.forName("java.lang.ClassLoader");
+ defineClass1 = SecurityActions.getDeclaredMethod(
+ cl,
+ "defineClass",
+ new Class[] { String.class, byte[].class,
+ int.class, int.class });
+
+ defineClass2 = SecurityActions.getDeclaredMethod(
+ cl,
+ "defineClass",
+ new Class[] { String.class, byte[].class,
+ int.class, int.class, ProtectionDomain.class });
+ }
+ catch (Exception e) {
+ throw new RuntimeException("cannot initialize");
+ }
+ else
+ try {
+ Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
+ theUnsafe.setAccessible(true);
+ sunMiscUnsafe = (sun.misc.Unsafe)theUnsafe.get(null);
+ }
+ catch (Throwable t) {}
+ }
+
+ /**
+ * Loads a class file by a given class loader.
+ *
+ * @param domain if it is null, a default domain is used.
+ * @since 3.22
+ */
+ public static Class<?> toClass(String className, ClassLoader loader,
+ ProtectionDomain domain, byte[] bcode)
+ throws CannotCompileException
+ {
+ if (ClassFile.MAJOR_VERSION < ClassFile.JAVA_9)
+ return toClass2(className, loader, domain, bcode);
+ else {
+ if (sunMiscUnsafe != null)
+ try {
+ return sunMiscUnsafe.defineClass(className, bcode, 0, bcode.length,
+ loader, domain);
+ }
+ catch (Throwable t2) {}
+
+ try {
+ Lookup lookup = MethodHandles.lookup();
+ lookup = lookup.dropLookupMode(java.lang.invoke.MethodHandles.Lookup.PRIVATE);
+ return lookup.defineClass(bcode);
+ }
+ catch (Throwable t) {
+ throw new CannotCompileException(t);
+ }
+ }
+ }
+
+ private static Class<?> toClass2(String cname, ClassLoader loader,
+ ProtectionDomain domain, byte[] bcode)
+ throws CannotCompileException
+ {
+ try {
+ Method method;
+ Object[] args;
+ if (domain == null) {
+ method = defineClass1;
+ args = new Object[] { cname, bcode, Integer.valueOf(0),
+ Integer.valueOf(bcode.length) };
+ }
+ else {
+ method = defineClass2;
+ args = new Object[] { cname, bcode, Integer.valueOf(0),
+ Integer.valueOf(bcode.length), domain };
+ }
+
+ return toClass3(method, loader, args);
+ }
+ catch (RuntimeException e) {
+ throw e;
+ }
+ catch (java.lang.reflect.InvocationTargetException e) {
+ throw new CannotCompileException(e.getTargetException());
+ }
+ catch (Exception e) {
+ throw new CannotCompileException(e);
+ }
+ }
+
+ private static synchronized
+ Class<?> toClass3(Method method, ClassLoader loader, Object[] args)
+ throws Exception
+ {
+ SecurityActions.setAccessible(method, true);
+ Class<?> clazz = (Class<?>)method.invoke(loader, args);
+ SecurityActions.setAccessible(method, false);
+ return clazz;
+ }
+}
diff --git a/src/main/javassist/util/proxy/FactoryHelper.java b/src/main/javassist/util/proxy/FactoryHelper.java
index b17b78ed..39114657 100644
--- a/src/main/javassist/util/proxy/FactoryHelper.java
+++ b/src/main/javassist/util/proxy/FactoryHelper.java
@@ -16,7 +16,6 @@
package javassist.util.proxy;
-import java.lang.reflect.Method;
import java.io.BufferedOutputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
@@ -35,28 +34,6 @@ import javassist.bytecode.ClassFile;
* @see ProxyFactory
*/
public class FactoryHelper {
- private static java.lang.reflect.Method defineClass1, defineClass2;
-
- static {
- try {
- Class cl = Class.forName("java.lang.ClassLoader");
- defineClass1 = SecurityActions.getDeclaredMethod(
- cl,
- "defineClass",
- new Class[] { String.class, byte[].class,
- int.class, int.class });
-
- defineClass2 = SecurityActions.getDeclaredMethod(
- cl,
- "defineClass",
- new Class[] { String.class, byte[].class,
- int.class, int.class, ProtectionDomain.class });
- }
- catch (Exception e) {
- throw new RuntimeException("cannot initialize");
- }
- }
-
/**
* Returns an index for accessing arrays in this class.
*
@@ -144,45 +121,16 @@ public class FactoryHelper {
* @since 3.3
*/
public static Class toClass(ClassFile cf, ClassLoader loader, ProtectionDomain domain)
- throws CannotCompileException
+ throws CannotCompileException
{
try {
byte[] b = toBytecode(cf);
- Method method;
- Object[] args;
- if (domain == null) {
- method = defineClass1;
- args = new Object[] { cf.getName(), b, Integer.valueOf(0),
- Integer.valueOf(b.length) };
- }
- else {
- method = defineClass2;
- args = new Object[] { cf.getName(), b, Integer.valueOf(0),
- Integer.valueOf(b.length), domain };
- }
-
- return toClass2(method, loader, args);
+ return DefineClassHelper.toClass(cf.getName(), loader, domain, b);
}
- catch (RuntimeException e) {
- throw e;
- }
- catch (java.lang.reflect.InvocationTargetException e) {
- throw new CannotCompileException(e.getTargetException());
- }
- catch (Exception e) {
+ catch (IOException e) {
throw new CannotCompileException(e);
}
- }
-
- private static synchronized Class toClass2(Method method,
- ClassLoader loader, Object[] args)
- throws Exception
- {
- SecurityActions.setAccessible(method, true);
- Class clazz = (Class)method.invoke(loader, args);
- SecurityActions.setAccessible(method, false);
- return clazz;
- }
+ }
private static byte[] toBytecode(ClassFile cf) throws IOException {
ByteArrayOutputStream barray = new ByteArrayOutputStream();
diff --git a/src/main/javassist/util/proxy/ProxyFactory.java b/src/main/javassist/util/proxy/ProxyFactory.java
index a85e8de0..81792585 100644
--- a/src/main/javassist/util/proxy/ProxyFactory.java
+++ b/src/main/javassist/util/proxy/ProxyFactory.java
@@ -27,7 +27,6 @@ import java.util.*;
import java.lang.ref.WeakReference;
import javassist.CannotCompileException;
-import javassist.NotFoundException;
import javassist.bytecode.*;
/*
@@ -795,7 +794,7 @@ public class ProxyFactory {
superClass = OBJECT_TYPE;
superName = superClass.getName();
basename = interfaces.length == 0 ? superName
- : interfaces[0].getName();
+ : interfaces[0].getName();
} else {
superName = superClass.getName();
basename = superName;
@@ -805,7 +804,7 @@ public class ProxyFactory {
throw new RuntimeException(superName + " is final");
if (basename.startsWith("java."))
- basename = "org.javassist.tmp." + basename;
+ basename = "javassist.util.proxy." + basename.replace('.', '_');
}
private void allocateClassName() {