{"id":716,"date":"2011-11-02T11:36:00","date_gmt":"2011-11-02T11:36:00","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/2012\/10\/scala-tutorial-sbt-scalabha-packages-build-systems.html"},"modified":"2012-10-21T20:44:41","modified_gmt":"2012-10-21T20:44:41","slug":"scala-tutorial-sbt-scalabha-packages","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html","title":{"rendered":"Scala Tutorial &#8211; SBT, scalabha, packages, build systems"},"content":{"rendered":"<div dir=\"ltr\" style=\"text-align: left\">\n<h2> Preface<\/h2>\n<p>This is part 11 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other resources on <a href=\"http:\/\/icl-f11.utcompling.com\/links\">the links page of the Computational Linguistics course<\/a> I\u2019m creating these for. Additionally you can find this and other tutorial series on the JCG Java <a href=\"http:\/\/www.javacodegeeks.com\/p\/java-tutorials.html\">Tutorials page<\/a>.<\/p>\n<p>This tutorial gives an introduction to building Scala applications using <a href=\"https:\/\/github.com\/harrah\/xsbt\/wiki\">SBT<\/a> (the Simple Build Tool). This will be done in the context of the <a href=\"https:\/\/bitbucket.org\/jasonbaldridge\/scalabha\/overview\">Scalabha<\/a> package, which I have created for primarily for <a href=\"http:\/\/icl-f11.utcompling.com\/\">my Introduction to Computational Linguistics class<\/a>. Some supporting code is available in Scalabha for some basic natural language processing tasks; most relevant at the moment is the code that is in Scalabha that supports <a href=\"http:\/\/icl-f11.utcompling.com\/assignments\/hw4-part-of-speech-tagging\">the part-of-speech tagging homework<\/a> for the class.<\/p>\n<p><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scripting-compiling-main.html\" title=\"First steps in Scala for beginning programmers, Part 10\">The previous tutorial <\/a>showed how Scala code can be compiled with <em>scalac<\/em> and then run with <em>scala<\/em>. One problem we ended up with is that there were generated class files littering the working directory. Another thing we did not discuss is how a large system can be created in a modular way that organizes code and classes. For example, you might want to have code in different directories generate classes that can be used by one another. You also may want want to incorporate classes from other libraries into your own code. The solutions we\u2019ll discuss to address these needs and more are build systems and packages.<\/p>\n<p><em>Note<\/em>: The tutorial assumes you are using some version of Unix. If you are on Windows, you should consider using Cygwin, or you could <a href=\"https:\/\/help.ubuntu.com\/community\/WindowsDualBoot\">dual boot your computer<\/a>.<\/p>\n<p><em>Note<\/em>: In this tutorial, I\u2019ll assume you are using as simple text editor to modify files. However, note that the general setup you are working with here can be used from more powerful Integrated Developer Environements (IDEs) like Eclipse, IntelliJ, and NetBeans.<\/p>\n<h2> Setting up Scalabha<\/h2>\n<p>We\u2019ll work with SBT, which is perhaps the most popular build tool for Scala.  The Scalabha toolkit mentioned earlier uses SBT (version 0.11.0), so we\u2019ll discuss SBT in the Scalabha context.<br \/>\nThe first thing you need to do is download <a href=\"https:\/\/bitbucket.org\/jasonbaldridge\/scalabha\/downloads\/scalabha-0.1.1-src.zip\">Scalabha v0.1.1<\/a> Next unzip the file, change to the directory it unpacked to, and list the directory contents.<\/p>\n<pre class=\"brush: bash;\">$ unzip scalabha-0.1.1-src.zip\r\nArchive:  scalabha-0.1.1-src.zip\r\n&lt;lots of output&gt;\r\n$ cd scalabha-0.1.1\r\n$ ls\r\nCHANGES.txt README      build.sbt   project\r\nLICENSE     bin         data        src\r\n<\/pre>\n<p>Briefly, these contents are:<\/p>\n<ul>\n<li><strong>README<\/strong>: A text file describing how to install Scalabha on your machine.<\/li>\n<li><strong>LICENSE<\/strong>: A text file giving the license, which is the Apache Software License 2.0.<\/li>\n<li><strong>CHANGES.tx<\/strong>t: A text file describing the modifications made for each version (not much so far).<\/li>\n<li><strong>build.sbt<\/strong>: A text file that contains instructions for SBT regarding how to build Scalabha<\/li>\n<li><strong>bin<\/strong>: A directory that contains the scalabha script, which will be used to run applications developed within the Scalabha build system and also to run SBT itself. It also contains sbt-launch-0.11.0.jar, which is a bottled up package of SBT\u2019s classes that will allow us to use SBT very easily. There are some other files that are Perl scripts that are relevant for a research project and aren\u2019t important here.<\/li>\n<li><strong>data<\/strong>: A directory containing part-of-speech tagged data for English and Czech that forms the basis for the fourth homework of my Introduction to Computational Linguistics course this semester.<\/li>\n<li><strong>project<\/strong>: A directory containing a single file \u201cplugins.sbt\u201d which tells SBT to use the Assembly plugin. More on this later.<\/li>\n<li><strong>src<\/strong>: The most important directory of all \u2014 it contains the source code of the Scalabha system, and is where you\u2019ll be adding some code as you work with SBT.<\/li>\n<\/ul>\n<p>At this point you should read the <strong>README<\/strong> and get Scalabha set up on your computer, including building the system from source. In this tutorial, I will give some extra details on using SBT and code development with it, complementing and extending the brief information given in the README.<\/p>\n<p>Note that I will refer the environment variable <strong>SCALABHA_DIR<\/strong> below. As specified in the README, you should set this variable\u2019s value to be where you unpacked Scalabha. For example, for me this directory is <strong>~\/devel\/scalabha<\/strong>.<br \/>\n<em>Tip<\/em>: to make it so that you don\u2019t have to set your environment variables every time you open a new shell, you can set environment variables in your <strong>~\/.profile<\/strong> (Mac, Cygwin) or <strong>~\/.bash_aliases<\/strong> (Ubuntu) files. For example, this is in my profile files on my machines.<\/p>\n<pre class=\"brush: bash;\">export SCALABHA_DIR=$HOME\/devel\/scalabha\r\nexport PATH=$PATH:$SCALABHA_DIR\/bin\r\n<\/pre>\n<h2> SBT: The Simple Build Tool<\/h2>\n<p>This is not a tutorial about setting up a project to use SBT \u2014 it is simply about how to use a project that is already set up for SBT. So, if you are looking for resources about learning SBT, what you\u2019ll mainly find are resources to help programmers configure SBT for their project. These will likely confuse you (the Simple Build Tool is not so simple any more, when it comes to configuration). Using it is straightforward, but the kind of know-how that experienced coders have with using something like SBT is what you probably won\u2019t find much help on. Here, I intend to give the basics so that you have a better starting point for doing more with SBT.<\/p>\n<p>First off, there is a bit of slight of hand with Scalabha that could be confusing. Rather than having users install SBT themselves, I have put the jar file for SBT in the <em>bin<\/em> directory of Scalabha; then, the <em>scalabha<\/em> executable (in that same directory) can pick that up and use it to run SBT. (My students and I have set up a number of Scala\/Java projects in this way, including <a href=\"https:\/\/bitbucket.org\/jasonbaldridge\/fogbow\">Fogbow<\/a>, <a href=\"http:\/\/code.google.com\/p\/junto\/\">Junto<\/a>, <a href=\"https:\/\/bitbucket.org\/utcompling\/textgrounder\">Textgrounder<\/a>, and <a href=\"https:\/\/bitbucket.org\/speriosu\/updown\/wiki\/Home\">Updown<\/a>.) The <em>scalabha<\/em> executable has a number of execution targets (more on this later), and one of these is \u201c<em>build<\/em>\u201c.<\/p>\n<p>When you call scalabha\u2019s <em>build<\/em> target, it invokes SBT and drops you into the SBT interface.<br \/>\nDo the following, in your <em>SCALABHA_DIR<\/em>.<\/p>\n<pre class=\"brush: bash;\">$ scalabha build\r\n[info] Loading project definition from \/Users\/jbaldrid\/devel\/scalabha\/project\r\n[info] Set current project to Scalabha (in build file:\/Users\/jbaldrid\/devel\/scalabha\/)\r\n&gt;\r\n<\/pre>\n<p>You could have achieved the same by downloading SBT and running it according to the instructions for SBT, but this setup saves you that trouble and ensures that you get the right version of SBT. It is just worth pointing out so that you don\u2019t think that Scalabha is SBT \u2013  SBT is entirely independent of Scalabha.<\/p>\n<p>If you have had any trouble with the Scalabha setup, you can create <a href=\"https:\/\/bitbucket.org\/jasonbaldridge\/scalabha\/issues\">an issue on the Scalabha Bitbucket site<\/a>. That just means that I\u2019ll get a notice that you had some problems and can hopefully help you out. And, it is possible that someone else will have had the same problem, in which case you might find your answer there. Most of the problems with this sort of setup are due to confusions about environment variables and unfamiliarity with command line tools.<\/p>\n<h2> Compiling with SBT<\/h2>\n<p>Let\u2019s actually do something with SBT now. If you successfully got through the README, you will have already done what is next, but I\u2019ll give some more details about what is going on.<br \/>\nBecause you may have run some SBT actions already as part of doing the README, start out by running the \u201c<em>clean<\/em>\u201d action so that we\u2019re on the same page.<\/p>\n<pre class=\"brush: bash;\">&gt; clean\r\n[success] Total time: 0 s, completed Oct 26, 2011 10:18:08 AM\r\n<\/pre>\n<p>Then, run the \u201c<em>compile<\/em>\u201d action.<\/p>\n<pre class=\"brush: bash;\">&gt; compile\r\n[info] Updating {file:\/Users\/jbaldrid\/devel\/scalabha\/}default-86efd0...\r\n[info] Done updating.\r\n[info] Compiling 13 Scala sources to \/Users\/jbaldrid\/devel\/scalabha\/target\/classes...\r\n[success] Total time: 9 s, completed Oct 26, 2011 10:18:19 AM\r\n<\/pre>\n<p>In another shell (which means another command line window), go to <em>SCALABHA_DIR<\/em> and list the contents of the directory. You\u2019ll see that two new directories have been created, <em>lib_managed<\/em> and <em>target<\/em>. The first is where other libraries have been download from the internet and placed into the Scalabha project space so that they can be easily used \u2014 don\u2019t worry about this for the time being. The second is where the compiled class files have gone. To see some example class files, do the following.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<pre class=\"brush: bash;\">$ ls target\/classes\/opennlp\/scalabha\/postag\/\r\nBaselineTagger$$anonfun$tag$1.class\r\nBaselineTagger.class\r\nEnglishTagInfo$$anonfun$zipWithTag$1$1.class\r\n&lt;... many more class files ...&gt;\r\nRuleBasedTagger$$anonfun$tag$2.class\r\nRuleBasedTagger$$anonfun$tagWord$1.class\r\nRuleBasedTagger.class\r\n<\/pre>\n<p>These were generated from the following source files.<\/p>\n<pre class=\"brush: bash;\">$ ls src\/main\/scala\/opennlp\/scalabha\/postag\/\r\nHmmTagger.scala PosTagger.scala\r\n<\/pre>\n<p>Open up <strong>PosTagger.scala<\/strong> in a text editor and look at it \u2014 you\u2019ll see the class and object definitions that were the sources for the generated class files in the <em>target\/classes<\/em> directory. Basically, SBT has conveniently handled the separation of source and compile class files so that we don\u2019t have the class files littering our work space.<\/p>\n<p>How does SBT know where the class files are? Simple: it is configured to look at <em>src\/main\/scala<\/em> and compile every <em>.scala<\/em> file it finds under that directory. In just a bit, you\u2019ll start adding your own scala files and be able to compile and run them as part of the Scalabha build system.<\/p>\n<p>Next, at the SBT prompt, invoke the \u201c<em>package<\/em>\u201d action.<\/p>\n<pre class=\"brush: bash;\">&gt; package\r\n[info] Updating {file:\/Users\/jbaldrid\/devel\/scalabha\/}default-86efd0...\r\n[info] Done updating.\r\n[info] Packaging \/Users\/jbaldrid\/devel\/scalabha\/target\/scalabha-0.1.1.jar ...\r\n[info] Done packaging.\r\n[success] Total time: 0 s, completed Oct 26, 2011 10:19:02 AM\r\n<\/pre>\n<p>In the shell prompt that we used to list files previously, list the contents of the target directory.<\/p>\n<pre class=\"brush: bash;\">$ ls target\/\r\ncache              classes            scalabha-0.1.1.jar streams\r\n<\/pre>\n<p>You have just created <em>scalabha-0.1.1.jar,<\/em> a bottled up version of the Scalabha code that others could use in their own libraries. The extension \u201cjar\u201d stands for <strong>J<\/strong>ava <strong>Ar<\/strong>chive, and it is basically just a zipped up collection of a bunch of class files.<\/p>\n<p>Scalabha itself uses another of supporting libraries produced by others. To see the jars that are used as supporting libraries by Scalabha, do the following.<\/p>\n<pre class=\"brush: bash;\">$ ls lib_managed\/jars\/*\/*\/*.jar\r\nlib_managed\/jars\/jline\/jline\/jline-0.9.94.jar\r\nlib_managed\/jars\/junit\/junit\/junit-3.8.1.jar\r\nlib_managed\/jars\/org.apache.commons\/commons-lang3\/commons-lang3-3.0.1.jar\r\nlib_managed\/jars\/org.clapper\/argot_2.9.1\/argot_2.9.1-0.3.5.jar\r\nlib_managed\/jars\/org.clapper\/grizzled-scala_2.9.1\/grizzled-scala_2.9.1-1.0.8.jar\r\nlib_managed\/jars\/org.scalatest\/scalatest_2.9.0\/scalatest_2.9.0-1.6.1.jar\r\n<\/pre>\n<p>Of course, you may still be wondering what it means to \u201cuse a library\u201d in your code. More on this after we talk about packages and actually start doing some code ourselves.<\/p>\n<h2> Packages<\/h2>\n<p>Projects with a lot of code are generally organized into a package that has a set of sub-packages for parts of the code base that work closely together. At the very high level, a package is simply a way to ensure that we have unique fully qualified names for classes. For example, there is a class called <strong>Range<\/strong> in the Apache Commons Lang library and in the core Scala library. If you want to use both of these classes in the same piece of code, there is an obvious problem of a name conflict. Fortunately, they are contained within packages that allow us to refer to them uniquely.<\/p>\n<ul>\n<li><strong>Range<\/strong> in the Apache Commons Lang library is <strong>org.apache.commons.lang3.Range<\/strong><\/li>\n<li><strong>Range<\/strong> in Scala is <strong>scala.collection.immutable.Range<\/strong><\/li>\n<\/ul>\n<p>So, when we do need to use them together, we are still able to do so without conflict. You\u2019ve actually already seen some package names before, for example with <strong>java.lang.String<\/strong> and the distinction between <strong>scala.collection.mutable.Map<\/strong> and <strong>scala.collection.immutable.Map<\/strong>.<\/p>\n<p>To see the packages and classes in Scalabha, run the \u201c<em>doc<\/em>\u201d action in SBT.<\/p>\n<pre class=\"brush: bash;\">&gt; doc\r\n[info] Generating API documentation for main sources...\r\nmodel contains 35 documentable templates\r\n[info] API documentation generation successful.\r\n[success] Total time: 7 s, completed Oct 26, 2011 10:22:23 AM\r\n<\/pre>\n<p>Now, point your browser to the file <em>target\/api\/index.html<\/em>. Note: this means doing \u201copen file\u201d and then going to your <em>SCALABHA_DIR<\/em> and then to <strong>target<\/strong>, then to <em>api<\/em>, and then selecting<em> index.html<\/em>. You can then browse the packages and classes in Scalabha. For example, look at <strong>HmmTagger<\/strong>, which is in the package <strong>opennlp.scalabha.postag<\/strong>, and you\u2019ll see some of the fields and functions that are made available by that class.<\/p>\n<p>But, you may still be wondering: how do I use these packages and classes in my code anyway? We do so via <em>import<\/em> statements. We\u2019ll explore this by creating our own source code and compiling it.<\/p>\n<h2> Creating and compiling new code in SBT<\/h2>\n<p>First, we\u2019ll begin by just doing a simple hello world application that is done in the context of Scalabha and uses a package name. Get set up for this by doing the following set of commands.<\/p>\n<p>Now, point your browser to the file <strong>target\/api\/index.html<\/strong>. Note: this means doing \u201copen file\u201d and then going to your SCALABHA_DIR and then to target, then to api, and then selecting index.html. You can then browse the packages and classes in Scalabha. For example, look at HmmTagger, which is in the package opennlp.scalabha.postag, and you\u2019ll see some of the fields and functions that are made available by that class.<\/p>\n<p>But, you may still be wondering: how do I use these packages and classes in my code anyway? We do so via import statements. We\u2019ll explore this by creating our own source code and compiling it.<\/p>\n<h2> Creating and compiling new code in SBT<\/h2>\n<p>First, we\u2019ll begin by just doing a simple hello world application that is done in the context of Scalabha and uses a package name. Get set up for this by doing the following set of commands.<\/p>\n<pre class=\"brush: bash;\">$ cd $SCALABHA_DIR\r\n$ cd src\/main\/scala\/opennlp\/\r\n$ mkdir bcomposes\r\n<\/pre>\n<p>Next, using a text editor, create the file <strong>Hello.scala<\/strong> in the <em>src\/main\/scala\/opennlp\/bcomposes<\/em> directory with the following contents.<\/p>\n<pre class=\"brush: scala;\">package opennlp.bcomposes\r\n\r\nobject Hello {\r\n  def main (args: Array[String]) = println(\"Hello, world!\")\r\n}\r\n<\/pre>\n<p>This is just like the hello world object from the previous tutorial, but now it has the additional package specification that indicates that its fully qualified name is <strong>opennlp.bcomposes.Hello<\/strong>.<\/p>\n<p>Because the source code for <em>Hello.scala<\/em> is in a sub-directory of the <em>src\/main\/scala<\/em> directory, we can now compile this file using SBT. Make sure to save <em>Hello.scala<\/em>, and then go back to your SBT prompt and type \u201c<em>compile<\/em>\u201c.<\/p>\n<pre class=\"brush: bash;\">&gt; compile\r\n[info] Compiling 1 Scala source to \/Users\/jbaldrid\/devel\/scalabha\/target\/classes...\r\n[success] Total time: 1 s, completed Oct 26, 2011 10:35:15 AM\r\n<\/pre>\n<p>Notice that it compiled just one Scala source: SBT has already compiled the other source files in Scalabha, so it only had to compile the new one that you just saved.<\/p>\n<p>Having successfully created <strong>and<\/strong> compiled the <strong>opennlp.bcomposes.Hello<\/strong> object, we can now run it. The scalabha executable provides a \u201c<em>run<\/em>\u201d target that allows you to run any of the code you\u2019ve produced in the Scalabha build setup. In your shell, type the following.<\/p>\n<pre class=\"brush: bash;\">$ scalabha run opennlp.bcomposes.Hello\r\nHello, world!\r\n<\/pre>\n<p>There is actually a bunch of stuff going on under the hood that ensures that your new class is included in the <em>CLASSPATH<\/em> and can be used in this manner (see <em>bin\/scalabha<\/em> for details). This will simplify things for you considerable. To make a long story short, getting the <em>CLASSPATH<\/em> appropriately set is one of the main points of confusion for new developers; this way you can keep on moving without having to worry about what is essentially a plumbing problem.<\/p>\n<p>Now, let\u2019s say you want to change the definition of the <strong>Hello<\/strong> object to also print out an additional message that is supplied on the command line. Modify the <strong>main<\/strong> method to look like this.<\/p>\n<pre class=\"brush: scala;\">def main (args: Array[String]) {\r\n  println(\"Hello, world!\")\r\n  println(args(0))\r\n}\r\n<\/pre>\n<p>Now save it, and try running it.<\/p>\n<pre class=\"brush: bash;\">$ scalabha run opennlp.bcomposes.Hello Goodbye\r\nHello, world!\r\n<\/pre>\n<p>Oops \u2014 it didn\u2019t work?! I\u2019ve just forced you directly into a common point of confusion for students who are switching from scripting to compiling: you must compile before it can be used. So, invoke <em>compile<\/em> in SBT, and then try that command again.<\/p>\n<pre class=\"brush: bash;\">$ scalabha run opennlp.bcomposes.Hello Goodbye\r\nHello, world!\r\nGoodbye\r\n<\/pre>\n<p>To see what happens when you produce a syntax error in your Scala code, go back to <em>Hello.scala<\/em> and change first print statement in the <strong>main<\/strong> method so that it is missing the last quote:<\/p>\n<pre class=\"brush: scala;\">println(\"Hello, world!)\r\n<\/pre>\n<p>Now go back to SBT and compile again to see the love letter you get from the Scala compiler.<\/p>\n<pre class=\"brush: bash;\">[info] Compiling 1 Scala source to \/Users\/jbaldrid\/devel\/scalabha\/target\/classes...\r\n[error] \/Users\/jbaldrid\/devel\/scalabha\/src\/main\/scala\/opennlp\/bcomposes\/Hello.scala:5: unclosed string literal\r\n[error]     println(\"Hello, world!)\r\n[error]             ^\r\n[error] \/Users\/jbaldrid\/devel\/scalabha\/src\/main\/scala\/opennlp\/bcomposes\/Hello.scala:7: ')' expected but '}' found.\r\n[error]   }\r\n[error]   ^\r\n[error] two errors found\r\n[error] {file:\/Users\/jbaldrid\/devel\/scalabha\/}default-86efd0\/compile:compile: Compilation failed\r\n[error] Total time: 0 s, completed Oct 26, 2011 11:02:07 AM\r\n<\/pre>\n<p>The compile attempt failed, and you must go back and fix it. But don\u2019t do that yet. There\u2019s a handy aspect of SBT in this <em>write-save-compile<\/em> loop that saves you time and effort: SBT allows <em>triggered<\/em> executation of actions, which means that SBT can automatically perform an action if there is a change to the stuff it cares about. The <em>compile<\/em> action cares about the source code, so it can monitor changes in the file system and automatically recompile any time a file is saved. To do this, you simply add <strong>~<\/strong> in front of the action.<\/p>\n<p>Before fixing the error, type <strong>~compile<\/strong> into SBT. You\u2019ll see the same error message as before, but don\u2019t worry about that. The last line of output from SBT will say:<\/p>\n<pre class=\"brush: bash;\">1. Waiting for source changes... (press enter to interrupt)\r\n<\/pre>\n<p>Now go to <em>Hello.scala<\/em> again, add the quote back in, and save the file. This triggers the compile action in SBT, so you\u2019ll see it automatically compile, with a success message.<\/p>\n<pre class=\"brush: bash;\">[info] Compiling 1 Scala source to \/Users\/jbaldrid\/devel\/scalabha\/target\/classes...\r\n[success] Total time: 0 s, completed Oct 26, 2011 11:02:49 AM\r\n2. Waiting for source changes... (press enter to interrupt)\r\n<\/pre>\n<p>This is a nice way to see if your code is compiling as you work on it, with very little effort. Every time you save the file, it will let you know if there are problems. And, you\u2019ll also be able to use the <em>scalabha<\/em> <em>run<\/em> target and know that you are using the latest compiled version when you do so.<\/p>\n<p>As you develop your code in this way, you can invoke the \u201c<em>doc<\/em>\u201d action in SBT, then reload the <em>index.html<\/em> page in your browser, and it will show you the updated documentation for the things you\u2019ve created. Try it now and look at the <strong>opennlp.bcomposes<\/strong> package that you\u2019ve now created.<\/p>\n<h2> Creating code that uses existing packages<\/h2>\n<p>Now we can come back to using code from existing packages. In the past (if you\u2019ve gone through all of these tutorials), you\u2019ve seen statements like <strong>import scala.io.Source<\/strong>. That came from the standard Scala library, so it is always available to any Scala program. However, you can also use classes developed by others in a similar manner, provided your <em>CLASSPATH<\/em> is set up such that they are available. That is exactly what SBT does for you: all of the classes that are defined in the <em>src\/main\/scala<\/em> sub-directories are ready for your use.<\/p>\n<p>As an example, save the following code as <em>src\/main\/scala\/opennlp\/bcomposes\/TreeTest.scala<\/em>. It constructs a standard phrase structure tree for the sentence \u201cI like coffee.\u201d<\/p>\n<pre class=\"brush: scala;\">package opennlp.bcomposes\r\n\r\nimport opennlp.scalabha.model.{Node,Value}\r\n\r\nobject TreeTest {\r\n\r\n  def main (args: Array[String]) {\r\n    val leaf1 = Value(\"I\")\r\n    val leaf2 = Value(\"like\")\r\n    val leaf3 = Value(\"coffee\")\r\n    val subjNpNode = Node(\"NP\", List(leaf1))\r\n    val verbNode = Node(\"V\", List(leaf2))\r\n    val objNpNode = Node(\"NP\", List(leaf3))\r\n    val vpNode = Node(\"VP\", List(verbNode, objNpNode))\r\n    val sentenceNode = Node(\"S\", List(subjNpNode, vpNode))\r\n\r\n    println(\"Printing the full tree:\\n\" + sentenceNode)\r\n    println(\"\\nPrinting the children of the VP node:\\n\" + vpNode.children)\r\n\r\n    println(\"\\nPrinting the yield of the full tree:\\n\" + sentenceNode.getTokens.mkString(\" \"))\r\n    println(\"\\nPrinting the yield of the VP node:\\n\" + vpNode.getTokens.mkString(\" \"))\r\n  }\r\n\r\n}\r\n<\/pre>\n<p>There are a few things to note here. The <em>import<\/em> statement at the top is what tells Scala the fully qualified package names for the classes <strong>Node<\/strong> and <strong>Value<\/strong>. You could have equivalently written it less concisely as follows.<\/p>\n<pre class=\"brush: scala;\">import opennlp.scalabha.model.Node\r\nimport opennlp.scalabha.model.Value\r\n<\/pre>\n<p>Or, you could have left out the <em>import<\/em> statement and written the fully qualified names everywhere, e.g.:<\/p>\n<pre class=\"brush: scala;\">val leaf1 = opennlp.scalabha.model.Value(\"I\")\r\n<\/pre>\n<p>Second, <strong>Node<\/strong> and <strong>Value<\/strong> are <em>case<\/em> classes. We\u2019ll discus this more later, but for now, all you need to know is that to create an object of the <strong>Node<\/strong> or <strong>Value<\/strong> classes, it isn\u2019t necessary to use the \u201c<em>new<\/em>\u201d keyword.<\/p>\n<p>Third, the <em>print<\/em> statements are using the Scalabha API (Application Programming Interface) to do useful things with the objects, such as printing out the tree they describe, printing the yield of the nodes (the words that they cover), and so on. The scaladoc you looked at before for Scalabha shows you these functions, so go have a look if you haven\u2019t already.<\/p>\n<p>Note that if you had left the triggered compilation on, SBT will have automatically compiled the <em>TreeTest.scala<\/em>. Otherwise, make sure to compile it yourself. Then, run it.<\/p>\n<pre class=\"brush: bash;\">$ scalabha run opennlp.bcomposes.TreeTest\r\nPrinting the full tree:\r\nNode(S,List(Node(NP,List(Value(I))), Node(VP,List(Node(V,List(Value(like))), Node(NP,List(Value(coffee)))))))\r\n\r\nPrinting the children of the VP node:\r\nList(Node(V,List(Value(like))), Node(NP,List(Value(coffee))))\r\n\r\nPrinting the yield of the full tree:\r\nI like coffee\r\n\r\nPrinting the yield of the VP node:\r\nlike coffee\r\n<\/pre>\n<h2> Make and use your own package<\/h2>\n<p>By importing the classes you need in this manner, you can get more done by using them as you need. Any class in Scalabha or in the libraries that are included with it will be available for you, including any classes you define. As an example, do the following.<\/p>\n<pre class=\"brush: bash;\">$ cd $SCALABHA_DIR\/src\/main\/scala\/opennlp\/bcomposes\r\n$ mkdir person\r\n$ mkdir music\r\n<\/pre>\n<p>Now save the <strong>Person<\/strong> class from the previous tutorial as <em>Person.scala<\/em> in the <em>person<\/em> directory. Here\u2019s the code again (note the addition of the <em>package<\/em> statement).<\/p>\n<pre class=\"brush: scala;\">package opennlp.bcomposes.person\r\n\r\nclass Person (\r\n  val firstName: String,\r\n  val lastName: String,\r\n  val age: Int,\r\n  val occupation: String\r\n) {\r\n\r\n  def fullName: String = firstName + \" \" + lastName\r\n\r\n  def greet (formal: Boolean): String = {\r\n    if (formal)\r\n      \"Hello, my name is \" + fullName + \". I'm a \" + occupation + \".\"\r\n    else\r\n      \"Hi, I'm \" + firstName + \"!\"\r\n  }\r\n\r\n}\r\n<\/pre>\n<p>Now save the following as <em>RadioheadGreeting.scala<\/em> in the <em>music<\/em> directory.<\/p>\n<pre class=\"brush: scala;\">package opennlp.bcomposes.music\r\n\r\nimport opennlp.bcomposes.person.Person\r\n\r\nobject RadioheadGreeting {\r\n\r\n  def main (args: Array[String]) {\r\n    val thomYorke = new Person(\"Thom\", \"Yorke\", 43, \"musician\")\r\n    val johnnyGreenwood = new Person(\"Johnny\", \"Greenwood\", 39, \"musician\")\r\n    val colinGreenwood = new Person(\"Colin\", \"Greenwood\", 41, \"musician\")\r\n    val edObrien = new Person(\"Ed\", \"O'Brien\", 42, \"musician\")\r\n    val philSelway = new Person(\"Phil\", \"Selway\", 44, \"musician\")\r\n    val radiohead = List(thomYorke, johnnyGreenwood, colinGreenwood, edObrien, philSelway)\r\n    radiohead.foreach(bandmember =&gt; println(bandmember.greet(false)))\r\n  }\r\n\r\n}\r\n<\/pre>\n<p>When we did <a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scripting-compiling-main.html\" title=\"First steps in Scala for beginning programmers, Part 10\">the compilation tutorial<\/a> previously, <em>Person.scala<\/em> and <em>RadioheadGreeting.scala<\/em> were in the same directory, which allowed the latter to know about the <strong>Person<\/strong> class. Now that they are in separate packages, the <strong>Person<\/strong> class must be explicitly imported; once you\u2019ve done so, you can code with <strong>Person<\/strong> objects just as you did before.<\/p>\n<p>Finally, to run it, we now must specify the fully qualified package name for <strong>RadioheadGreeting<\/strong>.<\/p>\n<pre class=\"brush: bash;\">$ scalabha run opennlp.bcomposes.music.RadioheadGreeting\r\nHi, I'm Thom!\r\nHi, I'm Johnny!\r\nHi, I'm Colin!\r\nHi, I'm Ed!\r\nHi, I'm Phil!\r\n<\/pre>\n<h2> A note on package names and their relation to directories<\/h2>\n<p>Package names are made unique by certain conventions that generally ensure you won\u2019t get clashes. For example, we are using<strong> opennlp.scalabha<\/strong> and <strong>opennlp.bcomposes<\/strong>, which I happen to know are unique. Quite often these names will include full internet domains, in reverse, like <strong>org.apache.commons<\/strong> and <strong>com.cloudera.crunch<\/strong>. By convention, we put the source files that are in packages (and subpackages) in directory structures that reflect the names. So, for example, <strong>opennlp.bcomposes.music.RadioheadGreeting<\/strong> is in the directory <em>src\/main\/scala\/opennlp\/bcomposes\/music<\/em>. However, it is worth noting that this is not a hard constraint with Scala (as it is with Java).<\/p>\n<p>There is a great deal more to using a build system, but this is where I must end this discussion, hoping it is enough to get the core concepts across and make it possible for my students to do <a href=\"http:\/\/icl-f11.utcompling.com\/assignments\/hw4-part-of-speech-tagging\">the homework on part-of-speech tagging<\/a> and making use of the <strong>opennlp.scalabha.postag<\/strong> package!<\/p>\n<p><strong><i>Reference: <\/i><\/strong><a href=\"http:\/\/bcomposes.wordpress.com\/2011\/10\/26\/first-steps-in-scala-for-beginning-programmers-part-11\/\">First steps in Scala for beginning programmers, Part 11<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Jason Baldridge at the <a href=\"http:\/\/bcomposes.wordpress.com\/\">Bcomposes<\/a> blog.<\/p>\n<p><strong><i>Related Articles :<\/i><\/strong><\/p>\n<ul>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/scala-tutorial-scala-repl-expressions.html\">Scala Tutorial &#8211; Scala REPL, expressions, variables, basic types, simple functions, saving and running programs, comments<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/scala-tutorial-tuples-lists-methods-on.html\">Scala Tutorial &#8211; Tuples, Lists, methods on Lists and Strings<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/scala-tutorial-conditional-execution.html\">Scala Tutorial &#8211; conditional execution with if-else blocks and matching<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-iteration-for.html\">Scala Tutorial &#8211; iteration, for expressions, yield, map, filter, count<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions.html\">Scala Tutorial &#8211; regular expressions, matching<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-regular-expressions_05.html\">Scala Tutorial &#8211; regular expressions, matching and substitutions with the scala.util.matching API<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-maps-sets-groupby.html\">Scala Tutorial &#8211; Maps, Sets, groupBy, Options, flatten, flatMap<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scalaiosource-accessing.html\">Scala Tutorial &#8211; scala.io.Source, accessing files, flatMap, mutable Maps<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-objects-classes.html\">Scala Tutorial &#8211; objects, classes, inheritance, traits, Lists with multiple related types, apply<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/10\/scala-tutorial-scripting-compiling-main.html\">Scala Tutorial &#8211; scripting, compiling, main methods, return values of functions<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-code-blocks-coding-style.html\">Scala Tutorial &#8211; code blocks, coding style, closures, scala documentation project<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/fun-with-function-composition-in-scala.html\">Fun with function composition in Scala<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/08\/how-scala-changed-way-i-think-about-my.html\">How Scala changed the way I think about my Java Code<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2011\/09\/testing-with-scala.html\">Testing with Scala<\/a><\/li>\n<li><a href=\"http:\/\/www.javacodegeeks.com\/2010\/12\/things-every-programmer-should-know.html\">Things Every Programmer Should Know<\/a><\/li>\n<\/ul>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Preface This is part 11 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other resources on the links page of the Computational Linguistics course I\u2019m creating these for. Additionally you can find this and other tutorial series on the JCG Java &hellip;<\/p>\n","protected":false},"author":67,"featured_media":227,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[235],"class_list":["post-716","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scala","tag-scala-tutorial"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Scala Tutorial - SBT, scalabha, packages, build systems - Java Code Geeks<\/title>\n<meta name=\"description\" content=\"PrefaceThis is part 11 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Scala Tutorial - SBT, scalabha, packages, build systems - Java Code Geeks\" \/>\n<meta property=\"og:description\" content=\"PrefaceThis is part 11 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2011-11-02T11:36:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2012-10-21T20:44:41+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Jason Baldridge\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@http:\/\/twitter.com\/jasonbaldridge\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Jason Baldridge\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"21 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html\"},\"author\":{\"name\":\"Jason Baldridge\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/95ef2670a4040b0f7101c48dba2795c0\"},\"headline\":\"Scala Tutorial &#8211; SBT, scalabha, packages, build systems\",\"datePublished\":\"2011-11-02T11:36:00+00:00\",\"dateModified\":\"2012-10-21T20:44:41+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html\"},\"wordCount\":3531,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"keywords\":[\"Scala Tutorial\"],\"articleSection\":[\"Scala\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html\",\"name\":\"Scala Tutorial - SBT, scalabha, packages, build systems - Java Code Geeks\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"datePublished\":\"2011-11-02T11:36:00+00:00\",\"dateModified\":\"2012-10-21T20:44:41+00:00\",\"description\":\"PrefaceThis is part 11 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/scala-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2011\\\/11\\\/scala-tutorial-sbt-scalabha-packages.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"JVM Languages\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/jvm-languages\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Scala\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/jvm-languages\\\/scala\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Scala Tutorial &#8211; SBT, scalabha, packages, build systems\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/95ef2670a4040b0f7101c48dba2795c0\",\"name\":\"Jason Baldridge\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g\",\"caption\":\"Jason Baldridge\"},\"sameAs\":[\"http:\\\/\\\/bcomposes.wordpress.com\\\/\",\"http:\\\/\\\/www.linkedin.com\\\/pub\\\/jason-baldridge\\\/5\\\/629\\\/9b2\",\"https:\\\/\\\/x.com\\\/http:\\\/\\\/twitter.com\\\/jasonbaldridge\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/jason-baldridge\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Scala Tutorial - SBT, scalabha, packages, build systems - Java Code Geeks","description":"PrefaceThis is part 11 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html","og_locale":"en_US","og_type":"article","og_title":"Scala Tutorial - SBT, scalabha, packages, build systems - Java Code Geeks","og_description":"PrefaceThis is part 11 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other","og_url":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2011-11-02T11:36:00+00:00","article_modified_time":"2012-10-21T20:44:41+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","type":"image\/jpeg"}],"author":"Jason Baldridge","twitter_card":"summary_large_image","twitter_creator":"@http:\/\/twitter.com\/jasonbaldridge","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Jason Baldridge","Est. reading time":"21 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html"},"author":{"name":"Jason Baldridge","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/95ef2670a4040b0f7101c48dba2795c0"},"headline":"Scala Tutorial &#8211; SBT, scalabha, packages, build systems","datePublished":"2011-11-02T11:36:00+00:00","dateModified":"2012-10-21T20:44:41+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html"},"wordCount":3531,"commentCount":0,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","keywords":["Scala Tutorial"],"articleSection":["Scala"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html","url":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html","name":"Scala Tutorial - SBT, scalabha, packages, build systems - Java Code Geeks","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","datePublished":"2011-11-02T11:36:00+00:00","dateModified":"2012-10-21T20:44:41+00:00","description":"PrefaceThis is part 11 of tutorials for first-time programmers getting into Scala. Other posts are on this blog, and you can get links to those and other","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/scala-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2011\/11\/scala-tutorial-sbt-scalabha-packages.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"JVM Languages","item":"https:\/\/www.javacodegeeks.com\/category\/jvm-languages"},{"@type":"ListItem","position":3,"name":"Scala","item":"https:\/\/www.javacodegeeks.com\/category\/jvm-languages\/scala"},{"@type":"ListItem","position":4,"name":"Scala Tutorial &#8211; SBT, scalabha, packages, build systems"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/95ef2670a4040b0f7101c48dba2795c0","name":"Jason Baldridge","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/b755d282f869512990e0ce9118c71ccd859fad42163f8e5d62d180ea42ea9720?s=96&d=mm&r=g","caption":"Jason Baldridge"},"sameAs":["http:\/\/bcomposes.wordpress.com\/","http:\/\/www.linkedin.com\/pub\/jason-baldridge\/5\/629\/9b2","https:\/\/x.com\/http:\/\/twitter.com\/jasonbaldridge"],"url":"https:\/\/www.javacodegeeks.com\/author\/jason-baldridge"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/716","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/67"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=716"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/716\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/227"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=716"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=716"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=716"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}