간단한 Scala 프로젝트를 빌드하기 위해 SBT (IntelliJ IDEA 내)를 사용하고 있습니다.
Uber JAR 파일 (일명 Fat JAR, Super JAR) 을 빌드하는 가장 간단한 방법 이 무엇인지 알고 싶습니다 .
현재 SBT를 사용하고 있지만 JAR 파일을 Apache Spark에 제출할 때 다음 오류가 발생합니다.
스레드 “main”java.lang.SecurityException의 예외 : Manifest 기본 속성에 대한 유효하지 않은 서명 파일 요약
또는 컴파일 시간 동안이 오류 :
java.lang.RuntimeException : 중복 제거 : 다음 위치에 다른 파일 내용이 있습니다.
PATH \ DEPENDENCY.jar : META-INF / DEPENDENCIES
PATH \ DEPENDENCY.jar : META-INF / MANIFEST.MF
그것은 처럼 보이는 내 일부 종속성이 최종 동네 짱의 JAR 파일에서 제거해야합니다 서명 파일 (META-INF)를 포함 때문입니다.
다음 과 같이 sbt-assembly 플러그인 을 사용하려고 했습니다.
/project/assembly.sbt
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
/project/plugins.sbt
logLevel := Level.Warn
/build.sbt
lazy val commonSettings = Seq(
name := "Spark-Test"
version := "1.0"
scalaVersion := "2.11.4"
)
lazy val app = (project in file("app")).
settings(commonSettings: _*).
settings(
libraryDependencies ++= Seq(
"org.apache.spark" %% "spark-core" % "1.2.0",
"org.apache.spark" %% "spark-streaming" % "1.2.0",
"org.apache.spark" % "spark-streaming-twitter_2.10" % "1.2.0"
)
)
IntelliJ IDEA에서 ” Build Artifact … “를 클릭 하면 JAR 파일이 생성됩니다. 그러나 나는 같은 오류로 끝납니다 …
저는 SBT를 처음 접했고 IntelliJ IDE를 많이 실험하지 않았습니다.
감사.
답변
마지막으로 IntelliJ IDEA 사용을 완전히 건너 뛰어 글로벌 이해에서 노이즈 생성을 방지합니다. 🙂
나는 공식 SBT 튜토리얼을 읽기 시작했다 .
다음 파일 구조로 프로젝트를 만들었습니다.
my-project/project/assembly.sbt
my-project/src/main/scala/myPackage/MyMainObject.scala
my-project/build.sbt
내 assembly.sbt 파일 에 sbt-assembly 플러그인 을 추가했습니다 . 뚱뚱한 JAR을 만들 수 있습니다.
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
내 최소한의 build.sbt 는 다음과 같습니다.
lazy val root = (project in file(".")).
settings(
name := "my-project",
version := "1.0",
scalaVersion := "2.11.4",
mainClass in Compile := Some("myPackage.MyMainObject")
)
val sparkVersion = "1.2.0"
libraryDependencies ++= Seq(
"org.apache.spark" %% "spark-core" % sparkVersion % "provided",
"org.apache.spark" %% "spark-streaming" % sparkVersion % "provided",
"org.apache.spark" %% "spark-streaming-twitter" % sparkVersion
)
// META-INF discarding
mergeStrategy in assembly <<= (mergeStrategy in assembly) { (old) =>
{
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}
}
참고 : % "provided"
최종 팻 JAR에 종속성을 포함하지 않는 수단 (이러한 라이브러리는 이미 내 작업자에 포함되어 있음)
참고 : 이 answser에서 영감을 얻은 META-INF 폐기 .
이제 내 / my-project 루트 폴더 에서 다음 명령을 실행 하여 SBT ( 설치 방법)를 사용하여 뚱뚱한 JAR을 빌드 할 수 있습니다 .
sbt assembly
내 fat JAR은 이제 새로 생성 된 / target 폴더에 있습니다.
/my-project/target/scala-2.11/my-project-assembly-1.0.jar
다른 사람에게 도움이되기를 바랍니다.
IntelliJ IDE 내에서 SBT를 횡령하려는 사람들을 위해 : IntelliJ IDEA 내에서 sbt-assembly 작업을 실행하는 방법은 무엇입니까?
답변
IntelliJ Idea에서 Uber JAR / Fat JAR 빌드를위한 3 단계 프로세스 :
Uber JAR / Fat JAR : 모든 외부 libraray 종속성이있는 JAR 파일입니다.
-
IntelliJ Idea에 SBT 어셈블리 플러그인 추가
ProjectName / project / target / plugins.sbt 파일로 이동 하여이 줄을 추가합니다.
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
-
build.sbt에 병합, 폐기 및 추가 안 함 전략 추가
ProjectName / build.sbt 파일로 이동하여 Uber JAR 패키징 전략을 추가합니다.
병합 전략 : 라이브러리 버전에 대한 두 패키지에 충돌이있는 경우 Uber JAR에 패키지 할 패키지.
폐기 전략 : Uber JAR에서 패키징하지 않으려는 라이브러리에서 일부 파일을 제거합니다.
전략 추가 금지 : Uber JAR에 일부 패키지를 추가하지 마십시오.
예 :spark-core
Spark Cluster에 이미 존재하므로 Uber JAR에 패키징해서는 안됩니다.전략 병합 및 전략 기본 코드 폐기 :
assemblyMergeStrategy in assembly := {
case PathList("META-INF", xs @ _*) => MergeStrategy.discard
case x => MergeStrategy.first
}따라서이 명령을 사용하여 META-INF 파일을 삭제하도록 요청하고
MergeStrategy.discard
나머지 파일에 대해이 명령을 사용하여 충돌이있는 경우 라이브러리 파일 의 첫 번째 발생 을 가져옵니다MergeStrategy.first
.전략 기본 코드를 추가하지 마십시오.
libraryDependencies += "org.apache.spark" %% "spark-core" % "1.4.1" %"provided"
이미 클러 서에있는 Uber JAR 파일에 스파크 코어를 추가하지 않으려면
% "provided"
끝에 라이브러리 종속성을 추가합니다 . -
모든 종속성으로 Uber JAR 빌드
sbt assembly
패키지 구축을위한 터미널 유형
짜잔 !!! Uber JAR이 빌드되었습니다. JAR은 ProjectName / target / scala-XX에 있습니다.
답변
프로젝트 /plugins.sbt에 다음 줄을 추가합니다.
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")
build.sbt에 다음을 추가하십시오.
mainClass in assembly := some("package.MainClass")
assemblyJarName := "desired_jar_name_after_assembly.jar"
val meta = """META.INF(.)*""".r
assemblyMergeStrategy in assembly := {
case PathList("javax", "servlet", xs @ _*) => MergeStrategy.first
case PathList(ps @ _*) if ps.last endsWith ".html" => MergeStrategy.first
case n if n.startsWith("reference.conf") => MergeStrategy.concat
case n if n.endsWith(".conf") => MergeStrategy.concat
case meta(_) => MergeStrategy.discard
case x => MergeStrategy.first
}
어셈블리 병합 전략은 fat jar를 만들 때 발생한 충돌을 해결하는 데 사용됩니다.