GraphX-加权最短路径实现-java.lang.NoSuchMethodError

GraphX-加权最短路径实现-java.lang.NoSuchMethodError,java,scala,apache-spark,spark-graphx,Java,Scala,Apache Spark,Spark Graphx,编辑-我发现这本书是为scala1.6编写的,但剩下的是2.11 我正在尝试实现Michael Malak和Robin East的Spark GraphX in Actionbook中的加权最短路径算法。所讨论的部分是第6章中的清单6.4“执行使用面包屑的最短路径算法” 我有我自己的图形,我从两个RDD创建。有344436顶点和772983边。我可以使用本机GraphX库执行未加权最短路径计算,我对图形构造很有信心 在本例中,我使用他们的Dijkstra实现,如下所示: val my_graph

编辑-我发现这本书是为scala
1.6
编写的,但剩下的是
2.11

我正在尝试实现Michael Malak和Robin East的Spark GraphX in Actionbook中的加权最短路径算法。所讨论的部分是第6章中的清单6.4“执行使用面包屑的最短路径算法”

我有我自己的图形,我从两个RDD创建。有
344436
顶点和
772983
边。我可以使用本机GraphX库执行未加权最短路径计算,我对图形构造很有信心

在本例中,我使用他们的Dijkstra实现,如下所示:

val my_graph: Graph[(Long),Double] = Graph.apply(verticesRDD, edgesRDD).cache()

def dijkstra[VD](g:Graph[VD,Double], origin:VertexId) = {
  var g2 = g.mapVertices(
      (vid,vd) => (false, if (vid == origin) 0 else Double.MaxValue, List[VertexId]())
  )

  for (i <- 1L to g.vertices.count-1) {
    val currentVertexId = g2.vertices
      .filter(!_._2._1)
      .fold((0L, (false, Double.MaxValue, List[VertexId]())))(
          (a,b) => if (a._2._2 < b._2._2) a else b)
      )
      ._1

    val newDistances = g2.aggregateMessages[(Double, List[VertexId])](
        ctx => if (ctx.srcId == currentVertexId) {
          ctx.sendToDst((ctx.srcAttr._2 + ctx.attr, ctx.srcAttr._3 :+ ctx.srcId))
        },
        (a,b) => if (a._1 < b._1) a else b
    )

    g2 = g2.outerJoinVertices(newDistances)((vid, vd, newSum) => {
      val newSumVal = newSum.getOrElse((Double.MaxValue,List[VertexId]()))

      (
          vd._1 || vid == currentVertexId,
          math.min(vd._2, newSumVal._1),
          if (vd._2 < newSumVal._1) vd._3 else newSumVal._2
      )
    })

  }

  g.outerJoinVertices(g2.vertices)((vid, vd, dist) =>
    (vd, dist.getOrElse((false,Double.MaxValue,List[VertexId]()))
      .productIterator.toList.tail
  ))
}

//  Path Finding - random node from which to find all paths
val v1 = 4000000028222916L
但是,这将返回以下内容:

Error: Exception in thread "main" java.lang.NoSuchMethodError: scala.runtime.ObjectRef.create(Ljava/lang/Object;)Lscala/runtime/ObjectRef;
    at GraphX$.dijkstra$1(GraphX.scala:51)
    at GraphX$.main(GraphX.scala:85)
    at GraphX.main(GraphX.scala)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731)
    at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181)
    at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206)
    at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121)
    at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
