in extscript-core-root/extscript-core/src/main/java/org/apache/myfaces/extensions/scripting/core/engine/ThrowAwayClassloader.java [78:137]
public Class<?> loadClass(String className) throws ClassNotFoundException
{
ClassResource res = (ClassResource) WeavingContext.getInstance().getResource(className);
if (res == null) return super.loadClass(className);
if (!res.isTainted() && res.getAClass() != null) return res.getAClass();
File target = resolveClassFile(className);
//a load must happen anyway because the target was recompiled
int fileLength;
byte[] fileContent;
FileInputStream iStream = null;
//we cannot load while a compile is in progress
//we have to wait until it is one
try
{
fileLength = (int) target.length();
fileContent = new byte[fileLength];
iStream = new FileInputStream(target);
int result = iStream.read(fileContent);
_logger.log(Level.FINER, "read {0} bytes", String.valueOf(result));
}
catch (FileNotFoundException e)
{
throw new ClassNotFoundException(e.toString());
}
catch (IOException e)
{
throw new ClassNotFoundException(e.toString());
}
finally
{
if (iStream != null)
{
try
{
iStream.close();
}
catch (Exception e)
{
Logger log = Logger.getLogger(this.getClass().getName());
log.log(SEVERE, "", e);
}
}
}
//here we use trick17 we can store as many classes of the same name
//as long as we store with a new classloader every time it needs refresh
//we need to do it because the classloader can call itself recursively
//TODO we might run into issues here with inner classes
Class retVal;
if (res != null) {
retVal = (new ThrowAwayClassloader(getParent(),_untaint)).defineClass(className, fileContent, 0, fileLength);
if(_untaint) {
res.setAClass(retVal);
res.setTainted(false);
}
} else {
retVal = super.defineClass(className, fileContent, 0, fileLength);
}
return retVal;
}