在SBT/Play中的构建定义内运行Java方法

在SBT/Play中的构建定义内运行Java方法,java,scala,playframework-2.0,sbt,Java,Scala,Playframework 2.0,Sbt,在SBT中我想要的是有一个输入任务,对于Play 2.2.1控制台中的fooabc,执行对Java(静态)方法的调用,将abc作为参数列表传递 游戏控制台:fooabc===应该调用==>foo.bar(a,b,c) 我有以下播放目录结构和文件(Java项目): myfolder.Foo package myfolder; public class Foo { public static void bar(String... args) { for(String s :

在SBT中我想要的是有一个输入任务,对于Play 2.2.1控制台中的
fooabc
,执行对Java(静态)方法的调用,将
abc
作为参数列表传递

游戏控制台:
fooabc===应该调用==>foo.bar(a,b,c)

我有以下播放目录结构和文件(Java项目):

myfolder.Foo

package myfolder;

public class Foo {
    public static void bar(String... args) {
        for(String s : args)
            System.out.println(s);
    }
}
project/build.scala

import sbt._
import Keys._
import play.Project._
import sbt.complete.Parsers._

object ApplicationBuild extends Build {

    val appName         = "myplayapp"
    val appVersion      = "1.0-SNAPSHOT"

    val appDependencies = Seq()

    val foo = inputKey[Unit]("Foo you.")

    val fooSettings = foo := {    
        val args: Seq[String] = spaceDelimited("<arg>").parsed          
        // Foo.bar(args)
    }

    val main = play.Project(appName, appVersion, appDependencies).settings(
        fooSettings    
    )
}
package myfolder;

public class Foo {
    public static void bar(String... args) {
        for(String s : args)
            System.out.println(s);
    }
}

有什么方法可以实现我想要的吗?

sbt实例的类路径与项目的类路径不同。如果是这样的话,那么如果出现编译错误,就不可能在sbt中启动您的项目,例如,因为它会创建依赖项,编译器必须首先编译您的项目文件才能编译Build.scala文件

为了能够在sbt中使用类,它们必须位于构建源代码中,这些类位于
project/
目录中。如果您将构建相关的java源代码放在project/下,那么sbt将在运行之前编译这些源代码,并且您将能够从sbt构建文件访问这些类


(这使得在sbt中定义特定于项目的插件成为可能,而在例如maven中,您必须将所有插件作为可通过依赖系统解决的工件提供)

因为您使用的是随附的Play 2.2.1,我将使用
build.sbt
。您应该能够轻松地将其迁移到自己的
ApplicationBuild
,因为这些更改相当美观

使用以下内容在Play应用程序的项目目录中创建
build.sbt

import sbt.complete.Parsers._
import myfolder.Foo

lazy val foo = inputKey[Unit]("Foo you.")

foo := {
  val args: Seq[String] = spaceDelimited("<arg>").parsed
  Foo.bar(args: _*)
}
请注意,由于您需要在构建定义中使用Java类(能够使用SBT中的参数执行任务),因此它必须是SBT构建的一部分,而不是您的Play项目(因此它位于
项目下
-请参阅)

当SBT shell启动时,使用任意数量的参数运行
foo
input任务:

[sbt-0-13-1]> foo2 ala ma kota
ala
ma
kota
[success] Total time: 0 s, completed Jan 21, 2014 12:00:46 AM

问题不在于
静态
。这很好:
import java.lang.String.format;格式化(“a%s c”,“b”)
为什么不在build.scala中创建一个scala方法呢
def foo(args:String*):Unit=args.foreach(println)
或类似的东西或任何表达式。您可以在编译、测试等过程中使用安装、清理步骤并插入此方法。@AlekseyIzmailov好吧……我只知道Java,我知道Java和Scala是可互操作的。我只是想知道如何做到这一点。我可能错了,但您必须单独编译Java类,并使其在SBT类路径上可见。SBT可以编译源代码的Java类,然后编译使用它们的Scala类。然而,我从未见过这样的功能。也许它就在那里。我可以按照你的步骤在游戏机中运行这个方法。我刚刚在
/myplayapp/project
中创建了一个
/src/main/java/myfolder/Foo.java
,它成功了。我不知道这是否是我需要完成的最佳playframework实践,但我现在会坚持下去。谢谢你,Jacek。我没有太多的SBT经验,所以我不知道这是否是一个好的实践。在这种情况下,我要说的是,不管其他选择如何,如果它们是未知的,我们知道的是最好的选择。不过,我似乎想不出更好的办法。
package myfolder;

public class Foo {
    public static void bar(String... args) {
        for(String s : args)
            System.out.println(s);
    }
}
[sbt-0-13-1]> foo2 ala ma kota
ala
ma
kota
[success] Total time: 0 s, completed Jan 21, 2014 12:00:46 AM