[HADOOP] build.sbt에서 구아바가 제대로 음영 처리되지 않는 이유는 무엇입니까?
HADOOPbuild.sbt에서 구아바가 제대로 음영 처리되지 않는 이유는 무엇입니까?
카산드라와 HDFS는 내부적으로 구아바를 사용하지만 여러 가지 이유로 의존성을 가리지 않습니다. 구아바 버전은 이진 호환되지 않기 때문에 런타임에 NoSuchMethodErrors를 찾고 있습니다.
내 build.sbt에서 구아바를 직접 음영 처리하려고했습니다.
val HadoopVersion = "2.6.0-cdh5.11.0"
// ...
val hadoopHdfs = "org.apache.hadoop" % "hadoop-hdfs" % HadoopVersion
val hadoopCommon = "org.apache.hadoop" % "hadoop-common" % HadoopVersion
val hadoopHdfsTest = "org.apache.hadoop" % "hadoop-hdfs" % HadoopVersion % "test" classifier "tests"
val hadoopCommonTest = "org.apache.hadoop" % "hadoop-common" % HadoopVersion % "test" classifier "tests"
val hadoopMiniDFSCluster = "org.apache.hadoop" % "hadoop-minicluster" % HadoopVersion % Test
// ...
assemblyShadeRules in assembly := Seq(
ShadeRule.rename("com.google.common.**" -> "shade.com.google.common.@1").inLibrary(hadoopHdfs).inProject,
ShadeRule.rename("com.google.common.**" -> "shade.com.google.common.@1").inLibrary(hadoopCommon).inProject,
ShadeRule.rename("com.google.common.**" -> "shade.com.google.common.@1").inLibrary(hadoopHdfsTest).inProject,
ShadeRule.rename("com.google.common.**" -> "shade.com.google.common.@1").inLibrary(hadoopCommonTest).inProject,
ShadeRule.rename("com.google.common.**" -> "shade.com.google.common.@1").inLibrary(hadoopMiniDFSCluster).inProject
)
assemblyJarName in assembly := s"${name.value}-${version.value}.jar"
assemblyMergeStrategy in assembly := {
case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard
case _ => MergeStrategy.first
}
그러나 런타임 예외는 지속됩니다 (ha-사람들은 카산드라 농담입니다).
구체적인 예외는
[info] HdfsEntitySpec *** ABORTED ***
[info] java.lang.NoSuchMethodError: com.google.common.base.Objects.toStringHelper(Ljava/lang/Object;)Lcom/google/common/base/Objects$ToStringHelper;
[info] at org.apache.hadoop.metrics2.lib.MetricsRegistry.toString(MetricsRegistry.java:406)
[info] at java.lang.String.valueOf(String.java:2994)
[info] at java.lang.StringBuilder.append(StringBuilder.java:131)
[info] at org.apache.hadoop.ipc.metrics.RetryCacheMetrics.<init>(RetryCacheMetrics.java:46)
[info] at org.apache.hadoop.ipc.metrics.RetryCacheMetrics.create(RetryCacheMetrics.java:53)
[info] at org.apache.hadoop.ipc.RetryCache.<init>(RetryCache.java:202)
[info] at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.initRetryCache(FSNamesystem.java:1038)
[info] at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.<init>(FSNamesystem.java:949)
[info] at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.<init>(FSNamesystem.java:796)
[info] at org.apache.hadoop.hdfs.server.namenode.NameNode.format(NameNode.java:1040)
[info] ...
런타임 오류를 막기 위해 구아바를 올바르게 음영 처리하려면 어떻게합니까?
해결법
-
==============================
1.음영 처리 규칙은 뚱뚱한 항아리를 만들 때만 적용됩니다. 다른 sbt 작업 중에는 적용되지 않습니다.
음영 처리 규칙은 뚱뚱한 항아리를 만들 때만 적용됩니다. 다른 sbt 작업 중에는 적용되지 않습니다.
hadoop 종속성 내부에서 일부 라이브러리를 음영 처리하려면 hadoop 종속성 만있는 새 프로젝트를 만들고 라이브러리를 음영 처리하고 음영 처리 된 모든 hadoop 종속성이있는 팻 jar를 게시 할 수 있습니다.
새로운 hadoop jar의 모든 종속 항목을 사용하는 사람은 "알 수 없음"이므로 충돌을 수동으로 처리해야하므로 이는 완벽한 솔루션이 아닙니다.
다음은 fat hadoop jar를 게시하기 위해 build.sbt에 필요한 코드입니다. (코드 및 sbt 어셈블리 문서 사용) :
val HadoopVersion = "2.6.0-cdh5.11.0" val hadoopHdfs = "org.apache.hadoop" % "hadoop-hdfs" % HadoopVersion val hadoopCommon = "org.apache.hadoop" % "hadoop-common" % HadoopVersion val hadoopHdfsTest = "org.apache.hadoop" % "hadoop-hdfs" % HadoopVersion classifier "tests" val hadoopCommonTest = "org.apache.hadoop" % "hadoop-common" % HadoopVersion % classifier "tests" val hadoopMiniDFSCluster = "org.apache.hadoop" % "hadoop-minicluster" % HadoopVersion lazy val fatJar = project .enablePlugins(AssemblyPlugin) .settings( libraryDependencies ++= Seq( hadoopHdfs, hadoopCommon, hadoopHdfsTest, hadoopCommonTest, hadoopMiniDFSCluster ), assemblyShadeRules in assembly := Seq( ShadeRule.rename("com.google.common.**" -> "shade.@0").inAll ), assemblyMergeStrategy in assembly := { case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard case _ => MergeStrategy.first }, artifact in (Compile, assembly) := { val art = (artifact in (Compile, assembly)).value art.withClassifier(Some("assembly")) }, addArtifact(artifact in (Compile, assembly), assembly), crossPaths := false, // Do not append Scala versions to the generated artifacts autoScalaLibrary := false, // This forbids including Scala related libraries into the dependency skip in publish := true ) lazy val shaded_hadoop = project .settings( name := "shaded-hadoop", packageBin in Compile := (assembly in (fatJar, Compile)).value )
나는 그것을 테스트하지는 않았지만 그것이 핵심입니다.
파일에 다른 전략을 적용하고 싶기 때문에 병합 전략으로 인해 문제가 발생할 수 있다는 또 다른 문제를 지적하고자합니다. 기본 전략을 참조하십시오. 중복되지 않는 모든 것에 대한 원래 전략을 유지하기 위해 이와 같은 것을 사용하는 것이 좋습니다.
assemblyMergeStrategy in assembly := { entry: String => { val strategy = (assemblyMergeStrategy in assembly).value(entry) if (strategy == MergeStrategy.deduplicate) MergeStrategy.first else strategy } }
from https://stackoverflow.com/questions/47907446/why-isnt-guava-being-shaded-properly-in-my-build-sbt by cc-by-sa and MIT license
'HADOOP' 카테고리의 다른 글
[HADOOP] 압축 출력 스케일링 / 캐스 케이 딩 Tsv (0) | 2019.08.15 |
---|---|
[HADOOP] hadoop에서 시스템 속성을 맵 함수에 전달하는 방법 (0) | 2019.08.15 |
[HADOOP] 하이브 쿼리는 jdbc를 통해 결과 집합을 생성 할 수 없습니다 (0) | 2019.08.15 |
[HADOOP] 연결하는 동안 Eclipse Hadoop 플러그인에 "java.io.EOFException"이 표시됨 (0) | 2019.08.15 |
[HADOOP] 하둡의 setJarByClass () (0) | 2019.08.15 |