Maven - 如何在两个相互依赖的项目中使用不同的版本依赖关系

时间:2018-04-25 08:09:22

标签: java maven apache-spark dependencies

概述: 我有两个项目A和B. 项目A必须使用L库/ API的版本v1。 项目B,必须使用L库/ API的版本v2。 项目A依赖于项目B(在项目A中,我需要调用B中包含的方法)。

具体说明: 项目A实际上是一个机器学习器,它有一组使用旧版本spark-mllib的算法。 我想在项目A中集成XGBOOST-spark算法。

问题是XGBOOST api,特别是:ml.dmlc.xgboost4j.scala.spark.XGBoost.train()方法,需要RDD<org.apache.spark.ml.feature.LabeledPoint>。但是org.apache.spark.ml.feature.LabeledPoint仅在较新版本的spark-mllib中可用。从项目A(使用较旧版本的spark-mllib),我只能访问org.apache.spark.mllib.regression.LabeledPoint。因此,如果不升级项目A的spark-mllib版本,我无法直接在项目A中集成XGBOOST。

幸运的是,较新版本的spark-mllib有一种从旧的LabeledPoint(org.apache.spark.mllib.regression.LabeledPoint)转换为新的LabeledPoint(org.apache.spark.ml.feature.LabeledPoint)的方法。 )。方法是:org.apache.spark.mllib.regression.LabeledPoint.asML()。

所以,问题是:是否有任何聪明的方法使用仅在较新版本的spark中可用的方法.asML(),以便我可以转换LabeledPoint并将其传递给XGBOOST API?< / p>

我不熟悉maven如何处理依赖关系,但我想到的是:

创建一个项目B,它使用较新版本的spark-mllib和XGBOOST-API,并且我们有一个类和一个接收参数的方法(来自项目A),将旧的LabeledPoint转换为新的LabeledPoint调用生成模型的XGBoost.train()方法,然后将模型传回项目A.我们在项目A中导入该类(来自项目B),调用它的方法,得到模型,我们照常继续我们的业务。

当然,我试图这样做。但它不起作用。我认为这是因为我们在整个依赖树中只能有一个版本的spark-mllib。由于项目B中的类抛出java.lang.NoSuchMethodError: org.apache.spark.mllib.regression.LabeledPoint.asML()Lorg/apache/spark/ml/feature/LabeledPoint;,似乎在整个依赖关系树中,我们实际上使用了旧版本的spark-mllib(这是因为旧版本更接近依赖关系树的根) 。即使在项目B中,我们使用较新版本的spark-mllib,它具有asML()方法。

所以,实际的问题是:有没有聪明的方法使这项工作?没有在项目A上升级spark-mllib版本?升级不是一个可行的选择。项目A很大,如果我升级那个版本,我就搞砸了一切。

[更新] 我甚至尝试使用ClassLoader(URLClassLoader)来直接从spark-mllib_2.11-2.3.0.jar加载类并打印所有可用的方法。代码在这里:

URLClassLoader clsLoader = URLClassLoader.newInstance(new URL[] { 
            new URL("file:///home/myhome/spark-mllib_2.11-2.3.0.jar") 
            });
      Class cls = clsLoader.loadClass("org.apache.spark.mllib.regression.LabeledPoint");

      Method[] m = cls.getDeclaredMethods();
      for (int i = 0; i < m.length; i++)
          System.out.println(m[i].toString());

在我的.pom文件中,如果我添加依赖项:

<dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-mllib_2.11</artifactId>
        <version>2.3.0</version>
    </dependency>

如果我使用2.3.0版本,方法public org.apache.spark.ml.feature.LabeledPoint org.apache.spark.mllib.regression.LabeledPoint.asML()会出现结果。

但是当我使用spark-mllib的1.6.2版本时,它就不再存在了。 尽管asML()方法在spark-mllib的jar中。这有点奇怪。

1 个答案:

答案 0 :(得分:1)

您可以通过创建项目B的着色依赖项并在项目A中使用它来实现此目的。请参阅此answer以了解maven着色以及如何使用它。