418596 Faults in JARs during class scanning should report the jar that caused the problem

This commit is contained in:
Jan Bartel 2013-10-04 11:01:31 +10:00
parent a0ddb2c5d7
commit d505350a9f
4 changed files with 69 additions and 70 deletions

View File

@ -278,24 +278,18 @@ public class AnnotationConfiguration extends AbstractConfiguration
throws Exception
{
AnnotationParser parser = createAnnotationParser();
boolean multiThreadedScan = isUseMultiThreading(context);
int maxScanWait = 0;
if (multiThreadedScan)
{
_parserTasks = new ArrayList<ParserTask>();
maxScanWait = getMaxScanWait(context);
}
_parserTasks = new ArrayList<ParserTask>();
long start = 0;
if (LOG.isDebugEnabled())
{
start = System.nanoTime();
LOG.debug("Scanning for annotations: webxml={}, metadatacomplete={}, configurationDiscovered={}, multiThreaded={}",
LOG.debug("Scanning for annotations: webxml={}, metadatacomplete={}, configurationDiscovered={}, multiThreaded={}, maxScanWait={}",
context.getServletContext().getEffectiveMajorVersion(),
context.getMetaData().isMetaDataComplete(),
context.isConfigurationDiscovered(),
multiThreadedScan);
isUseMultiThreading(context),
getMaxScanWait(context));
}
parseContainerPath(context, parser);
@ -307,23 +301,15 @@ public class AnnotationConfiguration extends AbstractConfiguration
parseWebInfClasses(context, parser);
parseWebInfLib (context, parser);
if (!multiThreadedScan)
{
if (LOG.isDebugEnabled())
{
long end = System.nanoTime();
LOG.debug("Annotation parsing millisec={}",(TimeUnit.MILLISECONDS.convert(end-start, TimeUnit.NANOSECONDS)));
}
return;
}
if (LOG.isDebugEnabled())
start = System.nanoTime();
//execute scan asynchronously using jetty's thread pool
//execute scan, either effectively synchronously (1 thread only), or asychronously (limited by number of processors available)
final Semaphore task_limit = (isUseMultiThreading(context)? new Semaphore(Runtime.getRuntime().availableProcessors()):new Semaphore(1));
final CountDownLatch latch = new CountDownLatch(_parserTasks.size());
final MultiException me = new MultiException();
final Semaphore task_limit=new Semaphore(Runtime.getRuntime().availableProcessors());
for (final ParserTask p:_parserTasks)
{
task_limit.acquire();
@ -349,13 +335,10 @@ public class AnnotationConfiguration extends AbstractConfiguration
});
}
boolean timeout = !latch.await(maxScanWait, TimeUnit.SECONDS);
boolean timeout = !latch.await(getMaxScanWait(context), TimeUnit.SECONDS);
if (LOG.isDebugEnabled())
{
long end = System.nanoTime();
LOG.debug("Annotation parsing millisec={}",(TimeUnit.MILLISECONDS.convert(end-start, TimeUnit.NANOSECONDS)));
}
LOG.debug("Annotation parsing millisec={}",(TimeUnit.MILLISECONDS.convert(System.nanoTime()-start, TimeUnit.NANOSECONDS)));
if (timeout)
me.add(new Exception("Timeout scanning annotations"));
@ -607,9 +590,6 @@ public class AnnotationConfiguration extends AbstractConfiguration
//queue it up for scanning if using multithreaded mode
if (_parserTasks != null)
_parserTasks.add(new ParserTask(parser, handlers, r, _containerClassNameResolver));
else
//just scan it now
parser.parse(handlers, r, _containerClassNameResolver);
}
}
@ -664,8 +644,6 @@ public class AnnotationConfiguration extends AbstractConfiguration
if (_parserTasks != null)
_parserTasks.add (new ParserTask(parser, handlers,r, _webAppClassNameResolver));
else
parser.parse(handlers, r, _webAppClassNameResolver);
}
}
@ -694,8 +672,6 @@ public class AnnotationConfiguration extends AbstractConfiguration
{
if (_parserTasks != null)
_parserTasks.add(new ParserTask(parser, handlers, dir, _webAppClassNameResolver));
else
parser.parse(handlers, dir, _webAppClassNameResolver);
}
}

View File

