Skip to content

Commit

Permalink
Minor code cleanups
Browse files Browse the repository at this point in the history
Signed-off-by: Alexander Pinčuk <alexander.v.pinchuk@gmail.com>
  • Loading branch information
avpinchuk committed Jun 4, 2023
1 parent 1127fe0 commit fbfc8c7
Showing 1 changed file with 56 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
import java.time.Instant;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
Expand All @@ -76,9 +75,9 @@
import static java.util.logging.Level.INFO;

/**
* Class loader used by the ejbs of an application or stand alone module.
* Class loader used by the ejbs of an application or stand-alone module.
*
* This class loader also keeps cache of not found classes and resources.
* <p>This class loader also keeps cache of not found classes and resources.
*
* @author Nazrul Islam
* @author Kenneth Saks
Expand Down Expand Up @@ -198,7 +197,7 @@ public void close() throws IOException {
+ "\n AT " + Instant.now() +
" \n BY :" + Arrays.toString(Thread.currentThread().getStackTrace());

// Presumably OK to set this flag now while the rest of the cleanup proceeeds,
// Presumably OK to set this flag now while the rest of the cleanup proceeds,
// because we've taken the snapshot.
doneCalled = true;

Expand All @@ -221,12 +220,8 @@ public void close() throws IOException {
// clears out the tables
// Clear all values. Because fields are 'final' (for thread safety), cannot null them
this.urlSet.clear();
if (this.notFoundResources != null) {
this.notFoundResources.clear();
}
if (this.notFoundClasses != null) {
this.notFoundClasses.clear();
}
this.notFoundResources.clear();
this.notFoundClasses.clear();
}

super.close();
Expand Down Expand Up @@ -265,7 +260,7 @@ public void addURL(URL url) {


/**
* Add a url to the list of urls we search for a class's bytecodes.
* Add an url to the list of urls we search for a class's bytecodes.
*
* @param url url to be added
*/
Expand Down Expand Up @@ -307,7 +302,8 @@ public synchronized void appendURL(URL url) {

/**
* Returns the urls of this class loader.
* Method is 'synchronized' to avoid the thread-unsafe null-check idiom idiom, also
*
* <p>Method is {@code synchronized} to avoid the thread-unsafe null-check idiom, also
* protects the caller from simultaneous changes while iterating,
* by returning a URL[] (copy) rather than the original. Also protects against
* changes to 'urlSet' while iterating over it.
Expand All @@ -316,24 +312,14 @@ public synchronized void appendURL(URL url) {
*/
@Override
public synchronized URL[] getURLs() {
final URL[] url;
if (this.urlSet != null) {
url = new URL[this.urlSet.size()];
int i = 0;
for (URLEntry urlEntry : urlSet) {
url[i++] = urlEntry.source;
}
} else {
url = new URL[0];
}
return url;
return urlSet.stream().map(urlEntry -> urlEntry.source).toArray(URL[]::new);
}

/**
* Returns all the "file" protocol resources of this ASURLClassLoader,
* concatenated to a classpath string.
*
* Notice that this method is called by the setClassPath() method of
* <p>Notice that this method is called by the setClassPath() method of
* org.apache.catalina.loader.WebappLoader, since this ASURLClassLoader does
* not extend off of URLClassLoader.
*
Expand Down Expand Up @@ -362,7 +348,7 @@ public String getClasspath() {

/**
* Refreshes the memory of the class loader. This involves clearing the
* not-found cahces and recreating the hash tables for the URLEntries that
* not-found caches and recreating the hash tables for the URLEntries that
* record the files accessible for each.
* <p>
* Code that creates an ASURLClassLoader and then adds files to a directory
Expand All @@ -384,7 +370,7 @@ public void addTransformer(ClassFileTransformer transformer) {


/**
* Create a new instance of a sibling classloader
* Create a new instance of a sibling classloader.
*
* @return a new instance of a class loader that has the same visibility
* as this class loader
Expand Down Expand Up @@ -462,7 +448,7 @@ private URL findResource0(final URLEntry res, final String name) {

@Override
public URL findResource(String name) {
// quick quick that relies on 'doneCalled' being 'volatile'
// quick that relies on 'doneCalled' being 'volatile'
if (doneCalled) {
_logger.log(Level.WARNING, CULoggerInfo.getString(CULoggerInfo.findResourceAfterDone, name, this),
new Throwable());
Expand All @@ -476,7 +462,7 @@ public URL findResource(String name) {
//
// HOWEVER, there is still a race condition from the check for 'doneCalled' above.
// That's OK for 'notFoundResources', but it could lead to an ArrayIndexOutOfBounds
// excpetion for 'urlSet', should the set be cleared while looping.
// exception for 'urlSet', should the set be cleared while looping.

// resource is in the not found list
String nf = notFoundResources.get(name);
Expand Down Expand Up @@ -591,7 +577,7 @@ private byte[] loadClassData0(final URLEntry res, final String entryName) {
PrivilegedAction<byte[]> action = () -> {
InputStream classStream = null;
try {
if (res.isJar) { // It is a jarfile..
if (res.isJar) { // It is a jarfile.
JarFile zip = res.zip;
JarEntry entry = zip.getJarEntry(entryName);
if (entry != null) {
Expand All @@ -601,8 +587,7 @@ private byte[] loadClassData0(final URLEntry res, final String entryName) {
return classData1;
}
} else { // Its a directory....
File classFile = new File (res.file,
entryName.replace('/', File.separatorChar));
File classFile = new File (res.file, entryName.replace('/', File.separatorChar));

if (classFile.exists()) {
try {
Expand All @@ -612,9 +597,9 @@ private byte[] loadClassData0(final URLEntry res, final String entryName) {
return classData2;
} finally {
/*
*Close the stream only if this is a directory. The stream for
*a jar/zip file was opened elsewhere and should remain open after this
*method completes.
* Close the stream only if this is a directory. The stream for
* a jar/zip file was opened elsewhere and should remain open after this
* method completes.
*/
if (classStream != null) {
try {
Expand Down Expand Up @@ -670,15 +655,15 @@ protected PermissionCollection getPermissions(CodeSource codeSource) {
* and thus works on the same classData? Or defines the same package? Maybe
* the same work just gets done twice, and that's all.
* <p>
* CAUTION: this method might be overriden, and subclasses must be cautious (also)
* CAUTION: this method might be overridden, and subclasses must be cautious (also)
* about thread safety.
*/
@Override
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
// search through 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()));
}
Expand Down Expand Up @@ -741,8 +726,7 @@ protected Class<?> findClass(String name) throws ClassNotFoundException {
}
try {
byte[] bytes = classData.getClassBytes();
Class<?> clazz = defineClass(name, bytes, 0, bytes.length, classData.pd);
return clazz;
return defineClass(name, bytes, 0, bytes.length, classData.pd);
} catch (UnsupportedClassVersionError ucve) {
throw new UnsupportedClassVersionError(
sm.getString("ejbClassLoader.unsupportedVersion", name, System.getProperty("java.version")));
Expand Down Expand Up @@ -773,7 +757,7 @@ private synchronized ClassData findClassData(String name) throws ClassNotFoundEx
throw new ClassNotFoundException(name);
}

// search thru the JARs for a file of the form java/lang/Object.class
// search through the JARs for a file of the form java/lang/Object.class
String entryName = name.replace('.', '/') + ".class";

for (URLEntry u : this.urlSet) {
Expand Down Expand Up @@ -992,16 +976,16 @@ private void fillTable(File f, HashMap<String, String> t, String parent) throws
}

/**
*Adds a file (or, if a directory, the directory's contents) to the table
*of files this loader knows about.
*<p>
*Invokes fillTable for subdirectories which in turn invokes processFile
*recursively.
*@param fileToProcess the File to be processed
*@param t the HashMap that holds the files the loader knows about
*@param parentLocalName prefix to be used for the full path; should be
*non-empty only for recursive invocations
*@throws IOException in case of errors working with the fileToProcess
* Adds a file (or, if a directory, the directory's contents) to the table
* of files this loader knows about.
* <p>
* Invokes fillTable for subdirectories which in turn invokes processFile
* recursively.
* @param fileToProcess the File to be processed
* @param t the HashMap that holds the files the loader knows about
* @param parentLocalName prefix to be used for the full path; should be
* non-empty only for recursive invocations
* @throws IOException in case of errors working with the fileToProcess
*/
private void processFile(File fileToProcess, HashMap<String, String> t, String parentLocalName) throws IOException {
String key = parentLocalName + fileToProcess.getName();
Expand All @@ -1014,33 +998,33 @@ private void processFile(File fileToProcess, HashMap<String, String> t, String p


private boolean hasItem(String item) {
// in the case of ejbc stub compilation, asurlclassloader is created before stubs
// in the case of ejbc stub compilation, ASURLClassLoader is created before stubs
// gets generated, thus we need to return true for this case.
if (table.isEmpty()) {
return true;
}

/*
*Even with the previous special handling, a file could be created
*in a directory after the loader was created and its table of
*URLEntry names populated. So check the table first and, if
*the target item is not there and this URLEntry is for a directory, look for
*the file. If the file is now present but was not when the loader
*was created, add an entry for the file in the table.
* Even with the previous special handling, a file could be created
* in a directory after the loader was created and its table of
* URLEntry names populated. So check the table first and, if
* the target item is not there and this URLEntry is for a directory, look for
* the file. If the file is now present but was not when the loader
* was created, add an entry for the file in the table.
*/
boolean result;
String target = item;
// special handling
if (item.startsWith("./")) {
target = item.substring(2, item.length());
target = item.substring(2);
}

result = table.containsKey(target);
if ( ! result && ! isJar) {
/*
*If the file exists now then it has been added to the directory since the
*loader was created. Add it to the table of files we
*know about.
* If the file exists now then it has been added to the directory since the
* loader was created. Add it to the table of files we
* know about.
*/
File targetFile = privilegedCheckForFile(target);
if (targetFile != null) {
Expand All @@ -1059,19 +1043,18 @@ private boolean hasItem(String item) {
}

/**
*Returns a File object for the requested path within the URLEntry.
*<p>
*Runs privileged because user code could trigger invocations of this
*method.
*@param targetPath the relative path to look for
*@return File object for the requested file; null if it does not exist or
*in case of error
* Returns a File object for the requested path within the URLEntry.
* <p>
* Runs privileged because user code could trigger invocations of this method.
* @param targetPath the relative path to look for
* @return File object for the requested file; null if it does not exist or
* in case of error
*/
private File privilegedCheckForFile(final String targetPath) {
/*
*Check for the file existence with privs, because this code can
*be invoked from user code which may not otherwise have access
*to the directories of interest.
* Check for the file existence with privs, because this code can
* be invoked from user code which may not otherwise have access
* to the directories of interest.
*/
try {
PrivilegedExceptionAction<File> action = () -> {
Expand Down Expand Up @@ -1249,10 +1232,8 @@ protected URLConnection openConnection(final URL u) throws IOException {
throw new IOException("Cannot open a foreign URL; this.url=" + mURL + "; foreign.url=" + u);
}
String entryName = path.substring(separator + 1);
if (entryName != null) {
assert (entryName.startsWith("/"));
entryName = entryName.substring(1);
}
assert (entryName.startsWith("/"));
entryName = entryName.substring(1);
return new InternalJarURLConnection(u, mRes, entryName);
} catch (URISyntaxException e) {
throw new IOException(e);
Expand Down Expand Up @@ -1304,7 +1285,6 @@ private synchronized byte[] getClassBytes() {
private synchronized void setClassBytes(byte[] newBytes) {
classBytes = newBytes;
}

}

/**
Expand All @@ -1327,6 +1307,7 @@ private static final class DelegatingClassLoader extends SecureClassLoader {

/**
* Create a new instance.
*
* @param applicationCL is the original class loader associated
* with this application. The new class loader uses it to delegate
* stream handling operations. The new class loader also uses
Expand Down

0 comments on commit fbfc8c7

Please sign in to comment.