Scala¶
A collection of useful tips for Scala in combination with Metals and the official Neovim plugin. This can convert Neovim into a decent Scala editor that benefits from Metals’ rich feature set.
Create FAT jars¶
So called fat jars are self-contained jars that include all the Scala runtime stuff. They can run without
a Scala installation using only a java VM. java -jar foo.jar where foo jar is a fat JAR generated with
the sbt-assembly plugin.
https://www.baeldung.com/scala/sbt-fat-jar
Using Scala-CLI¶
Scala-CLI can be used to build and manage projects. It is not as powerful as sbt, but can be faster in
some cases. It works well with metals for small single-module projects. Scala-CLI is still under heavy
development and will see improvements in future releases. For large projects, particularly such with
multiple modules, sbt might still be the better option.
Power mode¶
Power-mode is the synonym for the experimental mode in Scala-CLI. Power-mode offers more features, but
some of them should be considered unstable and experimental. You can enable Power-mode with the --power
command line argument or globally by running:
# enable power-mode globally (for the current user)
$ scala-cli config power true
Create a FAT Jar (aka assembly)¶
A fat JAR works exactly like in sbt. It creates a JAR that contains all dependencies including the
Scala default library. It will run on any compatible JVM.
# build a fat JAR (aka assembly)
$ scala-cli package --force --assembly .
Note the --force parameter. It is generally needed by all Scala-CLI commands in order to overwrite
existing builds.
Create a standalone Jar¶
This is basically the same as a FAT Jar, but there are some minor differences in the internal format.
Like the FAT Jar, this is fully self-contained and will run on any compatible JVM using the -jar
command line argument.
# build a standalone JAR
$ scala-cli package --force --standalone .
Using Scala-CLI to build native apps¶
Scala-CLI fully supports building native executables with scala-native. While this is still considered
experimental software, it’s fairly complete and works fine for many smaller applications. Note that
native does not always mean faster execution. In fact, some code could run faster when executed by the
JVM, but native will almost always result in much faster startup times.
# build the application in the current directoy, using a scala-native optimized release build
$scala-cli package --force --native --native-mode release-full .
Using Scala-CLI to build native apps via Graal VM¶
This is a different way to produce standalone executables. It requires a compatible version of Graal which will be downloaded via coursier on-demand during the build process. This process cares about some issues related to Scala. It allows you to use Java libraries using reflection (a common problem when building native binaries) and also Scala’s LazyVal semantics. Scala-CLI will automatically generate the necessary manifest and configuration files for Graal’s native image generator.
scala-cli package --native-image --graalvm-version "21.0.2" --graalvm-java-version 21 .
Remember, use --force to overwrite an existing build. Use --graalvm-args to pass arguments to the
Graal VM native image generator.
Language topics¶
Catching multiple exceptions with the same variable¶
This is possible via pattern alternatives, a detail of the very powerful pattern matching features in Scala.
try {
...
} catch {
case e @ (_: IOException | _: RuntimeException) = { println(e.getMessage()) }
}
This will catch both exception types into e.
Time and Date stuff¶
// create a ZonedDateTime with a time zone information
val ts = ZonedDateTime.of(2000, 1, 6, 18, 14, 0, 0, ZoneId.of("UTC"))
// > 2000-01-06T18:14Z[UTC]
// translate into a different time zone
val translated = ts.withZoneSameInstant(ZoneId.of("Europe/Vienna"))
// 2000-01-06T19:14+01:00[Europe/Vienna]
val translated.toLocalDateTime()
// 2000-01-06T19:14:10