Skip to content

Commit

Permalink
handled fatal analysis failure due to JVM bug.
Browse files Browse the repository at this point in the history
When analysis failes an explanation is printed to console, with stacktrace and a link to the github issue  #68

The Tests that triggered the failure are included on JDK versions with the problem.
  • Loading branch information
schauder committed Aug 31, 2016
1 parent 8feb933 commit a946f89
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,33 @@ object Analyzer extends AnalyzerLike {
def analyze(sourceFolder: String, categorizer: (Node) => Node, filter: (Node) => Boolean): Graph = {
val g = new Graph(categorizer, filter, new NoSelfReference(categorizer))

def analyze(f : File)={
def readStream(reader: ClassReader, name: String): Unit = {
try {
reader.accept(new GraphBuildingClassVisitor(g), 0)
} catch {
case e: Exception =>
println("Something went wrong when analyzing " + name)
println("For this class some or all dependencies will be missing.")
println("This is most likely due to a bug in the JDK (no, really) or ASM,")
println("see https://github.com/schauder/degraph/issues/68 for details.")
println("If the stacktrace below does not match what you see in the issue above,")
println("please create a new issue and include the stacktrace.")
e.printStackTrace()
}
}

def analyze(f: File) = {
if (f.getName.endsWith(".class")) {
val reader = new ClassReader(new BufferedInputStream(new FileInputStream(f)))
reader.accept(new GraphBuildingClassVisitor(g), 0)
readStream(reader, f.getName)
} else {
val zipFile = new ZipFile(f)
val entries = zipFile.entries()
while (entries.hasMoreElements) {
val e = entries.nextElement()
if (e.getName.endsWith(".class")) {
val reader = new ClassReader(zipFile.getInputStream(e))
reader.accept(new GraphBuildingClassVisitor(g), 0)
readStream(reader, e.getName)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,21 @@ import org.scalatest.Matchers._

@RunWith(classOf[JUnitRunner])
class AnalyzerTest extends FunSuite {


private val testClassFolder = System.getProperty("java.class.path")
private val graphs = Map(
"asm" -> asm.Analyzer.analyze(testClassFolder, x => x, _ => true))

private def isJavaVersionWithBrokenTypeAnnotations: Boolean = {
val javaVersionString = System.getProperty("java.version")
javaVersionString > "1.8.0_31"
}

private val graphs =
if (isJavaVersionWithBrokenTypeAnnotations)
Map()
else
Map(
"asm" -> asm.Analyzer.analyze(testClassFolder, x => x, _ => true))


for ((label, graph) <- graphs) {
Expand Down Expand Up @@ -58,6 +70,7 @@ class AnalyzerTest extends FunSuite {
graph should connect("de.schauderhaft.degraph.jdk8tests.ClassWithTypeAnnotations" -> "de.schauderhaft.degraph.jdk8tests.TypeAnno8")
}


def connect(connection: (String, String)) = {
val (from, to) = connection
new Matcher[Graph] {
Expand All @@ -84,4 +97,12 @@ class AnalyzerTest extends FunSuite {
}
}
}

// if annotations are broken, at least verify that broken stuff doesn't completely kill the analysis
if (isJavaVersionWithBrokenTypeAnnotations) {
test("Analysis does not explode") {
asm.Analyzer.analyze(testClassFolder, x => x, _ => true)
}
}

}
7 changes: 7 additions & 0 deletions releaseNotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
- `printTo` in the ConstraintBuilder now always prints the analysis results. If you want the old behaviour back, use
`printOnFailure`

- `Check` and `JCheck` got a new method `customClasspath`. You can use it in order to provide a classpath explicitly
instead of using the classpath used by the current JVM.

- ConstraintBuilder got a new method `filterClasspath(pattern: String): ConstraintBuilder`
for limiting the classpath to elements matching the pattern.
This should be useful, if you want to analyze some, but not all jar-files.
Expand All @@ -21,6 +24,10 @@

- minor performance improvements

### Known Issues

- Due to a JDK or ASM bug analysis of class files which contain Type-Annotations might fail. Dependencies of such classes
will be incomplete. A message saying so will be displayed. See

## 0.1.3

Expand Down

0 comments on commit a946f89

Please sign in to comment.