Skip to content

Commit bf8d903

Browse files
aherlihytgodzik
authored andcommitted
Add wrapper around :jar to avoid crashing repl on invalid jar
[Cherry-picked 42c4e89]
1 parent f14495b commit bf8d903

File tree

2 files changed

+28
-24
lines changed

2 files changed

+28
-24
lines changed

compiler/src/dotty/tools/repl/ReplDriver.scala

+27-23
Original file line numberDiff line numberDiff line change
@@ -530,8 +530,6 @@ class ReplDriver(settings: Array[String],
530530
if (f.isClassContainer) f.iterator.flatMap(flatten)
531531
else Iterator(f)
532532

533-
val entries = flatten(jarFile)
534-
535533
def tryClassLoad(classFile: AbstractFile): Option[String] = {
536534
val input = classFile.input
537535
try {
@@ -546,27 +544,33 @@ class ReplDriver(settings: Array[String],
546544
}
547545
}
548546

549-
val existingClass = entries.filter(_.ext.isClass).find(tryClassLoad(_).isDefined)
550-
if (existingClass.nonEmpty)
551-
out.println(s"The path '$path' cannot be loaded, it contains a classfile that already exists on the classpath: ${existingClass.get}")
552-
state
553-
else inContext(state.context):
554-
val jarClassPath = ClassPathFactory.newClassPath(jarFile)
555-
val prevOutputDir = ctx.settings.outputDir.value
556-
557-
// add to compiler class path
558-
ctx.platform.addToClassPath(jarClassPath)
559-
SymbolLoaders.mergeNewEntries(defn.RootClass, ClassPath.RootPackage, jarClassPath, ctx.platform.classPath)
560-
561-
// new class loader with previous output dir and specified jar
562-
val prevClassLoader = rendering.classLoader()
563-
val jarClassLoader = fromURLsParallelCapable(
564-
jarClassPath.asURLs, prevClassLoader)
565-
rendering.myClassLoader = new AbstractFileClassLoader(
566-
prevOutputDir, jarClassLoader)
567-
568-
out.println(s"Added '$path' to classpath.")
569-
state
547+
try {
548+
val entries = flatten(jarFile)
549+
550+
val existingClass = entries.filter(_.ext.isClass).find(tryClassLoad(_).isDefined)
551+
if (existingClass.nonEmpty)
552+
out.println(s"The path '$path' cannot be loaded, it contains a classfile that already exists on the classpath: ${existingClass.get}")
553+
else inContext(state.context):
554+
val jarClassPath = ClassPathFactory.newClassPath(jarFile)
555+
val prevOutputDir = ctx.settings.outputDir.value
556+
557+
// add to compiler class path
558+
ctx.platform.addToClassPath(jarClassPath)
559+
SymbolLoaders.mergeNewEntries(defn.RootClass, ClassPath.RootPackage, jarClassPath, ctx.platform.classPath)
560+
561+
// new class loader with previous output dir and specified jar
562+
val prevClassLoader = rendering.classLoader()
563+
val jarClassLoader = fromURLsParallelCapable(
564+
jarClassPath.asURLs, prevClassLoader)
565+
rendering.myClassLoader = new AbstractFileClassLoader(
566+
prevOutputDir, jarClassLoader)
567+
568+
out.println(s"Added '$path' to classpath.")
569+
} catch {
570+
case e: Throwable =>
571+
out.println(s"Failed to load '$path' to classpath: ${e.getMessage}")
572+
}
573+
state
570574

571575
case KindOf(expr) =>
572576
out.println(s"""The :kind command is not currently supported.""")

compiler/test-resources/repl/jar-errors

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ scala>:jar sbt-test/source-dependencies/canon/actual/a.jar
88
The path 'sbt-test/source-dependencies/canon/actual/a.jar' cannot be loaded, it contains a classfile that already exists on the classpath: sbt-test/source-dependencies/canon/actual/a.jar(A.class)
99

1010
scala>:require sbt-test/source-dependencies/canon/actual/a.jar
11-
:require has been deprecated and replaced with :jar. Please use :jar
11+
:require is no longer supported, but has been replaced with :jar. Please use :jar

0 commit comments

Comments
 (0)