java.org.objenesis.instantiator.util.ClassDefinitionUtils Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of securemock Show documentation
Show all versions of securemock Show documentation
Libraries for Elasticsearch
The newest version!
/*
* Copyright 2006-2018 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.objenesis.instantiator.util;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.ProtectionDomain;
/**
* Helper class for ProxyObjectInstantiator. We can see the details of a class specification
* here
*
* @author Henri Tremblay
*/
public final class ClassDefinitionUtils {
public static final byte OPS_aload_0 = 42;
public static final byte OPS_invokespecial = -73; // has two bytes parameters
public static final byte OPS_return = -79;
public static final byte OPS_new = -69;
public static final byte OPS_dup = 89;
public static final byte OPS_areturn = -80;
public static final int CONSTANT_Utf8 = 1;
public static final int CONSTANT_Integer = 3;
public static final int CONSTANT_Float = 4;
public static final int CONSTANT_Long = 5;
public static final int CONSTANT_Double = 6;
public static final int CONSTANT_Class = 7;
public static final int CONSTANT_String = 8;
public static final int CONSTANT_Fieldref = 9;
public static final int CONSTANT_Methodref = 10;
public static final int CONSTANT_InterfaceMethodref = 11;
public static final int CONSTANT_NameAndType = 12;
public static final int CONSTANT_MethodHandle = 15;
public static final int CONSTANT_MethodType = 16;
public static final int CONSTANT_InvokeDynamic = 18;
public static final int ACC_PUBLIC = 0x0001; // Declared public; may be accessed from outside its package.
public static final int ACC_FINAL = 0x0010; // Declared final; no subclasses allowed.
public static final int ACC_SUPER = 0x0020; // Treat superclass methods specially when invoked by the invokespecial instruction.
public static final int ACC_INTERFACE = 0x0200; // Is an interface, not a class.
public static final int ACC_ABSTRACT = 0x0400; // Declared abstract; must not be instantiated.
public static final int ACC_SYNTHETIC = 0x1000; // Declared synthetic; not present in the source code.
public static final int ACC_ANNOTATION = 0x2000; // Declared as an annotation type.
public static final int ACC_ENUM = 0x4000; // Declared as an enum type.
public static final byte[] MAGIC = { (byte) 0xca, (byte) 0xfe, (byte) 0xba, (byte) 0xbe };
public static final byte[] VERSION = { (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x31 }; // minor_version, major_version (Java 5)
private ClassDefinitionUtils() { }
private static final ProtectionDomain PROTECTION_DOMAIN;
static {
PROTECTION_DOMAIN = AccessController.doPrivileged((PrivilegedAction) ClassDefinitionUtils.class::getProtectionDomain);
}
/**
* Define a class in the provided class loader from the array of bytes. Inspired by cglib
* ReflectUtils.defineClass
*
* @param type of the class returned
* @param className class name in the format org.objenesis.MyClass
* @param b bytes representing the class
* @param neighbor a class in the same package as the loaded class
* @param loader the class loader where the class will be loaded
* @return the newly loaded class
* @throws Exception whenever something goes wrong
*/
@SuppressWarnings("unchecked")
public static Class defineClass(String className, byte[] b, Class> neighbor, ClassLoader loader)
throws Exception {
Class c = (Class) DefineClassHelper.defineClass(className, b, 0, b.length, neighbor, loader, PROTECTION_DOMAIN);
// Force static initializers to run.
Class.forName(className, true, loader);
return c;
}
/**
* Read the bytes of a class from the classpath
*
* @param className full class name including the package
* @return the bytes representing the class
* @throws IllegalArgumentException if the class is longer than 2500 bytes
* @throws IOException if we fail to read the class
*/
public static byte[] readClass(String className) throws IOException {
// convert to a resource
className = ClassUtils.classNameToResource(className);
byte[] b = new byte[2500]; // I'm assuming that I'm reading class that are not too big
int length;
try (InputStream in = ClassDefinitionUtils.class.getClassLoader().getResourceAsStream(className)) {
length = in.read(b);
}
if(length >= 2500) {
throw new IllegalArgumentException("The class is longer that 2500 bytes which is currently unsupported");
}
byte[] copy = new byte[length];
System.arraycopy(b, 0, copy, 0, length);
return copy;
}
/**
* Write all class bytes to a file.
*
* @param fileName file where the bytes will be written
* @param bytes bytes representing the class
* @throws IOException if we fail to write the class
*/
public static void writeClass(String fileName, byte[] bytes) throws IOException {
try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(fileName))) {
out.write(bytes);
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy