From ac07e252571819685d3f74cb69c90c23abd340a0 Mon Sep 17 00:00:00 2001 From: "Marc R. Hoffmann" Date: Mon, 20 May 2013 12:56:11 +0200 Subject: Context information for error messages. Analyzer and Instrumenter now expect a resource name parameter to provide better messages in case of internal errors. --- .../src/org/jacoco/core/analysis/Analyzer.java | 86 +++++++++++-------- .../src/org/jacoco/core/instr/Instrumenter.java | 99 +++++++++++++--------- 2 files changed, 108 insertions(+), 77 deletions(-) (limited to 'org.jacoco.core/src/org') diff --git a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java index f25da1e1..0a55213d 100644 --- a/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java +++ b/org.jacoco.core/src/org/jacoco/core/analysis/Analyzer.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.io.InputStream; import java.util.StringTokenizer; import java.util.zip.GZIPInputStream; +import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; import org.jacoco.core.data.ExecutionData; @@ -100,9 +101,18 @@ public class Analyzer { * * @param buffer * class definitions + * @param name + * a name used for exception messages + * @throws IOException + * if the class can't be analyzed */ - public void analyzeClass(final byte[] buffer) { - analyzeClass(new ClassReader(buffer)); + public void analyzeClass(final byte[] buffer, final String name) + throws IOException { + try { + analyzeClass(new ClassReader(buffer)); + } catch (final RuntimeException cause) { + throw analyzerError(name, cause); + } } /** @@ -110,27 +120,26 @@ public class Analyzer { * * @param input * stream to read class definition from + * @param name + * a name used for exception messages * @throws IOException - * if the stream can't be read + * if the stream can't be read or the class can't be analyzed */ - public void analyzeClass(final InputStream input) throws IOException { - analyzeClass(new ClassReader(input)); + public void analyzeClass(final InputStream input, final String name) + throws IOException { + try { + analyzeClass(new ClassReader(input)); + } catch (final RuntimeException e) { + throw analyzerError(name, e); + } } - /** - * Analyzes all classes contained in the ZIP archive (jar, war, ear, etc.) - * given as an input stream. Contained archives are read recursively. - * - * @param input - * ZIP archive data - * @return number of class files found - * @throws IOException - * if the stream can't be read - * @deprecated Use {@link #analyzeAll(InputStream)} instead - */ - @Deprecated - public int analyzeArchive(final InputStream input) throws IOException { - return analyzeZip(input); + private IOException analyzerError(final String name, + final RuntimeException cause) { + final IOException ex = new IOException(String.format( + "Error while analyzing class %s.", name)); + ex.initCause(cause); + return ex; } /** @@ -141,22 +150,25 @@ public class Analyzer { * * @param input * input data + * @param name + * a name used for exception messages * @return number of class files found * @throws IOException - * if the stream can't be read + * if the stream can't be read or a class can't be analyzed */ - public int analyzeAll(final InputStream input) throws IOException { + public int analyzeAll(final InputStream input, final String name) + throws IOException { final ContentTypeDetector detector = new ContentTypeDetector(input); switch (detector.getType()) { case ContentTypeDetector.CLASSFILE: - analyzeClass(detector.getInputStream()); + analyzeClass(detector.getInputStream(), name); return 1; case ContentTypeDetector.ZIPFILE: - return analyzeZip(detector.getInputStream()); + return analyzeZip(detector.getInputStream(), name); case ContentTypeDetector.GZFILE: - return analyzeGzip(detector.getInputStream()); + return analyzeGzip(detector.getInputStream(), name); case ContentTypeDetector.PACK200FILE: - return analyzePack200(detector.getInputStream()); + return analyzePack200(detector.getInputStream(), name); default: return 0; } @@ -171,7 +183,7 @@ public class Analyzer { * file or folder to look for class files * @return number of class files found * @throws IOException - * if the file can't be read + * if the file can't be read or a class can't be analyzed */ public int analyzeAll(final File file) throws IOException { int count = 0; @@ -182,7 +194,7 @@ public class Analyzer { } else { final InputStream in = new FileInputStream(file); try { - count += analyzeAll(in); + count += analyzeAll(in, file.getPath()); } finally { in.close(); } @@ -202,7 +214,7 @@ public class Analyzer { * entries * @return number of class files found * @throws IOException - * if a file can't be read + * if a file can't be read or a class can't be analyzed */ public int analyzeAll(final String path, final File basedir) throws IOException { @@ -214,21 +226,25 @@ public class Analyzer { return count; } - private int analyzeZip(final InputStream input) throws IOException { + private int analyzeZip(final InputStream input, final String name) + throws IOException { final ZipInputStream zip = new ZipInputStream(input); + ZipEntry entry; int count = 0; - while (zip.getNextEntry() != null) { - count += analyzeAll(zip); + while ((entry = zip.getNextEntry()) != null) { + count += analyzeAll(zip, name + "@" + entry.getName()); } return count; } - private int analyzeGzip(final InputStream input) throws IOException { - return analyzeAll(new GZIPInputStream(input)); + private int analyzeGzip(final InputStream input, final String name) + throws IOException { + return analyzeAll(new GZIPInputStream(input), name); } - private int analyzePack200(final InputStream input) throws IOException { - return analyzeAll(Pack200Streams.unpack(input)); + private int analyzePack200(final InputStream input, final String name) + throws IOException { + return analyzeAll(Pack200Streams.unpack(input), name); } } diff --git a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java index 9f7c5158..c4d52669 100644 --- a/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java +++ b/org.jacoco.core/src/org/jacoco/core/instr/Instrumenter.java @@ -84,11 +84,19 @@ public class Instrumenter { * * @param buffer * definition of the class + * @param name + * a name used for exception messages * @return instrumented definition - * + * @throws IOException + * if the class can't be analyzed */ - public byte[] instrument(final byte[] buffer) { - return instrument(new ClassReader(buffer)); + public byte[] instrument(final byte[] buffer, final String name) + throws IOException { + try { + return instrument(new ClassReader(buffer)); + } catch (final RuntimeException e) { + throw instrumentError(name, e); + } } /** @@ -96,12 +104,20 @@ public class Instrumenter { * * @param input * stream to read class definition from + * @param name + * a name used for exception messages * @return instrumented definition * @throws IOException - * if reading data from the stream fails + * if reading data from the stream fails or the class can't be + * instrumented */ - public byte[] instrument(final InputStream input) throws IOException { - return instrument(new ClassReader(input)); + public byte[] instrument(final InputStream input, final String name) + throws IOException { + try { + return instrument(new ClassReader(input)); + } catch (final RuntimeException e) { + throw instrumentError(name, e); + } } /** @@ -111,32 +127,27 @@ public class Instrumenter { * stream to read class definition from * @param output * stream to write the instrumented version of the class to + * @param name + * a name used for exception messages * @throws IOException - * if reading data from the stream fails + * if reading data from the stream fails or the class can't be + * instrumented */ - public void instrument(final InputStream input, final OutputStream output) - throws IOException { - output.write(instrument(new ClassReader(input))); + public void instrument(final InputStream input, final OutputStream output, + final String name) throws IOException { + try { + output.write(instrument(new ClassReader(input))); + } catch (final RuntimeException e) { + throw instrumentError(name, e); + } } - /** - * Creates a instrumented version of the given archive, i.e. with all class - * files contained in this archive instrumented. Contained resources which - * are no class files or archive files are copied as is. - * - * @param input - * stream to read archive from - * @param output - * stream to write the instrumented version of the class to - * @return number of instrumented classes - * @throws IOException - * if reading data from the stream fails - * @deprecated Use {@link #instrumentAll(InputStream, OutputStream)} instead - */ - @Deprecated - public int instrumentArchive(final InputStream input, - final OutputStream output) throws IOException { - return instrumentZip(input, output); + private IOException instrumentError(final String name, + final RuntimeException cause) { + final IOException ex = new IOException(String.format( + "Error while instrumenting class %s.", name)); + ex.initCause(cause); + return ex; } /** @@ -148,38 +159,41 @@ public class Instrumenter { * stream to contents from * @param output * stream to write the instrumented version of the contents + * @param name + * a name used for exception messages * @return number of instrumented classes * @throws IOException - * if reading data from the stream fails + * if reading data from the stream fails or a class can't be + * instrumented */ - public int instrumentAll(final InputStream input, final OutputStream output) - throws IOException { + public int instrumentAll(final InputStream input, + final OutputStream output, final String name) throws IOException { final ContentTypeDetector detector = new ContentTypeDetector(input); switch (detector.getType()) { case ContentTypeDetector.CLASSFILE: - instrument(detector.getInputStream(), output); + instrument(detector.getInputStream(), output, name); return 1; case ContentTypeDetector.ZIPFILE: - return instrumentZip(detector.getInputStream(), output); + return instrumentZip(detector.getInputStream(), output, name); case ContentTypeDetector.GZFILE: - return instrumentGzip(detector.getInputStream(), output); + return instrumentGzip(detector.getInputStream(), output, name); case ContentTypeDetector.PACK200FILE: - return instrumentPack200(detector.getInputStream(), output); + return instrumentPack200(detector.getInputStream(), output, name); default: copy(detector.getInputStream(), output); return 0; } } - private int instrumentZip(final InputStream input, final OutputStream output) - throws IOException { + private int instrumentZip(final InputStream input, + final OutputStream output, final String name) throws IOException { final ZipInputStream zipin = new ZipInputStream(input); final ZipOutputStream zipout = new ZipOutputStream(output); ZipEntry entry; int count = 0; while ((entry = zipin.getNextEntry()) != null) { zipout.putNextEntry(new ZipEntry(entry.getName())); - count += instrumentAll(zipin, zipout); + count += instrumentAll(zipin, zipout, name + "@" + entry.getName()); zipout.closeEntry(); } zipout.finish(); @@ -187,17 +201,18 @@ public class Instrumenter { } private int instrumentGzip(final InputStream input, - final OutputStream output) throws IOException { + final OutputStream output, final String name) throws IOException { final GZIPOutputStream gzout = new GZIPOutputStream(output); - final int count = instrumentAll(new GZIPInputStream(input), gzout); + final int count = instrumentAll(new GZIPInputStream(input), gzout, name); gzout.finish(); return count; } private int instrumentPack200(final InputStream input, - final OutputStream output) throws IOException { + final OutputStream output, final String name) throws IOException { final ByteArrayOutputStream buffer = new ByteArrayOutputStream(); - final int count = instrumentAll(Pack200Streams.unpack(input), buffer); + final int count = instrumentAll(Pack200Streams.unpack(input), buffer, + name); Pack200Streams.pack(buffer.toByteArray(), output); return count; } -- cgit v1.2.3