8

I created a multi-project build in sbt. Here's build.sbt in the main directory:

lazy val root = project in file(".") aggregate(data, reco, result)

lazy val data = project dependsOn(common)

lazy val reco = project 

lazy val result = project dependsOn(common)

lazy val common = project

When I use package or one-jar command, the classes and resources in common project are not packaged into data or result jars. So when I run the generated jar by

java -jar data_2.10-1.0-onejar.jar

it leads to NoClassDefFoundError as a consequence.

So could anyone help me deal with such problem? Thanks in advance.

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
Dzanvu
  • 523
  • 7
  • 18
  • It'd be worthwhile to explain *"leading to NoClassDefFoundError as a consequence"*, i.e. when exactly do you face the error? What command/task do you execute to end up with the error? Update your question, please. – Jacek Laskowski Mar 21 '14 at 10:24

2 Answers2

3

Your dependent projects are not exporting Jars (producing classes only). Put the following line in the build.sbt of all dependent projects (including your current project too, if necessary):

exportJars := true

That should fix it.

Vikash Madhow
  • 1,287
  • 11
  • 15
  • I'm curious how would this actually produce the desired result? It this worked, it seems we would not need to use sbt-assembly in some cases. – matanster Oct 18 '15 at 11:45
0

I might be misunderstanding your issue...please pardon me if I have.

From Classpath dependencies:

A project may depend on code in another project. This is done by adding a dependsOn method call.

and later (in the same doc):

Now code in core can use classes from util. This also creates an ordering between the projects when compiling them; util must be updated and compiled before core can be compiled.

and then in Per-configuration classpath dependencies:

foo dependsOn(bar) means that the compile configuration in foo depends on the compile configuration in bar.

We may also need to see what package is all about:

> help package
Produces the main artifact, such as a binary jar.  This is typically an alias for the task that actually does the packaging.

or even inspect it to see what dependencies it has:

> inspect package
[info] Task: java.io.File
[info] Description:
[info]  Produces the main artifact, such as a binary jar.  This is typically an alias for the task that actually does the packaging.
[info] Provided by:
[info]  {file:/C:/dev/sandbox/0.13.2/}root-0-13-2/compile:package
[info] Defined at:
[info]  (sbt.Defaults) Defaults.scala:565
[info] Dependencies:
[info]  compile:packageBin
[info] Delegates:
[info]  compile:package
[info]  *:package
[info]  {.}/compile:package
[info]  {.}/*:package
[info]  */compile:package
[info]  */*:package
[info] Related:
[info]  jacoco:package
[info]  test:package

With all that said, package doesn't package other project's artifacts - you need the sbt-assembly plugin instead (as you're crossing the boundaries of a single project and most if not all tasks in sbt are single-project only).

Jacek Laskowski
  • 72,696
  • 27
  • 242
  • 420
  • 1
    sbt-assembly can package the depended project? I found that sbt-onejar cannot perform such thing. When I package the jar by `one-jar` command, it only packages libraryDependancies but not the related project. – Dzanvu Mar 24 '14 at 02:06
  • See http://stackoverflow.com/questions/22556499/what-are-key-differences-between-sbt-pack-and-sbt-assembly – Jacek Laskowski Mar 24 '14 at 13:52