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

Java Maven-如何在相互依赖的两个项目中使用不同的版本依赖关系,java,maven,apache-spark,dependencies,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.

一般说明: 我有两个项目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仅在更新版本的spark mllib中可用。从项目A(使用旧版本的spark mllib)开始,我只能访问org.apache.spark.mllib.regression.LabeledPoint。因此,如果不升级项目A的spark mllib版本,我无法直接将XGBOOST集成到项目A中

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

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

我不熟悉maven是如何处理依赖关系的,但我想到了类似这样的事情:

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

当然,我试过这么做。但它不起作用。我认为这是因为我们在整个依赖关系树中只能有一个版本的spark mllib。由于ProjectB中的类抛出
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很大,如果我升级那个版本,我几乎把一切都搞砸了

[更新] 我甚至尝试使用类加载器(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());
URLClassLoader clsLoader=URLClassLoader.newInstance(新URL[]{
新网址(“file:///home/myhome/spark-mllib_2.11-2.3.0.jar") 
});
类cls=clsLoader.loadClass(“org.apache.spark.mllib.regression.LabeledPoint”);
方法[]m=cls.getDeclaredMethods();
对于(int i=0;i
在该项目的my.pom文件中,如果我添加了以下依赖项:

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

org.apache.spark
spark-mllib_2.11
2.3.0
如果我使用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中。这有点奇怪。

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

spark mllib的较旧和较新的具体版本分别是1.6.2和2.x.x。更准确地说,请使用包名的重新定位项目B中常见的jar。感谢您的回答!嗯,我试着重新定位spark mllib的包。例如,对于org.apache.spark.ml.feature.LabeledPoint,我们现在有org.shade.apache.spark.ml.feature.LabeledPoint。但问题是,现在asML()方法返回org.shade.apache.spark.ml.feature.LabeledPoint(由于重新定位,重写字节码)。但是XGBoost API需要org.apache.spark.ml.feature.LabeledPoint。一切都搞砸了。更不用说关于依赖关系的其他问题了。我想这是不可能的。。。