@ -39,6 +39,7 @@ import java.util.jar.JarInputStream;
import org.eclipse.jetty.util.ConcurrentHashSet;
import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.util.MultiException;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
@ -614,6 +615,7 @@ public class AnnotationParser
}
}
}
if (visitSuperClasses)
cz = cz.getSuperclass();
else
@ -650,19 +652,29 @@ public class AnnotationParser
public void parse (Set<? extends Handler> handlers, List<String> classNames, ClassNameResolver resolver)
throws Exception
{
MultiException me = new MultiException();
for (String s:classNames)
{
if ((resolver == null) || (!resolver.isExcluded(s) && (!isParsed(s) || resolver.shouldOverride(s))))
try
{
s = s.replace('.', '/')+".class";
URL resource = Loader.getResource(this.getClass(), s);
if (resource!= null)
if ((resolver == null) || (!resolver.isExcluded(s) && (!isParsed(s) || resolver.shouldOverride(s))))
{
Resource r = Resource.newResource(resource);
scanClass(handlers, null, r.getInputStream());
s = s.replace('.', '/')+".class";
URL resource = Loader.getResource(this.getClass(), s);
if (resource!= null)
{
Resource r = Resource.newResource(resource);
scanClass(handlers, null, r.getInputStream());
}
}
}
catch (Exception e)
{
me.add(new RuntimeException("Error scanning class "+s, e));
}
}
me.ifExceptionThrow();
}
@ -682,25 +694,27 @@ public class AnnotationParser
if (LOG.isDebugEnabled()) {LOG.debug("Scanning dir {}", dir);};
MultiException me = new MultiException();
String[] files=dir.list();
for (int f=0;files!=null && f<files.length;f++)
{
try
Resource res = dir.addPath(files[f]);
if (res.isDirectory())
parseDir(handlers, res, resolver);
else
{
Resource res = dir.addPath(files[f]);
if (res.isDirectory())
parseDir(handlers, res, resolver);
//we've already verified the directories, so just verify the class file name
boolean valid = true;
File file = res.getFile();
if (file == null)
LOG.warn("Unable to validate class file name for {}", res);
else
valid = isValidClassFileName(file.getName());
if (valid)
{
//we've already verified the directories, so just verify the class file name
boolean valid = true;
File file = res.getFile();
if (file == null)
LOG.warn("Unable to validate class file name for {}", res);
else
valid = isValidClassFileName(file.getName());
if (valid)
try
{
String name = res.getName();
if ((resolver == null)|| (!resolver.isExcluded(name) && (!isParsed(name) || resolver.shouldOverride(name))))
@ -709,15 +723,16 @@ public class AnnotationParser
if (LOG.isDebugEnabled()) {LOG.debug("Scanning class {}", r);};
scanClass(handlers, dir, r.getInputStream());
}
}
catch (Exception ex)
{
me.add(new RuntimeException("Error scanning file "+files[f],ex));
}
}
}
catch (Exception ex)
{
LOG.warn(Log.EXCEPTION,ex);
}
}
me.ifExceptionThrow();
}
@ -740,6 +755,8 @@ public class AnnotationParser
if (!(loader instanceof URLClassLoader))
return; //can't extract classes?
final MultiException me = new MultiException();
JarScanner scanner = new JarScanner()
{
@Override
@ -751,13 +768,14 @@ public class AnnotationParser
}
catch (Exception e)
{
LOG.warn("Problem parsing jar entry: {}", entry.getName());
me.add(new RuntimeException("Error parsing entry "+entry.getName()+" from jar "+ jarUri, e));
}
}
};
scanner.scan(null, loader, nullInclusive, visitParents);
me.ifExceptionThrow();
}
@ -774,6 +792,8 @@ public class AnnotationParser
if (uris==null)
return;
MultiException me = new MultiException();
for (URI uri:uris)
{
try
@ -782,10 +802,10 @@ public class AnnotationParser
}
catch (Exception e)
{
LOG.warn("Problem parsing classes from {}", uri);
me.add(new RuntimeException("Problem parsing classes from "+ uri, e));
}
}
me.ifExceptionThrow();
}
/**
@ -801,8 +821,6 @@ public class AnnotationParser
return;
parse (handlers, Resource.newResource(uri), resolver);
}
@ -895,13 +913,22 @@ public class AnnotationParser
if (in==null)
return;
MultiException me = new MultiException();
JarInputStream jar_in = new JarInputStream(in);
try
{
JarEntry entry = jar_in.getNextJarEntry();
while (entry!=null)
{
parseJarEntry(handlers, jarResource, entry, resolver);
try
{
parseJarEntry(handlers, jarResource, entry, resolver);
}
catch (Exception e)
{
me.add(new RuntimeException("Error scanning entry "+entry.getName()+" from jar "+jarResource, e));
}
entry = jar_in.getNextJarEntry();
}
}
@ -909,7 +936,8 @@ public class AnnotationParser
{
jar_in.close();
}
}
me.ifExceptionThrow();
}
}
/**

View File

@ -25,7 +25,6 @@ import java.util.Set;
import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.annotations.AnnotationParser;
import org.eclipse.jetty.annotations.AnnotationParser.Handler;
import org.eclipse.jetty.annotations.ClassNameResolver;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.resource.Resource;
@ -86,8 +85,6 @@ public class MavenAnnotationConfiguration extends AnnotationConfiguration
throws Exception
{
if (_parserTasks != null)
_parserTasks.add(new ParserTask(parser, handlers, resource, _webAppClassNameResolver));
else
parser.parse(handlers, resource, _webAppClassNameResolver);
_parserTasks.add(new ParserTask(parser, handlers, resource, _webAppClassNameResolver));
}
}

View File

@ -179,8 +179,6 @@ public class AnnotationConfiguration extends org.eclipse.jetty.annotations.Annot
ClassNameResolver classNameResolver = createClassNameResolver(context);
if (_parserTasks != null)
_parserTasks.add(new BundleParserTask(parser, handlers, bundleRes, classNameResolver));
else
parser.parse(handlers, bundle, classNameResolver);
}
/**