use of java.lang.instrument.ClassFileTransformer in project Payara by payara.
the class ASURLClassLoader method findClass.
/**
* THREAD SAFETY: what happens when more than one thread requests the same class
* and thus works on the same classData? Or defines the same package? Maybe
* the same work just gets done twice, and that's all.
* CAUTION: this method might be overriden, and subclasses must be cautious (also)
* about thread safety.
*/
protected Class findClass(String name) throws ClassNotFoundException {
ClassData classData = findClassData(name);
// Instruments the classes if the profiler's enabled
if (PreprocessorUtil.isPreprocessorEnabled()) {
// search thru the JARs for a file of the form java/lang/Object.class
final String entryName = name.replace('.', '/') + ".class";
classData.setClassBytes(PreprocessorUtil.processClass(entryName, classData.getClassBytes()));
}
// Define package information if necessary
int lastPackageSep = name.lastIndexOf('.');
if (lastPackageSep != -1) {
String packageName = name.substring(0, lastPackageSep);
if (getPackage(packageName) == null) {
try {
// There's a small chance that one of our parents
// could define the same package after getPackage
// returns null but before we call definePackage,
// since the parent classloader instances
// are not locked. So, just catch the exception
// that is thrown in that case and ignore it.
//
// It's unclear where we would get the info to
// set all spec and impl data for the package,
// so just use null. This is consistent will the
// JDK code that does the same.
definePackage(packageName, null, null, null, null, null, null, null);
} catch (IllegalArgumentException iae) {
// duplicate attempt to define same package.
// safe to ignore.
_logger.log(Level.FINE, "duplicate package " + "definition attempt for " + packageName, iae);
}
}
}
// Loop though the transformers here!!
try {
final ArrayList<ClassFileTransformer> xformers = (ArrayList<ClassFileTransformer>) transformers.clone();
for (final ClassFileTransformer transformer : xformers) {
// see javadocs of transform().
// It expects class name as java/lang/Object
// as opposed to java.lang.Object
final String internalClassName = name.replace('.', '/');
final byte[] transformedBytes = transformer.transform(this, internalClassName, null, classData.pd, classData.getClassBytes());
if (transformedBytes != null) {
// null indicates no transformation
_logger.log(Level.INFO, CULoggerInfo.actuallyTransformed, name);
classData.setClassBytes(transformedBytes);
}
}
} catch (IllegalClassFormatException icfEx) {
throw new ClassNotFoundException(icfEx.toString(), icfEx);
}
Class clazz = null;
try {
byte[] bytes = classData.getClassBytes();
clazz = defineClass(name, bytes, 0, bytes.length, classData.pd);
return clazz;
} catch (UnsupportedClassVersionError ucve) {
throw new UnsupportedClassVersionError(sm.getString("ejbClassLoader.unsupportedVersion", name, System.getProperty("java.version")));
}
}
Aggregations