Skip to content

Commit c95cc83

Browse files
committed
Add wrapper around :jar to avoid crashing repl on invalid jar
1 parent 4bb08f7 commit c95cc83

File tree

3 files changed

+28
-30
lines changed

3 files changed

+28
-30
lines changed

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

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

530-
val entries = flatten(jarFile)
531-
532530
def tryClassLoad(classFile: AbstractFile): Option[String] = {
533531
val input = classFile.input
534532
try {
@@ -543,27 +541,33 @@ class ReplDriver(settings: Array[String],
543541
}
544542
}
545543

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

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

compiler/test-resources/repl/i9227

-6
This file was deleted.

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)