第51行是指
var g2=g.mapVertices(
第85行是指行
val results=dijkstra(我的图,1L).vertices.map(u._2).collect

此异常指的是什么方法?我可以使用
sbt
打包,没有错误,我看不出我调用的方法是什么,因为不存在该方法。

错误分析: 请查看错误:

Exception in thread "main" java.lang.NoSuchMethodError: scala.runtime.ObjectRef.create
您的程序正在寻找
create()
方法,但没有找到该方法

根本原因分析: 实际上,当scala和spark之间的版本不匹配时,就会发生这种类型的错误

或,

编译由一个版本完成,在运行时使用另一个scala版本


Scala版本差异:

如果选中,Scala 2.10.x版

您将获得,
ObjectRef
class have

public T elem;
public ObjectRef(T elem) { this.elem = elem; }
public String toString() { return String.valueOf(elem); }
public T elem;
public ObjectRef(T elem) { this.elem = elem; }
@Override
public String toString() { return String.valueOf(elem); }

public static <U> ObjectRef<U> create(U e) { return new ObjectRef<U>(e); } // Your program wants to get this method, but not getting this.
public static ObjectRef<Object> zero() { return new ObjectRef<Object>(null); }

但如果您选中,Scala 2.11.x版

您将获得,
ObjectRef
class have

public T elem;
public ObjectRef(T elem) { this.elem = elem; }
public String toString() { return String.valueOf(elem); }
public T elem;
public ObjectRef(T elem) { this.elem = elem; }
@Override
public String toString() { return String.valueOf(elem); }

public static <U> ObjectRef<U> create(U e) { return new ObjectRef<U>(e); } // Your program wants to get this method, but not getting this.
public static ObjectRef<Object> zero() { return new ObjectRef<Object>(null); }
公共元素;
public ObjectRef(T elem){this.elem=elem;}
@凌驾
公共字符串toString(){return String.valueOf(elem);}
publicstaticobjectrefcreate(ue){returnnewobjectref(e);}//您的程序想要得到这个方法,但没有得到这个方法。
公共静态ObjectRef zero(){返回新的ObjectRef(null);}
create()
方法在此处可用


解决方案#1: 所以,请确认,编译和运行时,他们是从同一版本的Scala

解决方案#2: 请检查:

在这里,在这个评论里也讲过这样的话

Spark 1.6基于Scala 2.10而不是2.11

因此,您可以从这里更新Spark版本


最新稳定版本是Apache Spark 2.0.1,于2016年10月3日发布

问题不在于版本错误,也不在于缺少实现,而在于编译器的错误误导

好的,事情是这样的:在研究代码之后,我注意到以下部分包含一个额外的右括号:

val currentVertexId: VertexId = g2.vertices.filter(!_._2._1)
  .fold((0L, (false, Double.MaxValue, List[VertexId]())))(
    (a, b) => if (a._2._2 < b._2._2) a else b))._1 
                                              ^
                                              |
