Reputation: 591
Been recently trying to change the way my Scala project does the assembly so that only a single jar is generated out of it instead of one per module.
main-project
| - inner-module-one [inner_module_one]
| - inner-module-two [inner_module_two]
What I've currently done is the following for the main module (the one I want its uber jar containing other modules content).
project
.in(file("."))
.settings(
name := "main-project",
assemblyName,
settings
)
.aggregate(
inner_module_one,
inner_module_two
)
Having the other two modules declared as follows.
lazy val inner_module_one = project
.in(file("inner-module-one"))
.settings(
name := "inner-module-one",
assemblyName,
settings,
dependencies and such (...)
)
.dependsOn(
inner_module_two
)
The jar file generated for the main-project
is really, really small (no more than 5mbs in size) and only contains Scala related stuff, no project classes or such. However, other modules jars are complete and contains everything they require.
I've already tried adding the following setting to the main-project
.
aggregate in assembly := false
But still no luck so far. Jars for submodules aren't generated but the main-project
jar still doesn't contain the contents of the submodules.
Any clue where the issue could be?
EDIT
Tried what @LuisMiguelMejíaSuárez suggested and seems to be wanting to build, however, some errors arise that were already solved within their respective modules. In a given module there are some conflicts which are solved due to some overrides, but now they are appearing again.
[error] deduplicate: different file contents found in the following:
Having the dependsOn
instead of aggregate
affects the way dependencies are added, overridden and such?
Upvotes: 1
Views: 768
Reputation: 8539
Let's divide your question into two sections, how to include the submodules into the main-project
, and you want to know how to not package assembly the 2 submodules.
Let's start from the easier, the second. sbt-assembly
, is a plugin for sbt. Just like any other plugin, you cann disable it using the disablePlugins
command. Therefore, if you define:
lazy val inner_module_one = project.disablePlugins(AssemblyPlugin)
.in(file("inner-module-one"))
.settings(
name := "inner-module-one"
)
.dependsOn(
inner_module_two
)
then inner_module_one won't build a jar.
To solve the first question, we need to understand the difference between aggregate and dependsOn. For that I'll quote from Jacek Laskowski great explanation:
aggregate causes the tasks to be executed in the aggregating module and all aggregated one while dependsOn sets a CLASSPATH dependency so the libraries are visible to the aggregateing module (depending on the configuration that's compile aka default in the example).
Therefore, when you aggregate inner_module_one
, and inner_module_two
, you just cause then to assembly as well. In order to get those to be part of main-project
all you need to do is declare:
project
.in(file("."))
.settings(
name := "main-project",
assemblyName,
settings
)
.dependsOn(
inner_module_one,
inner_module_two
)
In order to test it, I created the following structue:
main-project
|-inner_module_one
|-main
|-scala
|One.scala
|-inner_module_two
|-main
|-scala
|Two.scala
In order to check whether the class One was in a jar I used the command:
jar tfv inner-module-one/target/scala-2.12/inner-module-one-assembly-0.1.0-SNAPSHOT.jar | grep One
Then, when running sbt assembly
with the original aggregate
, the command above provided empty results on the output jar. And when running sbt assembly
with dependsOn
, the command above provided one result:
480 Fri Oct 09 01:48:14 IDT 2020 One.class
If this causes conflicts, you can read about it at sbt-assembly: deduplication found error
Upvotes: 2