Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Null Pointer Exception when using Control+D to send EOF to user input #562

Closed
lalaithion opened this issue May 19, 2021 · 2 comments
Closed

Comments

@lalaithion
Copy link

steps

sbt 1.5.2

problem

Running a command like sbt new scala/scala3.g8 fails with this stack trace:

java.lang.NullPointerException
	at giter8.G8$.$anonfun$interact$3(g8.scala:471)
	at scala.collection.LinearSeqOptimized.foldLeft(LinearSeqOptimized.scala:126)
	at scala.collection.LinearSeqOptimized.foldLeft$(LinearSeqOptimized.scala:122)
	at scala.collection.immutable.List.foldLeft(List.scala:89)
	at giter8.G8$.interact(g8.scala:460)
	at giter8.G8$.$anonfun$applyT$2(g8.scala:341)
	at scala.Option.getOrElse(Option.scala:189)
	at giter8.G8$.$anonfun$applyT$1(g8.scala:341)
	at scala.util.Either$RightProjection.flatMap(Either.scala:701)
	at giter8.G8$.applyT(g8.scala:338)
	at giter8.G8$.fromDirectory(g8.scala:77)
	at giter8.G8TemplateRenderer$.render(TemplateRenderer.scala:40)
	at giter8.AppProcessor.process(giter8.scala:58)
	at giter8.Runner.$anonfun$run$9(Runner.scala:51)
	at scala.util.Either.flatMap(Either.scala:341)
	at giter8.Runner.$anonfun$run$5(Runner.scala:48)
	at scala.util.Either.flatMap(Either.scala:341)
	at giter8.Runner.$anonfun$run$4(Runner.scala:47)
	at scala.util.Either.flatMap(Either.scala:341)
	at giter8.Runner.run(Runner.scala:46)
	at giter8.Giter8.run(giter8.scala:33)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at giter8.LauncherProcessor.call(LauncherMain.scala:114)
	at giter8.LauncherProcessor.virtuallyRun(LauncherMain.scala:88)
	at giter8.LauncherProcessor.process(LauncherMain.scala:38)
	at giter8.Runner.$anonfun$run$9(Runner.scala:51)
	at scala.util.Either.flatMap(Either.scala:341)
	at giter8.Runner.$anonfun$run$5(Runner.scala:48)
	at scala.util.Either.flatMap(Either.scala:341)
	at giter8.Runner.$anonfun$run$4(Runner.scala:47)
	at scala.util.Either.flatMap(Either.scala:341)
	at giter8.Runner.run(Runner.scala:46)
	at giter8.Runner.run(Runner.scala:72)
	at sbtgiter8resolver.Giter8TemplateResolver.run(Giter8TemplateResolver.scala:34)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at sbt.TemplateCommandUtil$.call(TemplateCommandUtil.scala:113)
	at sbt.TemplateCommandUtil$.runTemplate(TemplateCommandUtil.scala:88)
	at sbt.TemplateCommandUtil$.$anonfun$run$1(TemplateCommandUtil.scala:64)
	at sbt.TemplateCommandUtil$.$anonfun$run$1$adapted(TemplateCommandUtil.scala:60)
	at scala.collection.LinearSeqOptimized.find(LinearSeqOptimized.scala:115)
	at scala.collection.LinearSeqOptimized.find$(LinearSeqOptimized.scala:112)
	at scala.collection.immutable.List.find(List.scala:91)
	at sbt.TemplateCommandUtil$.run(TemplateCommandUtil.scala:60)
	at sbt.TemplateCommandUtil$.runTemplate(TemplateCommandUtil.scala:47)
	at sbt.TemplateCommandUtil$.$anonfun$templateCommand$2(TemplateCommandUtil.scala:28)
	at sbt.Command$.$anonfun$applyEffect$4(Command.scala:150)
	at sbt.Command$.$anonfun$applyEffect$2(Command.scala:145)
	at sbt.Command$.process(Command.scala:189)
	at sbt.MainLoop$.$anonfun$processCommand$5(MainLoop.scala:245)
	at scala.Option.getOrElse(Option.scala:189)
	at sbt.MainLoop$.process$1(MainLoop.scala:245)
	at sbt.MainLoop$.processCommand(MainLoop.scala:276)
	at sbt.MainLoop$.$anonfun$next$5(MainLoop.scala:163)
	at sbt.State$StateOpsImpl$.runCmd$1(State.scala:289)
	at sbt.State$StateOpsImpl$.process$extension(State.scala:325)
	at sbt.MainLoop$.$anonfun$next$4(MainLoop.scala:163)
	at sbt.internal.util.ErrorHandling$.wideConvert(ErrorHandling.scala:23)
	at sbt.MainLoop$.next(MainLoop.scala:163)
	at sbt.MainLoop$.run(MainLoop.scala:144)
	at sbt.MainLoop$.$anonfun$runWithNewLog$1(MainLoop.scala:119)
	at sbt.io.Using.apply(Using.scala:27)
	at sbt.MainLoop$.runWithNewLog(MainLoop.scala:112)
	at sbt.MainLoop$.runAndClearLast(MainLoop.scala:66)
	at sbt.MainLoop$.runLoggedLoop(MainLoop.scala:51)
	at sbt.MainLoop$.runLogged(MainLoop.scala:42)
	at sbt.StandardMain$.runManaged(Main.scala:218)
	at sbt.xMain$.$anonfun$run$9(Main.scala:113)
	at sbt.io.IO$.withTemporaryDirectory(IO.scala:490)
	at sbt.io.IO$.withTemporaryDirectory(IO.scala:500)
	at sbt.xMain$.run(Main.scala:101)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at sbt.internal.XMainConfiguration.run(XMainConfiguration.java:56)
	at sbt.xMain.run(Main.scala:46)
	at xsbt.boot.Launch$.$anonfun$run$1(Launch.scala:149)
	at xsbt.boot.Launch$.withContextLoader(Launch.scala:176)
	at xsbt.boot.Launch$.run(Launch.scala:149)
	at xsbt.boot.Launch$.$anonfun$apply$1(Launch.scala:44)
	at xsbt.boot.Launch$.launch(Launch.scala:159)
	at xsbt.boot.Launch$.apply(Launch.scala:44)
	at xsbt.boot.Launch$.apply(Launch.scala:21)
	at xsbt.boot.Boot$.runImpl(Boot.scala:78)
	at xsbt.boot.Boot$.run(Boot.scala:73)
	at xsbt.boot.Boot$.main(Boot.scala:21)
	at xsbt.boot.Boot.main(Boot.scala)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at coursier.bootstrap.launcher.a.a(Unknown Source)
	at coursier.bootstrap.launcher.Launcher.main(Unknown Source)

When entering Control+D into a user input field.

expectation

The program should gracefully exit.

@eed3si9n
Copy link
Member

@lalaithion Thanks for the report.

I am guessing that the NPE is caused by following line

val in = scala.io.StdIn.readLine().trim

where readLine() probably returns null and is blowing up at .trim.

Rather than treating it as an empty value it is throwing an exception, so it is getting the job done in a way to exit the program. Just not gracefully :)
I guess the improvement would be to wrap it in Option(...) and throw a specific exception and catch it in applyT silently:

} catch {
case e: STException =>
Left(s"Exiting due to error in the template: ${tmpl}\n${e.getMessage}")
case t: Throwable =>
t.printStackTrace()
Left("Unknown exception: " + t.getMessage)
}

@TonioGela
Copy link
Member

TonioGela commented May 29, 2021

@xuwei-k or @eed3si9n can be closed, or at least it can be closed once a new version is released.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

3 participants