Ответ 1
tl; dr aggregate
заставляет задачи выполняться в агрегационном модуле и все aggregate
d один, а dependsOn
устанавливает зависимость CLASSPATH, поэтому библиотеки видны в aggregate
(в зависимости от конфигурации, которая compile
aka default
в этом примере).
Образец для демонстрации различий.
Я использую следующий build.sbt
(ничего действительно интересного):
lazy val a = project
lazy val b = project
lazy val c = project dependsOn b aggregate (a,b)
В сборке определяются три модуля a
, b
и c
, а последний c
- агрегат для a
и b
. Там четвертый модуль - неявный, который объединяет все модули a
, b
и c
.
> projects
[info] In file:/Users/jacek/sandbox/aggregate-dependsOn/
[info] a
[info] * aggregate-dependson
[info] b
[info] c
Когда я выполняю задачу в модуле aggreate
, задача будет выполняться в модулях aggregate
d.
> compile
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}b...
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}a...
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}aggregate-dependson...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}c...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[success] Total time: 0 s, completed Oct 22, 2014 9:33:20 AM
То же самое происходит, когда я выполняю задачу в c
, которая, в свою очередь, выполняет ее против a
и b
, но не в проекте верхнего уровня.
> show c/clean
[info] a/*:clean
[info] ()
[info] b/*:clean
[info] ()
[info] c/*:clean
[info] ()
[success] Total time: 0 s, completed Oct 22, 2014 9:34:26 AM
Когда задача выполняется в a
или b
, она запускается только внутри проекта.
> show a/clean
[info] ()
[success] Total time: 0 s, completed Oct 22, 2014 9:34:43 AM
Независимо от того, выполняется ли задача в проектах aggregate
, управляется ключом aggregate
, охваченным проектом и/или задачей.
> show aggregate
[info] a/*:aggregate
[info] true
[info] b/*:aggregate
[info] true
[info] c/*:aggregate
[info] true
[info] aggregate-dependson/*:aggregate
[info] true
Измените его, как описано в Aggregation:
В проекте, выполняющем агрегацию, корневой проект в этом случае вы можете управлять агрегацией для каждой задачи. (...)
aggregate in
update - это совокупный ключ, охваченный задачей обновления.
Ниже я изменяю ключ для модуля c
и clean
, поэтому clean
больше не выполняется в aggregate
d-модулях a
и b
:
> set aggregate in (c, clean) := false
[info] Defining c/*:clean::aggregate
[info] The new value will be used by no settings or tasks.
[info] Reapplying settings...
[info] Set current project to aggregate-dependson (in build file:/Users/jacek/sandbox/aggregate-dependsOn/)
> show c/clean
[info] ()
[success] Total time: 0 s, completed Oct 22, 2014 9:39:13 AM
Другие задачи для c
не затронуты и все еще выполняют задачу в c
будут запускать ее в модулях aggregate
:
> show c/libraryDependencies
[info] a/*:libraryDependencies
[info] List(org.scala-lang:scala-library:2.10.4)
[info] b/*:libraryDependencies
[info] List(org.scala-lang:scala-library:2.10.4)
[info] c/*:libraryDependencies
[info] List(org.scala-lang:scala-library:2.10.4)
Пока aggregate
устанавливает зависимость для задач sbt, поэтому они выполняются в других модулях aggregate
d, dependsOn
устанавливает зависимость CLASSPATH, то есть код в модуле dependsOn
ed отображается в dependsOn
(извините за "новые" слова).
Предположим, что b
имеет основной объект следующим образом:
object Hello extends App {
println("Hello from B")
}
Сохраните объект Hello
до b/hello.scala
, то есть в модуле b
.
Так как c
был определен как dependsOn b
(см. build.sbt
выше), объект Hello
отображается в b
(потому что он принадлежит модулю), но также и в c
.
> b/run
[info] Running Hello
Hello from B
[success] Total time: 0 s, completed Oct 22, 2014 9:46:44 AM
> c/runMain Hello
[info] Running Hello
Hello from B
[success] Total time: 0 s, completed Oct 22, 2014 9:46:58 AM
(мне пришлось использовать runMain
в c
, поскольку только run
не мог видеть класс, который я не могу объяснить).
Попытка запуска задачи в a
заканчивается java.lang.ClassNotFoundException: Hello
, поскольку класс не отображается в модуле.
> a/runMain Hello
[info] Updating {file:/Users/jacek/sandbox/aggregate-dependsOn/}a...
[info] Resolving org.fusesource.jansi#jansi;1.4 ...
[info] Done updating.
[info] Running Hello
[error] (run-main-6) java.lang.ClassNotFoundException: Hello
java.lang.ClassNotFoundException: Hello
at java.lang.ClassLoader.findClass(ClassLoader.java:530)
at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
[trace] Stack trace suppressed: run last a/compile:runMain for the full output.
java.lang.RuntimeException: Nonzero exit code: 1
at scala.sys.package$.error(package.scala:27)
[trace] Stack trace suppressed: run last a/compile:runMain for the full output.
[error] (a/compile:runMain) Nonzero exit code: 1
[error] Total time: 0 s, completed Oct 22, 2014 9:48:15 AM
Переопределите a
до dependsOn b
в build.sbt
, и исключение исчезнет.
В официальной документации вы должны прочитать многопроектные сборки.