@@ -12,6 +12,8 @@ import scala.annotation.internal.sharable
1212import dotty .tools .dotc .util .ClasspathFromClassloader
1313import dotty .tools .runner .ObjectRunner
1414import dotty .tools .dotc .config .Properties .envOrNone
15+ import java .util .jar ._
16+ import java .util .jar .Attributes .Name
1517
1618enum ExecuteMode :
1719 case Guess
@@ -129,7 +131,25 @@ object MainGenericRunner {
129131 case ExecuteMode .Run =>
130132 val scalaClasspath = ClasspathFromClassloader (Thread .currentThread().getContextClassLoader).split(classpathSeparator)
131133 val newClasspath = (settings.classPath ++ scalaClasspath :+ " ." ).map(File (_).toURI.toURL)
132- errorFn(" " , ObjectRunner .runAndCatch(newClasspath, settings.residualArgs.head, settings.residualArgs.drop(1 )))
134+ val res = ObjectRunner .runAndCatch(newClasspath, settings.residualArgs.head, settings.residualArgs.drop(1 )).flatMap {
135+ case ex : ClassNotFoundException if ex.getMessage == settings.residualArgs.head =>
136+ val file = settings.residualArgs.head
137+ def withJarInput [T ](f : JarInputStream => T ): T =
138+ val in = new JarInputStream (java.io.FileInputStream (file))
139+ try f(in)
140+ finally in.close()
141+ val manifest = withJarInput(s => Option (s.getManifest))
142+ manifest match
143+ case None => Some (IllegalArgumentException (s " Cannot find manifest in jar: $file" ))
144+ case Some (f) =>
145+ f.getMainAttributes.get(Name .MAIN_CLASS ) match
146+ case mainClass : String =>
147+ ObjectRunner .runAndCatch(newClasspath :+ File (file).toURI.toURL, mainClass, settings.residualArgs)
148+ case _ =>
149+ Some (IllegalArgumentException (s " No main class defined in manifest in jar: $file" ))
150+ case ex => Some (ex)
151+ }
152+ errorFn(" " , res)
133153 case ExecuteMode .Script =>
134154 val properArgs =
135155 List (" -classpath" , settings.classPath.mkString(classpathSeparator)).filter(Function .const(settings.classPath.nonEmpty))
0 commit comments