developer tip

IntelliJ IDEA 내에서 SBT를 사용하여 Uber JAR (Fat JAR)을 빌드하는 방법은 무엇입니까?

copycodes 2020. 9. 18. 08:21
반응형

IntelliJ IDEA 내에서 SBT를 사용하여 Uber JAR (Fat JAR)을 빌드하는 방법은 무엇입니까?


간단한 Scala 프로젝트를 빌드하기 위해 IntelliJ IDEA 내에서 SBT를 사용하고 있습니다.

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")        
  )

libraryDependencies ++= Seq(
  "org.apache.spark" %% "spark-core" % "1.2.0" % "provided",
  "org.apache.spark" %% "spark-streaming" % "1.2.0" % "provided",
  "org.apache.spark" % "spark-streaming-twitter_2.10" % "1.2.0"
)

// 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

다른 사람에게 도움이되기를 바랍니다.


For those who wants to embeed SBT within IntelliJ IDE: How to run sbt-assembly tasks from within IntelliJ IDEA?


3 Step Process For Building Uber JAR/Fat JAR in IntelliJ Idea:

Uber JAR/Fat JAR : JAR file having all external libraray dependencies in it.

  1. Adding SBT Assembly plugin in IntelliJ Idea

    Plugin sbt Path

    Go to ProjectName/project/target/plugins.sbt file and add this line addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

  2. Adding Merge,Discard and Do Not Add strategy in build.sbt

    Build sbt Path

    Go to ProjectName/build.sbt file and add the Strategy for Packaging of an Uber JAR

    Merge Strategy : If there is conflict in two packages about a version of library then which one to pack in Uber JAR.
    Discard Strategy : To remove some files from library which you do not want to package in Uber JAR.
    Do not Add Strategy : Do not add some package to Uber JAR.
    For ex: spark-core will be already present at your Spark Cluster.So we should not package this in Uber JAR

    Merge Strategy and Discard Strategy Basic Code :

    assemblyMergeStrategy in assembly := { case PathList("META-INF", xs @ _*) => MergeStrategy.discard case x => MergeStrategy.first }

    So you are asking to discard META-INF files using this command MergeStrategy.discard and for rest of the files you are taking the first occurrence of library file if there is any conflict by using this command MergeStrategy.first.

    Do not Add Strategy Basic Code :

    libraryDependencies += "org.apache.spark" %% "spark-core" % "1.4.1" %"provided"

    If we do not want to add the spark-core to our Uber JAR file as it will be already on our clutser, so we are adding the % "provided" at end of it library dependency.

  3. Building Uber JAR with all its dependencies

    sbtassembly

    In terminal type sbt assembly for building up the package


Voila!!! Uber JAR is built. JAR will be in ProjectName/target/scala-XX

JarBuilt


Add the following line to your project/plugins.sbt

addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.12.0")

Add the following to your 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
}

The Assembly merge strategy is used to resolve conflicts occurred when creating fat jar.

참고URL : https://stackoverflow.com/questions/28459333/how-to-build-an-uber-jar-fat-jar-using-sbt-within-intellij-idea

반응형