Scala作为shell脚本:类路径上的jar

时间:2011-11-24 09:25:09

标签: scala jar

您可以将scala脚本作为linux shell脚本运行:

#!/bin/sh
exec scala "$0" "$@"
!#

println("Hello")

在一个这样的脚本中,我需要从一组jar中加载类(它们恰好与脚本位于同一目录中)。如果这是REPL,我可以使用:jar,但这在脚本模式下不可用。

我正在尝试设置-classpath参数:

#!/bin/sh
exec scala -classpath '.:./*.jar' "$0" "$@"
!#

import javax.media.jai.{JAI, RenderedOp}

但是编译器找不到类:

error: object media is not a member of package javax
import javax.media.jai.{JAI, RenderedOp}
             ^

如何加入这些罐子?

7 个答案:

答案 0 :(得分:10)

exec scala -classpath ./*.jar $0 $@

将起作用

答案 1 :(得分:9)

由于某种原因,glob(*.jar)无效。我能够通过手工放入所有库来运行脚本:

#!/bin/sh
exec scala -cp lib/jai_codec.jar:lib/jai_core.jar:lib/mlibwrapper_jai.jar $0 $@
!#

import javax.media.jai.{JAI, RenderedOp}

我不知道为什么为什么不能使用glob。

请注意,在这种情况下,我在类路径中没有.,因为脚本本身是作为参数提供的。在许多情况下,您需要包含它:

exec scala -cp .:lib/jai_codec.jar:lib/jai_core.jar:lib/mlibwrapper_jai.jar $0 $@

基于this helpful post,我有一个脚本标题,可以拉入lib文件夹中的每个jar,即使脚本(或它所在的文件夹)是符号链接。

#!/bin/sh
L=`readlink -f $0`
L=`dirname $L`/lib
cp=`echo $L/*.jar|sed 's/ /:/g'`
/usr/bin/env scala -classpath $cp $0 $@
exit
!#
  • 第一行将给定的脚本位置$0转换为磁盘上的实际位置,扩展了符号链接。
  • 第二行删除脚本名称并添加/lib
  • 第三行创建一个cp变量,其中所有广告字符由:
  • 分隔
  • 第四行运行scala,无论它在哪里。
  • 第五行退出。这可能不是必要的,但它让我感觉更好。

答案 2 :(得分:4)

我建议您使用SBT来处理它。请参阅scripts wiki,其中说明了如何执行以下操作:

#!/usr/bin/env scalas
!#

/***
scalaVersion := "2.9.0-1"

libraryDependencies ++= Seq(
  "net.databinder" %% "dispatch-twitter" % "0.8.3",
  "net.databinder" %% "dispatch-http" % "0.8.3"
)
*/

import dispatch.{ json, Http, Request }
import dispatch.twitter.Search
import json.{ Js, JsObject }

def process(param: JsObject) = {
  val Search.text(txt)        = param
  val Search.from_user(usr)   = param
  val Search.created_at(time) = param

  "(" + time + ")" + usr + ": " + txt
}

Http.x((Search("#scala") lang "en") ~> (_ map process foreach println))

答案 3 :(得分:1)

http://www.scalaclass.com/node/10 这应该适合你。我只是根据它来修复依赖。

答案 4 :(得分:0)

您还可以在类路径中使用glob放置单引号,如下所示:

exec scala -classpath '.:*.jar' "$0" "$@"

答案 5 :(得分:0)

为了避免在每个头中定义类路径定义,您可以定义一个函数,该函数将您的scala可执行文件包装在(例如).bashrc中,并使其可以访问外部作用域:

...
function scala() {

    PARAMS=( "$@" )

    FILENAME=${PARAMS[0]}
    REMAINING_PARAMS=(${PARAMS[@]:1:${#PARAMS[@]}})

    CUSTOM_CLASSPATH_DEF=".:/whatever/*"
    /path/to/scala -cp "$CUSTOM_CLASSPATH_DEF" -Dscala.color=true "$FILENAME" "${REMAINING_PARAMS[@]}"
}

export -f scala 
...

现在您可以将标题定义为:

#!/bin/bash
scala "$0" "$@"
exit 0
!#

(你仍然可以使用REPL从命令行输入'scala')

答案 6 :(得分:0)

以下内容适用于Cygwin

<object>