2014-12-24 19 views
5

Tổng quan về môi trường của tôi: Mac OS Yosemite, Play khuôn khổ 2.3.7, SBT 0.13.7, IntelliJ IDEA 14, java 1.8.0_25Làm thế nào để bao gồm tập tin trong chế độ sản xuất cho khung Chơi

Tôi cố gắng để chạy một chương trình đơn giản Spark trong khuôn khổ play, vì vậy tôi chỉ cần tạo một dự án Chơi 2 trong Intellij, và thay đổi một số file như sau:

app/controllers/Application.scala:

package controllers 

import play.api._ 
import play.api.libs.iteratee.Enumerator 
import play.api.mvc._ 

object Application extends Controller { 

    def index = Action { 
    Ok(views.html.index("Your new application is ready.")) 
    } 

    def trySpark = Action { 
    Ok.chunked(Enumerator(utils.TrySpark.runSpark)) 
    } 

} 

app/utils/TrySpark.scala:

package utils 

import org.apache.spark.{SparkContext, SparkConf} 

object TrySpark { 
    def runSpark: String = { 
    val conf = new SparkConf().setAppName("trySpark").setMaster("local[4]") 
    val sc = new SparkContext(conf) 
    val data = sc.textFile("public/data/array.txt") 
    val array = data.map (line => line.split(' ').map(_.toDouble)) 
    val sum = array.first().reduce((a, b) => a + b) 
    return sum.toString 
    } 
} 

công cộng/data/array.txt:

1 2 3 4 5 6 7 

conf/tuyến:

GET  /     controllers.Application.index 

GET  /spark    controllers.Application.trySpark 

GET  /assets/*file  controllers.Assets.at(path="/public", file) 

build.sbt:

name := "trySpark" 

version := "1.0" 

lazy val `tryspark` = (project in file(".")).enablePlugins(PlayScala) 

scalaVersion := "2.10.4" 

libraryDependencies ++= Seq(jdbc , anorm , cache , ws, 
"org.apache.spark" % "spark-core_2.10" % "1.2.0") 

unmanagedResourceDirectories in Test <+= baseDirectory (_ /"target/web/public/test") 

Tôi gõ activator run để chạy ứng dụng này trong chế độ phát triển, sau đó nhập localhost:9000/spark vào trình duyệt, nó hiển thị kết quả 28 như mong đợi. Tuy nhiên, khi tôi muốn gõ activator start để chạy ứng dụng này trong phương thức sản xuất nó cho thấy các thông báo lỗi sau:

[info] play - Application started (Prod) 
[info] play - Listening for HTTP on /0:0:0:0:0:0:0:0:9000 
[error] application - 

! @6kik15fee - Internal server error, for (GET) [/spark] -> 

play.api.Application$$anon$1: Execution exception[[InvalidInputException: Input path does not exist: file:/Path/to/my/project/target/universal/stage/public/data/array.txt]] 
    at play.api.Application$class.handleError(Application.scala:296) ~[com.typesafe.play.play_2.10-2.3.7.jar:2.3.7] 
    at play.api.DefaultApplication.handleError(Application.scala:402) [com.typesafe.play.play_2.10-2.3.7.jar:2.3.7] 
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:205) [com.typesafe.play.play_2.10-2.3.7.jar:2.3.7] 
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$14$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:202) [com.typesafe.play.play_2.10-2.3.7.jar:2.3.7] 
    at scala.runtime.AbstractPartialFunction.apply(AbstractPartialFunction.scala:33) [org.scala-lang.scala-library-2.10.4.jar:na] 
Caused by: org.apache.hadoop.mapred.InvalidInputException: Input path does not exist: file:/Path/to/my/project/target/universal/stage/public/data/array.txt 
    at org.apache.hadoop.mapred.FileInputFormat.listStatus(FileInputFormat.java:251) ~[org.apache.hadoop.hadoop-mapreduce-client-core-2.2.0.jar:na] 
    at org.apache.hadoop.mapred.FileInputFormat.getSplits(FileInputFormat.java:270) ~[org.apache.hadoop.hadoop-mapreduce-client-core-2.2.0.jar:na] 
    at org.apache.spark.rdd.HadoopRDD.getPartitions(HadoopRDD.scala:201) ~[org.apache.spark.spark-core_2.10-1.2.0.jar:1.2.0] 
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:205) ~[org.apache.spark.spark-core_2.10-1.2.0.jar:1.2.0] 
    at org.apache.spark.rdd.RDD$$anonfun$partitions$2.apply(RDD.scala:203) ~[org.apache.spark.spark-core_2.10-1.2.0.jar:1.2.0] 

Dường như tập tin array.txt của tôi không được tải trong phương thức sản xuất. Làm thế nào có thể giải quyết vấn đề này?

+0

cố gắng đặt tệp theo thư mục conf –

Trả lời

9

Sự cố ở đây là thư mục public sẽ không có sẵn trong thư mục dự án gốc của bạn khi bạn chạy trong sản xuất. Nó được đóng gói như một cái bình (thường là ở STAGE_DIR/lib/PROJ_NAME-VERSION-assets.jar) vì vậy bạn sẽ không thể truy cập chúng theo cách này.

tôi có thể thấy hai giải pháp ở đây:

1) Đặt các tập tin trong thư mục conf. Điều này sẽ làm việc, nhưng có vẻ rất bẩn đặc biệt là nếu bạn định sử dụng nhiều tập tin dữ liệu hơn;

2) Đặt các tệp đó vào một số thư mục và yêu cầu sbt cũng đóng gói nó. Bạn có thể tiếp tục sử dụng thư mục public mặc dù có vẻ tốt hơn khi sử dụng một thư mục khác, đặc biệt nếu bạn muốn có nhiều tệp hơn.

Giả array.txt được đặt trong một thư mục tên là datafiles ở gốc dự án của bạn, bạn có thể thêm video này vào build.sbt:

mappings in Universal ++= 
(baseDirectory.value/"datafiles" * "*" get) map 
    (x => x -> ("datafiles/" + x.getName)) 

Đừng quên thay đổi các đường dẫn trong mã ứng dụng của bạn:

// (...) 
val data = sc.textFile("datafiles/array.txt") 

Sau đó, chỉ cần làm sạch và khi bạn chạy start, stage hoặc dist những tệp đó sẽ có sẵn.

+0

Cảm ơn. Tôi đã thử cách tiếp cận thứ hai của bạn và nó hoạt động. Nhưng tôi tò mò điều gì làm cho thư mục 'public' trở nên đặc biệt? Có bất kỳ tệp cấu hình nào mà chúng tôi có thể kiểm soát liệu một thư mục có nên được đóng gói trong chế độ sản xuất không? – user3684014

+0

Activator sử dụng sbt dưới mui xe, và sbt sử dụng [gói bản địa] (http://www.scala-sbt.org/sbt-native-packager/index.html), đó là những gì đang được sử dụng trong phương pháp thứ hai. Tôi không nghĩ Play có một cái gì đó cụ thể để đối phó với trường hợp này – Salem

Các vấn đề liên quan