2014-12-24 49 views
5

我的环境概述: 的Mac OS的优胜美地,播放框架2.3.7,SBT 0.13.7,IntelliJ IDEA的14,JAVA 1.8.0_25如何包括生产模式播放框架文件

我试着运行游戏框架简单的星火计划,所以我只是在创建一个的IntelliJ播放2项目,并改变一些文件如下:

应用程序/控制器/ 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)) 
    } 

} 

应用程序/ 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 
    } 
} 

公共/数据/ array.txt:

1 2 3 4 5 6 7 

的conf /路线:

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") 

I型activator run运行此应用程序在开发模式下,然后在浏览器中键入localhost:9000/spark,它显示结果28如预期。然而,当我想输入activator start运行此应用在生产模式下,它显示了以下错误消息:

[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] 

看来,我array.txt文件没有生产方式装入。如何解决这个问题?

+0

尝试将该文件置于conf目录下 –

回答

9

这里的问题是,当您在生产环境中运行时,public目录在您的根项目目录中不可用。它被打包成一个罐子(通常在STAGE_DIR/lib/PROJ_NAME-VERSION-assets.jar),所以你将无法以这种方式访问​​它们。

我可以在这里看到两种解决方案:

1)将在conf目录中的文件。这会起作用,但是如果你打算使用更多的数据文件,看起来很肮脏;

2)将这些文件放在某个目录中,并告诉sbt将它打包。您可以继续使用public目录,尽管使用不同的目录似乎更好,尤其是如果您想要更多文件。

假设array.txt被放置在一个项目中的根命名datafiles目录,你可以添加这build.sbt

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

不要忘记改变你的应用程序的代码路径:

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

然后只要做一个干净的,当你运行start,stagedist这些文件将可用。

+0

谢谢。我试过你的第二种方法,它的工作原理。但是我很好奇是什么让'public'目录如此特别?是否有任何配置文件可以控制是否应该在生产模式下打包目录? – user3684014

+0

Activator在底层使用sbt,sbt使用[native packager](http://www.scala-sbt.org/sbt-native-packager/index.html),这是第二种方法正在使用的内容。我不认为Play有特定的事情来处理这种情况 – Salem