@@ -4,11 +4,13 @@ import org.objectweb.asm
4
4
import org .objectweb .asm .ClassReader
5
5
6
6
import java .io .{ByteArrayInputStream , InputStream }
7
+ import java .nio .file .NoSuchFileException
7
8
import java .util .jar .{Attributes , JarFile , JarInputStream , Manifest }
8
9
import java .util .zip .ZipEntry
9
10
10
11
import scala .build .input .Element
11
12
import scala .build .internal .zip .WrappedZipInputStream
13
+ import scala .build .{Logger , retry }
12
14
13
15
object MainClass {
14
16
@@ -44,29 +46,54 @@ object MainClass {
44
46
if (foundMainClass) nameOpt else None
45
47
}
46
48
47
- def findInClass (path : os.Path ): Iterator [String ] =
48
- findInClass(os.read.inputStream(path))
49
- def findInClass (is : InputStream ): Iterator [String ] =
49
+ private def findInClass (path : os.Path , logger : Logger ): Iterator [String ] =
50
50
try {
51
- val reader = new ClassReader (is)
52
- val checker = new MainMethodChecker
53
- reader.accept(checker, 0 )
54
- checker.mainClassOpt.iterator
51
+ val is = retry()(logger)(os.read.inputStream(path))
52
+ findInClass(is, logger)
53
+ }
54
+ catch {
55
+ case e : NoSuchFileException =>
56
+ e.getStackTrace.foreach(ste => logger.debug(ste.toString))
57
+ logger.log(s " Class file $path not found: $e" )
58
+ logger.log(" Are you trying to run too many builds at once? Trying to recover..." )
59
+ Iterator .empty
60
+ }
61
+ private def findInClass (is : InputStream , logger : Logger ): Iterator [String ] =
62
+ try retry()(logger) {
63
+ val reader = new ClassReader (is)
64
+ val checker = new MainMethodChecker
65
+ reader.accept(checker, 0 )
66
+ checker.mainClassOpt.iterator
67
+ }
68
+ catch {
69
+ case e : ArrayIndexOutOfBoundsException =>
70
+ e.getStackTrace.foreach(ste => logger.debug(ste.toString))
71
+ logger.log(s " Class input stream could not be created: $e" )
72
+ logger.log(" Are you trying to run too many builds at once? Trying to recover..." )
73
+ Iterator .empty
55
74
}
56
75
finally is.close()
57
76
58
- def findInJar (path : os.Path ): Iterator [String ] = {
59
- val content = os.read.bytes(path)
60
- val jarInputStream = WrappedZipInputStream .create(new ByteArrayInputStream (content))
61
- jarInputStream.entries().flatMap(ent =>
62
- if ! ent.isDirectory && ent.getName.endsWith(" .class" ) then {
63
- val content = jarInputStream.readAllBytes()
64
- val inputStream = new ByteArrayInputStream (content)
65
- findInClass(inputStream)
77
+ private def findInJar (path : os.Path , logger : Logger ): Iterator [String ] =
78
+ try retry()(logger) {
79
+ val content = os.read.bytes(path)
80
+ val jarInputStream = WrappedZipInputStream .create(new ByteArrayInputStream (content))
81
+ jarInputStream.entries().flatMap(ent =>
82
+ if ! ent.isDirectory && ent.getName.endsWith(" .class" ) then {
83
+ val content = jarInputStream.readAllBytes()
84
+ val inputStream = new ByteArrayInputStream (content)
85
+ findInClass(inputStream, logger)
86
+ }
87
+ else Iterator .empty
88
+ )
66
89
}
67
- else Iterator .empty
68
- )
69
- }
90
+ catch {
91
+ case e : NoSuchFileException =>
92
+ logger.debugStackTrace(e)
93
+ logger.log(s " JAR file $path not found: $e, trying to recover... " )
94
+ logger.log(" Are you trying to run too many builds at once? Trying to recover..." )
95
+ Iterator .empty
96
+ }
70
97
71
98
def findInDependency (jar : os.Path ): Option [String ] =
72
99
jar match {
@@ -79,19 +106,19 @@ object MainClass {
79
106
case _ => None
80
107
}
81
108
82
- def find (output : os.Path ): Seq [String ] =
109
+ def find (output : os.Path , logger : Logger ): Seq [String ] =
83
110
output match {
84
111
case o if os.isFile(o) && o.last.endsWith(" .class" ) =>
85
- findInClass(o).toVector
112
+ findInClass(o, logger ).toVector
86
113
case o if os.isFile(o) && o.last.endsWith(" .jar" ) =>
87
- findInJar(o).toVector
114
+ findInJar(o, logger ).toVector
88
115
case o if os.isDir(o) =>
89
116
os.walk(o)
90
117
.iterator
91
118
.filter(os.isFile)
92
119
.flatMap {
93
120
case classFilePath if classFilePath.last.endsWith(" .class" ) =>
94
- findInClass(classFilePath)
121
+ findInClass(classFilePath, logger )
95
122
case _ => Iterator .empty
96
123
}
97
124
.toVector
0 commit comments