Toute tentative de créer un pot de graisse avec SBT donne une erreur comme ceci:Les classes recompilées depuis la source dans les fichiers Spark rompent la fusion de sbt?
java.lang.RuntimeException: deduplicate: different file contents found in the following:
C:\Users\db\.ivy2\cache\org.apache.spark\spark-network-common_2.10\jars\spark-network-common_2.10-1.6.3.jar:com/google/common/base/Function.class
C:\Users\db\.ivy2\cache\com.google.guava\guava\bundles\guava-14.0.1.jar:com/google/common/base/Function.class
Il existe de nombreuses classes, c'est juste un pour le titre d'exemple. Goyave 14.0.1 est la version en jeu pour Function.class dans les deux pots:
[info] +-com.google.guava:guava:14.0.1
...
[info] | | +-com.google.guava:guava:14.0.1
Cela signifie que SBT/lierre ne détectera pas un comme la nouvelle version, mais les tailles et les dates sont différentes dans les pots, ce qui conduit sans doute à l'erreur ci-dessus:
$ jar tvf /c/Users/db/.ivy2/cache/org.apache.spark/spark-network-common_2.10/jars/spark-network-common_2.10-1.6.3.jar | grep "com/google/common/base/Function.class"
549 Wed Nov 02 16:03:20 CDT 2016 com/google/common/base/Function.class
$ jar tvf /c/Users/db/.ivy2/cache/com.google.guava/guava/bundles/guava-14.0.1.jar | grep "com/google/common/base/Function.class"
543 Thu Mar 14 19:56:52 CDT 2013 com/google/common/base/Function.class
Il semble que Apache est recompiler Function.class
de la source plutôt que d'inclure la classe comme initialement compilé. Est-ce que c'est une bonne compréhension de ce qui se passe ici? Maintenant, il est possible d'exclure les classes re-compilées en utilisant sbt, mais y a-t-il un moyen de construire le fichier jar sans exclure explicitement chaque fichier contenant une source recompilée par son nom? En excluant les pots conduit explicitement à quelque chose le long des lignes de l'extrait ci-dessous, ce qui fait croire que je vais descendre un mauvais chemin ici:
libraryDependencies += "org.apache.spark" %% "spark-core" % "1.6.3"
excludeAll(
ExclusionRule(organization = "com.twitter"),
ExclusionRule(organization = "org.apache.spark", name = "spark-network-common_2.10"),
ExclusionRule(organization = "org.apache.hadoop", name = "hadoop-client"),
ExclusionRule(organization = "org.apache.hadoop", name = "hadoop-hdfs"),
ExclusionRule(organization = "org.tachyonproject", name = "tachyon-client"),
ExclusionRule(organization = "commons-beanutils", name = "commons-beanutils"),
ExclusionRule(organization = "commons-collections", name = "commons-collections"),
ExclusionRule(organization = "org.apache.hadoop", name = "hadoop-yarn-api"),
ExclusionRule(organization = "org.apache.hadoop", name = "hadoop-yarn-common"),
ExclusionRule(organization = "org.apache.curator", name = "curator-recipes")
)
,
libraryDependencies += "org.apache.spark" %% "spark-network-common" % "1.6.3" exclude("com.google.guava", "guava"),
libraryDependencies += "org.apache.spark" %% "spark-graphx" % "1.6.3",
libraryDependencies += "com.typesafe.scala-logging" %% "scala-logging-slf4j" % "2.1.2",
libraryDependencies += "org.apache.hadoop" % "hadoop-client" % "2.2.0" exclude("com.google.guava", "guava"),
libraryDependencies += "com.google.guava" % "guava" % "14.0.1",
libraryDependencies += "org.json4s" %% "json4s-native" % "3.2.11",
libraryDependencies += "org.json4s" %% "json4s-ext" % "3.2.11",
libraryDependencies += "com.rabbitmq" % "amqp-client" % "4.1.1",
libraryDependencies += "commons-codec" % "commons-codec" % "1.10",
Si c'est le mauvais chemin, ce qui est une façon plus propre?
C'est ce que je fais pour l'application qui fonctionne sous Spark dans le nuage. Une partie de ce même code est utilisée dans le cadre d'une interface graphique. Il n'y a rien fourni par un conteneur. Peut-être que cela pointe vers une meilleure façon de construire le pot pour l'interface graphique? –
@DonBranson je vois. Je ne recommanderais certainement pas d'emballer Spark dans le cadre d'un pot uber, cela vous mènera à l'enfer de la dépendance, car Spark est assez massive. Au lieu de cela, je m'assurerais que le conteneur a ces dépendances fournies par une gestion de configuration qui est chargée de décompresser les jarres Spark. –
C'est un gâchis de dépendance à chaud, c'est sûr. Il n'y a pas de conteneur pour l'interface graphique. J'ai besoin de construire un standalone que je peux partager avec des non-développeurs. Y-a-t-il un moyen de faire ça? Peut-être que je dois faire un zip avec tous les pots, et un script pour les ajouter tous à un classpath. –