Scala как оболочка script: банки на пути к классам
Вы можете запустить scala script как оболочку linux script:
#!/bin/sh
exec scala "$0" "[email protected]"
!#
println("Hello")
В одном из таких script мне нужно загрузить классы из группы jars (которые находятся в том же каталоге, что и script). Если бы это был REPL, я мог бы использовать :jar
, но недоступный в режиме script.
Я пытаюсь установить параметр -classpath
:
#!/bin/sh
exec scala -classpath '.:./*.jar' "$0" "[email protected]"
!#
import javax.media.jai.{JAI, RenderedOp}
но компилятор просто не может найти классы:
error: object media is not a member of package javax
import javax.media.jai.{JAI, RenderedOp}
^
Как включить эти банки?
Ответы
Ответ 1
По какой-то причине glob (*.jar
) не работал. Мне удалось запустить script, поместив все библиотеки вручную:
#!/bin/sh
exec scala -cp lib/jai_codec.jar:lib/jai_core.jar:lib/mlibwrapper_jai.jar $0 [email protected]
!#
import javax.media.jai.{JAI, RenderedOp}
Я не знаю, почему glob не работает.
Обратите внимание, что в этом случае у меня нет .
в пути к классам, потому что сам script предоставляется в качестве аргумента. Во многих случаях, хотя вам нужно будет включить его:
exec scala -cp .:lib/jai_codec.jar:lib/jai_core.jar:lib/mlibwrapper_jai.jar $0 [email protected]
Основываясь на этом полезном сообщении, у меня есть заголовок script, который тянет каждую банку в папке lib
, даже если script (или его папка) являются символическими ссылками.
#!/bin/sh
L=`readlink -f $0`
L=`dirname $L`/lib
cp=`echo $L/*.jar|sed 's/ /:/g'`
/usr/bin/env scala -classpath $cp $0 [email protected]
exit
!#
- Первая строка превращает данное script местоположение
$0
в его фактическое местоположение на диске, расширяя символические ссылки.
- Вторая строка удаляет имя script и добавляет
/lib
- Третья строка создает переменную
cp
со всеми банками, разделенными :
- Четвертая строка работает scala, где бы она ни была.
- Пятая строка завершается. Возможно, это не обязательно, но мне становится легче.
Ответ 2
exec scala -classpath ./*.jar $0 [email protected]
будет работать
Ответ 3
Я рекомендую вам использовать SBT вместо этого. См. скрипты 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))
Ответ 4
http://www.scalaclass.com/node/10
Это должно сработать для вас. Я просто фиксирую зависимость в соответствии с ней.
Ответ 5
Вы также можете поместить одинарные кавычки вокруг пути к классам с помощью glob, например:
exec scala -classpath '.:*.jar' "$0" "[email protected]"
Ответ 6
Чтобы избежать определения определения пути к классам в каждом заголовке, вы можете определить функцию, которая обертывает ваш исполняемый файл scala в (например) ваш .bashrc и делает его видимым для внешней области:
...
function scala() {
PARAMS=( "[email protected]" )
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" "[email protected]"
exit 0
!#
(Вы все еще можете использовать REPL, набрав 'scala' из командной строки)