从另一个模块访问Scala私有类

时间:2015-01-13 02:52:39

标签: scala maven pom.xml

我有一个Scala / Spark项目(使用Maven构建),我想在其中执行以下操作。

我想修改org.apache.spark.mllib.recommendations.ALS,因此我已将该文件的源代码复制到我自己的包中:org.apache.spark.mllib.myrecommendations.ALS。但是,它依赖于org.apache.spark.util.Utils之类的某些类,它们被声明为private[spark]

我希望通过将我的代码放在org.apache.spark中,它可以访问私有成员。但它抱怨,也许是因为Spark是通过Maven模块导入的?我该如何解决这个问题?

以下是pom.xml如何导入spark-mllib:

    <dependency>
        <groupId>com.sparkjava</groupId>
        <artifactId>spark-core</artifactId>
        <version>2.0.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.spark</groupId>
        <artifactId>spark-mllib_2.10</artifactId>
        <version>1.1.0</version>
        <scope>provided</scope>
    </dependency>

以下是我遇到的错误消息示例:

error: variable checkpointDir in class SparkContext cannot be accessed in org.apache.spark.SparkContext
[WARNING]         if (sc.checkpointDir.isDefined && (iter % 3 == 0)) {
[WARNING]                ^

查看org.apache.spark.SparkContext的源代码,我看到checkpointDir被声明为org.apache.spark的私有:

private[spark] var checkpointDir: Option[String] = None

为什么我无法访问此成员,即使我的代码位于org.apache.spark.mllib.myrecommendation.ALS,org.apache.spark的子代?

2 个答案:

答案 0 :(得分:3)

它对我有用。

由于包是打开的,以你描述的方式添加它们是完全正常的(从密封的jar文件模数加载)。

一个简单的sbt项目,ALS.scala被修改为驻留在包recommendation2中(并修复了几个private[recommendation2])并导入org.apache.spark.mllib.recommendation.MatrixFactorizationModel

build.sbt:

scalaVersion := "2.10.3"

scalacOptions ++= Seq("-Xlint", "-deprecation")

libraryDependencies ++= Seq(
    "org.apache.spark" % "spark-core_2.10" % "1.2.0",
    "org.apache.spark" % "spark-mllib_2.10" % "1.2.0",
    "junit" % "junit" % "4.12" % "test"
)

然后

$ sbt compile
[info] Set current project to SparkHack (in build file:/home/apm/tmp/spark-hack/)
[info] Updating {file:/home/apm/tmp/spark-hack/}spark-hack...
[info] Resolving [snip]...
[info] Done updating.
[info] Compiling 1 Scala source to /home/apm/tmp/spark-hack/target/scala-2.10/classes...
[success] Total time: 22 s, completed Jan 19, 2015 9:10:03 AM

答案 1 :(得分:0)

请勿尝试以任何编程语言违反可见性和辅助功能规则。如果你真的需要在Spark源代码中改变它不适合的东西,那么安全的方法是:

  • 克隆源代码
  • 应用修改
  • 在您当地的Maven存储库中构建和发布(更改工件标识符中的内容)
  • 更新您的pom.xml以引用您已创建的新版本

Spark测试作为构建的一部分执行,并且希望如果您的修改引入了bug,您将发现它,因为测试失败。