искра и мельница - создать дополнительную задачу, которая создает отфильтрованную сборку
Я хочу построить mill
задание, которое позволяет мне разрабатывать и запускать задание Spark локально либо SparkSample.run
или иметь толстую банку для местных тестов. В какой-то момент я хотел бы отправить его как отфильтрованную сборку (то есть без всех связанных с Spark библиотек, но со всеми библиотеками проекта) в кластер с запущенным Spark Context.
Я сейчас использую это build.sc
import mill._, scalalib._
import mill.modules.Assembly
object SparkSample extends ScalaModule {
def scalaVersion = "2.12.10"
def scalacOptions =
Seq("-encoding", "utf-8", "-explaintypes", "-feature", "-deprecation")
def ivySparkDeps = Agg(
ivy"org.apache.spark::spark-sql:2.4.5"
.exclude("org.slf4j" -> "slf4j-log4j12"),
ivy"org.slf4j:slf4j-api:1.7.16",
ivy"org.slf4j:slf4j-log4j12:1.7.16"
)
def ivyBaseDeps = Agg(
ivy"com.lihaoyi::upickle:0.9.7"
)
// STANDALONE APP
def ivyDeps = ivyBaseDeps ++ ivySparkDeps
// REMOTE SPARK CLUSTER
// def ivyDeps = ivyBaseDeps
// def compileIvyDeps = ivySparkDeps
// def assemblyRules =
// Assembly.defaultRules ++
// Seq(
// "scala/.*",
// "org.slf4j.*",
// "org.apache.log4j.*"
// ).map(Assembly.Rule.ExcludePattern.apply)
}
Я оставляю все как есть для создания и создания полноценной банки.
Для создания отфильтрованной сборки я комментирую ivyDeps
строчку под "АВТОНОМНОЕ ПРИЛОЖЕНИЕ" и раскомментируйте все ниже "УДАЛЕННЫЙ КЛАСТЕР ИСКРЫ".
Мне показалось, что редактирование файла сборки для новой задачи не очень элегантно, поэтому я попытался добавить отдельную задачу в build.sc
def assembly2 = T {
def ivyDeps = ivyBaseDeps
def compileIvyDeps = ivySparkDeps
def assemblyRules =
Assembly.defaultRules ++
Seq(
"scala/.*",
"org.slf4j.*",
"org.apache.log4j.*"
).map(Assembly.Rule.ExcludePattern.apply)
super.assembly
}
но когда я бегу SparkSample.assembly2
он по-прежнему получает полную сборку, а не фильтрованную. Похоже на приоритетivyDeps
et. al. в Задаче не работает.
Возможно ли это в mill
?
1 ответ
Вы не можете переопределить определения в задачах. Просто локально определяя некоторыеivyDeps
а также compileIvyDeps
не сделает волшебным образом super.assembly
используя их.
Конечно, вы можете создать эту задачу, посмотрев, как super.assembly
определяется в JavaModule
, но вы в конечном итоге скопируете и адаптируете гораздо больше целей (upstreamAssembly
, upstreamAssemblyClasspath
, transitiveLocalClasspath
и т. д.) и затруднить чтение вашего файла сборки.
Лучшим способом было бы сделать более легкие зависимости и правила сборки по умолчанию и перенести создание автономного JAR в подмодуль.
import mill._, scalalib._
import mill.modules.Assembly
object SparkSample extends ScalaModule { outer =>
def scalaVersion = "2.12.10"
def scalacOptions =
Seq("-encoding", "utf-8", "-explaintypes", "-feature", "-deprecation")
def ivySparkDeps = Agg(
ivy"org.apache.spark::spark-sql:2.4.5"
.exclude("org.slf4j" -> "slf4j-log4j12"),
ivy"org.slf4j:slf4j-api:1.7.16",
ivy"org.slf4j:slf4j-log4j12:1.7.16"
)
def ivyDeps = Agg(
ivy"com.lihaoyi::upickle:0.9.7"
)
def compileIvyDeps = ivySparkDeps
def assemblyRules =
Assembly.defaultRules ++
Seq(
"scala/.*",
"org.slf4j.*",
"org.apache.log4j.*"
).map(Assembly.Rule.ExcludePattern.apply)
object standalone extends ScalaModule {
def scalaVersion = outer.scalaVersion
def moduleDeps = Seq(outer)
def ivyDeps = outer.ivySparkDeps
}
}
Чтобы создать Spark Cluster JAR, запустите: mill SparkSample.assembly
Чтобы создать автономный запуск JAR: mill SparkSample.standalone.assembly
Чтобы создать и то, и другое, вы просто запускаете: mill __.assembly