use of org.eclipse.persistence.internal.libraries.asm.ClassReader in project eclipselink by eclipse-ee4j.
the class PersistenceWeaver method transform.
/**
* INTERNAL:
* Perform dynamic byte code weaving of class.
* @param loader The defining loader of the class to be transformed, may be {@code null}
* if the bootstrap loader.
* @param className The name of the class in the internal form of fully qualified class and interface
* names.
* @param classBeingRedefined If this is a redefine, the class being redefined, otherwise {@code null}.
* @param protectionDomain The protection domain of the class being defined or redefined.
* @param classfileBuffer The input byte buffer in class file format (must not be modified).
* @return A well-formed class file buffer (the result of the transform), or {@code null} if no transform
* is performed.
*/
@Override
public byte[] transform(final ClassLoader loader, final String className, final Class<?> classBeingRedefined, final ProtectionDomain protectionDomain, final byte[] classfileBuffer) throws TransformerException {
final SessionLog log = AbstractSessionLog.getLog();
// PERF: Is finest logging on weaving turned on?
final boolean shouldLogFinest = log.shouldLog(SessionLog.FINEST, SessionLog.WEAVER);
final Map<String, ClassDetails> classDetailsMap = this.classDetailsMap;
// Check if cleared already.
if (classDetailsMap == null) {
return null;
}
try {
/*
* The ClassFileTransformer callback - when called by the JVM's
* Instrumentation implementation - is invoked for every class loaded.
* Thus, we must check the classDetailsMap to see if we are 'interested'
* in the class.
*/
final ClassDetails classDetails = classDetailsMap.get(Helper.toSlashedClassName(className));
if (classDetails != null) {
if (shouldLogFinest) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "begin_weaving_class", className);
}
ClassReader classReader = null;
try {
classReader = new ClassReader(classfileBuffer);
} catch (IllegalArgumentException iae) {
// in such case log a warning and try to re-read the class without class version check
if (log.shouldLog(SessionLog.FINE, SessionLog.WEAVER)) {
SessionLogEntry entry = new SessionLogEntry(null, SessionLog.FINE, SessionLog.WEAVER, iae);
entry.setMessage(ExceptionLocalization.buildMessage("unsupported_classfile_version", new Object[] { className }));
log.log(entry);
}
classReader = new EclipseLinkClassReader(classfileBuffer);
}
final String reflectiveIntrospectionProperty = PrivilegedAccessHelper.getSystemProperty(SystemProperties.WEAVING_REFLECTIVE_INTROSPECTION);
final ClassWriter classWriter = reflectiveIntrospectionProperty != null ? new ClassWriter(ClassWriter.COMPUTE_FRAMES) : new ComputeClassWriter(loader, ClassWriter.COMPUTE_FRAMES);
final ClassWeaver classWeaver = new ClassWeaver(classWriter, classDetails);
final ClassVisitor sv = new SerialVersionUIDAdder(classWeaver);
classReader.accept(sv, 0);
if (classWeaver.alreadyWeaved) {
if (shouldLogFinest) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "end_weaving_class", className);
}
return null;
}
if (classWeaver.weaved) {
final byte[] bytes = classWriter.toByteArray();
final String outputPath = PrivilegedAccessHelper.getSystemProperty(SystemProperties.WEAVING_OUTPUT_PATH, "");
if (!outputPath.equals("")) {
Helper.outputClassFile(className, bytes, outputPath);
}
// PERF: Don't execute this set of if statements with logging turned off.
if (shouldLogFinest) {
if (classWeaver.weavedPersistenceEntity) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_persistenceentity", className);
}
if (classWeaver.weavedChangeTracker) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_changetracker", className);
}
if (classWeaver.weavedLazy) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_lazy", className);
}
if (classWeaver.weavedFetchGroups) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_fetchgroups", className);
}
if (classWeaver.weavedRest) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "weaved_rest", className);
}
log.log(SessionLog.FINEST, SessionLog.WEAVER, "end_weaving_class", className);
}
return bytes;
}
if (shouldLogFinest) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "end_weaving_class", className);
}
} else {
if (shouldLogFinest) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "transform_missing_class_details", className);
}
}
} catch (Throwable exception) {
if (log.shouldLog(SessionLog.WARNING, SessionLog.WEAVER)) {
log.log(SessionLog.WARNING, SessionLog.WEAVER, "exception_while_weaving", new Object[] { className, exception.getLocalizedMessage() });
if (shouldLogFinest) {
log.logThrowable(SessionLog.FINEST, SessionLog.WEAVER, exception);
}
}
}
if (shouldLogFinest) {
log.log(SessionLog.FINEST, SessionLog.WEAVER, "transform_existing_class_bytes", className);
}
// Returning null means 'use existing class bytes'.
return null;
}
use of org.eclipse.persistence.internal.libraries.asm.ClassReader in project eclipselink by eclipse-ee4j.
the class ComputeClassWriter method getCommonSuperClass.
@Override
protected String getCommonSuperClass(final String type1, final String type2) {
try {
ClassReader info1 = typeInfo(type1);
ClassReader info2 = typeInfo(type2);
if ((info1.getAccess() & Opcodes.ACC_INTERFACE) != 0) {
if (typeImplements(type2, info2, type1)) {
return type1;
} else {
return "java/lang/Object";
}
}
if ((info2.getAccess() & Opcodes.ACC_INTERFACE) != 0) {
if (typeImplements(type1, info1, type2)) {
return type2;
} else {
return "java/lang/Object";
}
}
StringBuilder b1 = typeAncestors(type1, info1);
StringBuilder b2 = typeAncestors(type2, info2);
String result = "java/lang/Object";
int end1 = b1.length();
int end2 = b2.length();
while (true) {
int start1 = b1.lastIndexOf(";", end1 - 1);
int start2 = b2.lastIndexOf(";", end2 - 1);
if (start1 != -1 && start2 != -1 && end1 - start1 == end2 - start2) {
String p1 = b1.substring(start1 + 1, end1);
String p2 = b2.substring(start2 + 1, end2);
if (p1.equals(p2)) {
result = p1;
end1 = start1;
end2 = start2;
} else {
return result;
}
} else {
return result;
}
}
} catch (IOException e) {
throw new RuntimeException(e.toString());
}
}
use of org.eclipse.persistence.internal.libraries.asm.ClassReader in project eclipselink by eclipse-ee4j.
the class MetadataAsmFactory method buildClassMetadata.
/**
* Build the class metadata for the class name using ASM to read the class
* byte codes.
*/
protected void buildClassMetadata(MetadataClass metadataClass, String className, boolean isLazy) {
ClassMetadataVisitor visitor = new ClassMetadataVisitor(metadataClass, isLazy);
InputStream stream = null;
try {
String resourceString = className.replace('.', '/') + ".class";
if (PrivilegedAccessHelper.shouldUsePrivilegedAccess()) {
final String f_resourceString = resourceString;
stream = AccessController.doPrivileged(new PrivilegedAction<InputStream>() {
@Override
public InputStream run() {
return m_loader.getResourceAsStream(f_resourceString);
}
});
} else {
stream = m_loader.getResourceAsStream(resourceString);
}
ClassReader reader = new ClassReader(stream);
Attribute[] attributes = new Attribute[0];
reader.accept(visitor, attributes, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
} catch (IllegalArgumentException iae) {
// class was probably compiled with some newer than officially
// supported and tested JDK
// in such case log a warning and try to re-read the class
// without class version check
SessionLog log = getLogger().getSession() != null ? getLogger().getSession().getSessionLog() : AbstractSessionLog.getLog();
if (log.shouldLog(SessionLog.WARNING, SessionLog.METADATA)) {
SessionLogEntry entry = new SessionLogEntry(getLogger().getSession(), SessionLog.WARNING, SessionLog.METADATA, iae);
entry.setMessage(ExceptionLocalization.buildMessage("unsupported_classfile_version", new Object[] { className }));
log.log(entry);
}
if (stream != null) {
try {
ClassReader reader = new EclipseLinkClassReader(stream);
Attribute[] attributes = new Attribute[0];
reader.accept(visitor, attributes, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
} catch (Exception e) {
// our fall-back failed, this is severe
if (log.shouldLog(SessionLog.SEVERE, SessionLog.METADATA)) {
SessionLogEntry entry = new SessionLogEntry(getLogger().getSession(), SessionLog.SEVERE, SessionLog.METADATA, e);
entry.setMessage(ExceptionLocalization.buildMessage("unsupported_classfile_version", new Object[] { className }));
log.log(entry);
}
addMetadataClass(getVirtualMetadataClass(className));
}
} else {
addMetadataClass(getVirtualMetadataClass(className));
}
} catch (Exception exception) {
SessionLog log = getLogger().getSession() != null ? getLogger().getSession().getSessionLog() : AbstractSessionLog.getLog();
if (log.shouldLog(SessionLog.FINEST, SessionLog.METADATA)) {
log.logThrowable(SessionLog.FINEST, SessionLog.METADATA, exception);
}
addMetadataClass(getVirtualMetadataClass(className));
} finally {
try {
if (stream != null) {
stream.close();
}
} catch (IOException ignore) {
// Ignore.
}
}
}
use of org.eclipse.persistence.internal.libraries.asm.ClassReader in project eclipselink by eclipse-ee4j.
the class SignatureImporter method importSignatures.
public Map<String, ClassSignature> importSignatures(File jarFile) throws Exception {
ZipFile zipFile = new ZipFile(jarFile);
SignatureClassVisitor visitor = new SignatureClassVisitor();
for (Enumeration<? extends ZipEntry> zipEnum = zipFile.entries(); zipEnum.hasMoreElements(); ) {
ZipEntry entry = zipEnum.nextElement();
if (entry.getName().endsWith(".class")) {
InputStream in = zipFile.getInputStream(entry);
ClassReader reader = new ClassReader(in);
reader.accept(visitor, ClassReader.SKIP_CODE + ClassReader.SKIP_DEBUG);
in.close();
}
}
zipFile.close();
for (ClassSignature classSig : visitor.classes.values()) {
classSig.initialzeParent(visitor.classes);
}
return visitor.classes;
}
Aggregations