Call sbt externally - scala

I am designing a tool, that takes an sbt project path as a parameter. I would like to be able to build that given project on the fly, and be able to get its classpath.
I previously designed my tool as a sbt plugin to achieve this but it is not flexible enough for my purpose: I don't want to have to parameter anything in the sbt config files of the project I am studying.
I would like to use sbt externally, construct a project (from a sbt directory path) and compile it externally in my scala code without invoking sbt in a console. This is a reproduction in code of what happens when "sbt" is typed in a given directory in the console. Is there a straightforward way to achieve this?

I think you need to look at SBT jar file and source code. Find the "Main" class and call it programmatically. The code is here: https://github.com/sbt/sbt. The main class is: xsbt.boot.Boot. I got it from sbt jar file by unzipping it and looking at META-INF/MANIFEST.MF. So you can see how SBT passes command line arguments to it and take it from there. Here is the Boot class just in case: https://github.com/sbt/sbt/blob/0.13/launch/src/main/scala/xsbt/boot/Boot.scala. Have fun! :)
p.s. in your code just call Boot.main(<your sbt commands>).

I have a vaguely similar requirement. I produce a command-line tool as one of the deliverables from my project. The script launches the Scala runtime itself and naturally needs the effective class-path for the project's dependencies. To get that in an external form, I use the SBT-Start-Script plug-in. While that plug-in does produce an actual launcher, I need to do more than it provides, so I just use it to externalize the project's (current) class-path, which I extract into a shell array initialization in a separate source file that may be source-ed by the main launcher script.

Related

How to execute a task/command right after the project is loaded in sbt shell

I would like to execute a task/command every time I enter the sbt shell. Is there any init-task or init-command setting? Is there any other way?
Do you use *.sbt or *.scala to define you sbt project?
In case of scala files it's supposed to be simple. Basically during sbt startup all code in scala classes is compiled and executed. So basically what can you do is to define command(function) you want to execute directly inside class/object where your project is defined.
Option 2. Based on docs.
http://www.scala-sbt.org/0.12.2/docs/faq.html#how-can-i-take-action-when-the-project-is-loaded-or-unloaded
Pay attention on onLoad setting key.

Generate a JAR from one Scala source file

I have no Scala experience, but I need to create a JAR to include on a project's classpath from a single Scala source file.
I'm thinking there is a relatively straightforward way to do this, but I can't seem to figure it out.
The Scala file is here: http://pastebin.com/MYqjNkac
The JAR doesn't need to be executable, it just needs to be able to be referenced from another program.
The most convenient way is to use some build tool like Sbt or Maven. For maven there is the maven-scala-plugin plugin, and for Sbt here is a tutorial.
If you don't want to use any build tool, you may want to compile the code with scalac and then create the jar file manually by using zip on the resulting class files and renaming it to jar. But you have to preserve the directory structure. In your pastebin you use the package org.apache.spark.examples.pythonconverters, so make sure the directories match.
Btw, if you want to just integrate this piece of code with your java project, and using maven, you can have the scala code in your 1 project as well (in src/main/scala). Just use the maven-scala-plugin plugin and hook it to the compile phase, or some sooner phase if your Java code depends on it. However, I don't recommend mixing multiple languages in one project, I would split it into two separate ones.

How to build a scala application that was created in eclipse scala plugin FROM THE CL

I have developed a scala application for the first time, but I have to deploy it with a "one-click" type script that can run and build the scala application from source WITHOUT ECLIPSE.
Since I'm completely new to scala I don't know how to tell it where all my source files are etc... to get it to build my app from the command line. I also have 2 3rd party .jar libraries that I need to tell the scala compiler to link to...
Any documentation on this? Or example command lines? My project hierarchy is:
src/packagename: contains all .scala
bin/packagename: contains all.class files
libs/ -> contains 2 .jar files I will need to import somehow
I'm working on debian linux
EDIT: I found this ability to export in eclipse so I created a .java file and called my main scala object from it. Then I exported as a runnable jar. However, when I go to run the new runnable jar "sudo java runnable.jar" it says "class not found exception: runnable.jar"
You should take a look at https://github.com/harrah/xsbt/wiki which is the common way to build a Scala project. Run through the tutorial in the wiki to learn how you should organise your directory structure, so that everything may run fine.
If you want to combine it with eclipse, checkout this plugin: https://github.com/typesafehub/sbteclipse

Eclipse: script compiler as part of a project

This question is not limited to lex and yacc, but how can I add a custom script compiler as part of a project? For example, I have the following files in the project:
grammar.y
grammar.l
test.script
The binary 'script_compiler' will be generated using grammar.y and grammar.l compiled by lex, yacc and g++. And then I want to use that generated script_compiler to compile test.script to generate CompiledScript.java. This file should be compiled along with the rest of the java files in the project. This setting is possible with XCode or make, but is it also possible with Eclipse alone? If not, how about together with Maven plugin?
(I might setup the script compiler as a separate project, but it would be nice if they can be put in the same project so that changes to the grammar files can be applied immediately)
Thanks in advance for your help!
You can add a custom "Builder" from the project properties dialog. This can be an ant script (with an optional target) or any other script or executable.
There are also maven plugins for ant and other scripting languages
If you just want to run an external program in Maven this is what you want: http://mojo.codehaus.org/exec-maven-plugin/ -- you can then run Maven targets from your IDE or command line and it should do the right thing either way.
To integrate with the normal compilation bind the plugin to the "generate-sources" phase and add the location where the Java files are generated to the "sourceRoot" option of the exec plugin. That way the compiler will pick them up.
Ideally you generate the code into a folder "target/generated-sources/MY_SCRIPT_NAME". That is the standard location for generated sources in the Maven world and e.g. IntelliJ IDEA will pick up source files inside of that location. Note that this doesn't work if the files are directly in "target/generated-sources".
The other option is to write your own Maven plugin, which is actually quite easy as well. See e.g. https://github.com/peterbecker/maven-code-generator

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.