How to compile standalone scala - scala

Just starting to learn scala.. I can't seem to figure out how to compile something into a standalone application. I think I almost have a working .jar file, but keep getting a Main-Class error even though it's in the manifest,

Scala programs require at a minimum the scala-library.jar file that accompanied the Scala Development Kit whose compiler you used to compile the sources. This is in addition to any 3rd-party Java (or Scala) libraries you might use. So from the perspective of building a stand-alone application (i.e., one that can be launched with a java -jar ... command) you must treat the scala-library.jar like a 3rd-party library.

Related

What is the reason for nesting class files under 'scala' directory?

SBT puts compiled scala files in folder target/scala-<scalaVersion>.
As far as I understand class files contain JVM bytecode. They are language agnostic.
What is then the reason for the folder with the name of the language? I'd expect that class filed of both Scala and Java go to the same directory.
The compiled bytecode is language-agnostic, but of course, the code inside that bytecode may call out to libraries, including the Scala standard library. The compiler may also have generated calls into the Scala runtime.
The Scala runtime may change between versions, for example, the way lambdas are represented has changed completely in 2.12. A program compiled for Scala 2.12 will not work with a Scala 2.11 runtime.
So, while JVM bytecode is language agnostic, you still need the matching runtime.
Note that this is no different from any other language. If you compile C to native code, you still can't run your code, unless you have the proper C runtime in place.
SBT supports building the same project with multiple Scala versions (and then producing separate artifacts for them, etc.). These files will naturally be in the same path relative to their target directory (since this path is determined by the full class name). So different Scala versions need different target directories to avoid conflict.

when should use scala-compiler and when should use scala-library

I am using scala in android. And I want to include some basic library to the project, and I found there are 2 jar one is scala-compiler and another is scala-library. What's the difference between them, and how should we choose one?
Scala-compiler - is a compiler itself, which (simply saying) takes .scala files and compiles them into the .class files. You don't need it to run already compiled .jar/.class file if you don't interpret scala-code in runtime (which usually you don't). Scala-compiler.jar is used by your built-tool/ide to compile your scala code. Sometimes third-party libraries may also want it as transitive dependency.
Scala-library - is a library that contains scala API (built-in functions, collections, concurrency etc.). Usually (99,9%) you need this.

When I compile a file in IntelliJ on a maven project, what does it run?

I'm trying to make the move to VIM for my Java/Scala work. However it seems I cannot compile a single file using Maven. When developing I typically like to compile a file just to make sure it compiles before I compile the whole project.
In intellij I can choose to compile a single file that I'm on, what does that run behind the scenes so that my classpath is loaded with all my dependencies from maven?
The question boils down to what can I run from the command line to compile a file using Maven the fastest?
The fastest way to compile from IDEA is Build | Make. It will compile the changed files and all the dependencies. Compiling single file is also possible, IDEA will use Java Compiler API (like javac does) for such compilation.
IDEA doesn't compile using Maven in such cases.
I don't think single file is compiled using maven. I think IDEA just "knows" what what libraries are necessary (by parsing your pom.xml) and adds it to the classpath when running scalac.

Scala: Creating a small executable Jar relying on external Scala libraries

I'm trying to package a small application (still learning Scala!) in a "clean way". The goal is to have an executable JAR file. I've done the following:
packaged a JAR using sbt -> will work with
scala -cp myjarfile.jar MyClass
or
java -classpath path\to\scala-library.jar;myjarfile.jar MyClass
but won't work with
java -jar myjarfile.jar
because then scala/ScalaObject cannot be found. And no use adding a classpath on this last one, since the -jar option will ignore the -classpath option. Note that I have added the scala libs in my system CLASSPATH variable, but it seems to be ignored too when -jar is used.
added the scala library contents (by unzipping them first) to the jar created by sbt. This then works (the jar can be double-clicked and launched), but the manipulation is somewhat lengthy, and the resulting file is several megabytes big. Not ideal.
After hours of googling, I can see no way to create a small jar file that will launch when double-clicked and that doesn't involve a painful manipulation. What am I missing? I'm guessing there should be some way to define where the scala libraries are at system level. How do you deal with small applications that you want to be compiled and ready-to-run for efficiency?
Note that while I'm using sbt, I don't have a jar tool at hand (I'm relying on a JRE, not a JDK).
Thanks!
Pierric.
The following setup works for me:
have scala-library.jar in the same folder as the executable jar (and call java from there)
put this into your manifest:
Class-Path: scala-library.jar
Another option is to merge the contents of scala-library.jar into your application jar. The drawback is that this will increase its size. But you can use Proguard to strip unused classes from your final jar. I think there is an easy way of using sbt to package an executable jar using proguard.
Regarding the shrinking using Proguard, you can have a look at this page. It's about Android development; just ignore this part and have a look at the tables of the shrinking results. Some example applications shrink to less than 100kB.
Edit
Maybe you need to refine your question a bit. What are you trying to achieve? Do you want to install the program only on your system or do you want to distribute it?
If all you want is quickly launching a Java application without much impact of the JVM start-up time you can have a look at nailgun.

Packaging and Deploying Scala Applications

What is the simplest way to package a Scala application for use on a desktop PC? I'm guessing that would be in the form of a jar file.
At the moment I'm using SBT to compile and run programs
I'd be interested in solutions for machines that have Scala installed (and the library in their classpath), as well as those that only have Java.
The simplest (and the most consistent) way to package a Scala application, is packaging into a JAR (like you do with normal Java applications). As long as JAR consists of standard compiled Java classes, you may run "Scala" JAR, even if you don't have Scala runtime at the box (all you need is a Java Runtime and scala-lang.jar on the classpath). You may specify the main class (gateway to functionalities of your application) in the manifast
Main-Class: mypackage.MyClass
so that you'll be able to call it only passing a JAR name to java.exe.
java -jar myjar.jar
You may specify the main class in SBT project definition.
http://www.scala-sbt.org/sbt-native-packager/index.html
The plugin allows you to package in a variety of formats(zip, tar, deb, dmg, msi, etc) and in different archtypes.