val currentVertexId:VertexId=g2.Vertexs.filter(!\uu2.\u1)
.fold((0L,(false,Double.MaxValue,List[VertexId]()))(
(a,b)=>如果(a._2._2
你只需要去掉那个额外的括号,它就会工作得很好。以下是完整的代码:

// scala> :pa
// Entering paste mode (ctrl-D to finish)

import org.apache.spark.graphx._
def dijkstra[VD](g: Graph[VD, Double], origin: VertexId) = {
  var g2 = g.mapVertices(
(vid, vd) => (false, if (vid == origin) 0 else Double.MaxValue, List[VertexId]())
  )

  for (i <- 1L to g.vertices.count - 1) {
    val currentVertexId: VertexId = g2.vertices.filter(!_._2._1)
      .fold((0L, (false, Double.MaxValue, List[VertexId]())))(
        (a, b) => if (a._2._2 < b._2._2) a else b)._1

    val newDistances: VertexRDD[(Double, List[VertexId])] =
      g2.aggregateMessages[(Double, List[VertexId])](
    ctx => if (ctx.srcId == currentVertexId) {
      ctx.sendToDst((ctx.srcAttr._2 + ctx.attr, ctx.srcAttr._3 :+ ctx.srcId))
    },
    (a, b) => if (a._1 < b._1) a else b
  )

g2 = g2.outerJoinVertices(newDistances)((vid, vd, newSum) => {
  val newSumVal = newSum.getOrElse((Double.MaxValue, List[VertexId]()))
  (
    vd._1 || vid == currentVertexId,
    math.min(vd._2, newSumVal._1),
    if (vd._2 < newSumVal._1) vd._3 else newSumVal._2
    )
})
}

  g.outerJoinVertices(g2.vertices)((vid, vd, dist) =>
(vd, dist.getOrElse((false, Double.MaxValue, List[VertexId]()))
  .productIterator.toList.tail
  ))
}

//  Path Finding - random node from which to find all paths
//scala>:pa
//进入粘贴模式(按ctrl-D键完成)
导入org.apache.spark.graphx_
def dijkstra[VD](g:Graph[VD,Double],原点:VertexId)={
var g2=g.mapVertices(
(vid,vd)=>(false,如果(vid==原点)0 else Double.MaxValue,列出[VertexId]())
)
对于(i if(a.\u 2.\u 2if(ctx.srcId==currentVertexId){
ctx.sendToDst((ctx.srcatr.\u 2+ctx.attr,ctx.srcatr.\u 3:+ctx.srcId))
},
(a,b)=>如果(a._1{
val newSumVal=newSum.getOrElse((Double.MaxValue,List[VertexId]())
(
vd.| 1 | vid==currentVertexId,
math.min(第2版,新闻版第1版),
如果(vd.\u 2
(vd,dist.getOrElse((false,Double.MaxValue,List[VertexId]())
.productIterator.toList.tail
))
}
//路径查找-从中查找所有路径的随机节点
现在,让我们测试一下:

val myVertices: RDD[(VertexId, String)] = sc.makeRDD(Array((1L, "A"), (2L, "B"), (3L, "C"), (4L, "D"), (5L, "E"), (6L, "F"), (7L, "G")))
val myEdges: RDD[Edge[Double]] = sc.makeRDD(Array(Edge(1L, 2L, 7.0), Edge(1L, 4L, 5.0), Edge(2L, 3L, 8.0), Edge(2L, 4L, 9.0), Edge(2L, 5L, 7.0), Edge(3L, 5L, 5.0), Edge(4L, 5L, 15.0), Edge(4L, 6L, 6.0),Edge(5L, 6L, 8.0), Edge(5L, 7L, 9.0), Edge(6L, 7L, 11.0)))

val my_graph = Graph(myVertices, myEdges).cache()

val v1 = 4000000028222916L

val results = dijkstra(my_graph, 1L).vertices.map(_._2).collect

// [CTRL-D]
// Exiting paste mode, now interpreting.
// [Lscala.Tuple2;@668a0785                                                        
// import org.apache.spark.graphx._
// myVertices: org.apache.spark.rdd.RDD[(org.apache.spark.graphx.VertexId, String)] = ParallelCollectionRDD[556] at makeRDD at <console>:37
// myEdges: org.apache.spark.rdd.RDD[org.apache.spark.graphx.Edge[Double]] = ParallelCollectionRDD[557] at makeRDD at <console>:39
// my_graph: org.apache.spark.graphx.Graph[String,Double] = org.apache.spark.graphx.impl.GraphImpl@49ea0d90
// dijkstra: [VD](g: org.apache.spark.graphx.Graph[VD,Double], origin: org.apache.spark.graphx.VertexId)org.apache.spark.graphx.Graph[(VD, List[Any]),Double]
// v1: Long = 4000000028222916
// results: Array[(String, List[Any])] = Array((A,List(0.0, List())), (B,List(7.0, List(1))), (C,List(15.0, Li...
scala> results.foreach(println)
// (A,List(0.0, List()))
// (B,List(7.0, List(1)))
// (C,List(15.0, List(1, 2)))
// (D,List(5.0, List(1)))
// (E,List(14.0, List(1, 2)))
// (F,List(11.0, List(1, 4)))
// (G,List(22.0, List(1, 4, 6)))
val myVertices:RDD[(VertexId,String)]=sc.makeRDD(数组((1L,“A”),(2L,“B”),(3L,“C”),(4L,“D”),(5L,“E”),(6L,“F”),(7L,“G”))
valmyedges:RDD[Edge[Double]=sc.makeRDD(数组(Edge(1L,2L,7.0),Edge(1L,4L,5.0),Edge(2L,3L,8.0),Edge(2L,4L,9.0),Edge(2L,5L,7.0),Edge(3L,5L,5.0),Edge(4L,6L,6.0),Edge(5L,6L,8.0),Edge(5L,7L,9.0),Edge(6L,7,11.0))
val my_graph=图形(myVertices,MyEdge).cache()
val v1=4000000028222916L
val results=dijkstra(我的图,1L).vertices.map(u._2).collect
//[CTRL-D]
//正在退出粘贴模式,现在正在解释。
//[Lscala.Tuple2;@668a0785
//导入org.apache.spark.graphx_
//myVertices:org.apache.spark.rdd.rdd[(org.apache.spark.graphx.VertexId,String)]=ParallelCollectionRDD[556]位于makeRDD:37
//myEdges:org.apache.spark.rdd.rdd[org.apache.spark.graphx.Edge[Double]=ParallelCollectionRDD[557]位于makeRDD:39
//my_graph:org.apache.spark.graphx.graph[String,Double]=org.apache.spark.graphx.impl。GraphImpl@49ea0d90
//dijkstra:[VD](g:org.apache.spark.graphx.Graph[VD,Double],来源:org.apache.spark.graphx.VertexId)org.apache.spark.graphx.Graph[(VD,List[Any]),Double]
//v1:Long=4000000028222916
//结果:Array[(String,List[Any])]=Array((A,List(0.0,List()),(B,List(7.0,List(1)),(C,List(15.0,Li.))。。。
scala>results.foreach(println)
//(A,List(0.0,List()))
//(B,列表(7.0,列表(1)))
//(C,列表(15.0,列表(1,2)))
//(D,清单(5.0,清单(1)))
//(E,清单(14.0,清单(1,2)))
//(F,列表(11.0,列表(1,4)))
// (