Validate functionality of different JSR-223 providers in UDFs.

patch by Robert Stupp; reviewed by Mikhail Stepura for CASSANDRA-7874
This commit is contained in:
Robert Stupp 2014-11-26 12:51:37 -08:00 committed by Mikhail Stepura
parent c5cec00462
commit e13121318b
11 changed files with 286 additions and 0 deletions

12
.gitignore vendored
View File

@ -57,3 +57,15 @@ target/
*.tmp
.DS_Store
Thumbs.db
# JSR223
lib/jsr223/clojure/*.jar
lib/jsr223/groovy/*.jar
lib/jsr223/jaskell/*.jar
lib/jsr223/jruby/*.jar
lib/jsr223/jruby/jni
lib/jsr223/jruby/ruby
lib/jsr223/jython/*.jar
lib/jsr223/jython/cachedir
lib/jsr223/scala/*.jar

View File

@ -85,6 +85,29 @@ goto :eof
REM -----------------------------------------------------------------------------
:okClasspath
REM JSR223 - collect all JSR223 engines' jars
for /D %%P in ("%CASSANDRA_HOME%\lib\jsr223\*.*") do (
for %%i in ("%%P\*.jar") do call :append "%%i"
)
REM JSR223/JRuby - set ruby lib directory
if EXIST "%CASSANDRA_HOME%\lib\jsr223\jruby\ruby" (
set JAVA_OPTS=%JAVA_OPTS% "-Djruby.lib=%CASSANDRA_HOME%\lib\jsr223\jruby"
)
REM JSR223/JRuby - set ruby JNI libraries root directory
if EXIST "%CASSANDRA_HOME%\lib\jsr223\jruby\jni" (
set JAVA_OPTS=%JAVA_OPTS% "-Djffi.boot.library.path=%CASSANDRA_HOME%\lib\jsr223\jruby\jni"
)
REM JSR223/Jython - set python.home system property
if EXIST "%CASSANDRA_HOME%\lib\jsr223\jython\jython.jar" (
set JAVA_OPTS=%JAVA_OPTS% "-Dpython.home=%CASSANDRA_HOME%\lib\jsr223\jython"
)
REM JSR223/Scala - necessary system property
if EXIST "%CASSANDRA_HOME%\lib\jsr223\scala\scala-compiler.jar" (
set JAVA_OPTS=%JAVA_OPTS% "-Dscala.usejavacp=true"
)
REM Include the build\classes\main directory so it works in development
set CASSANDRA_CLASSPATH=%CLASSPATH%;"%CASSANDRA_HOME%\build\classes\main";"%CASSANDRA_HOME%\build\classes\thrift"
set CASSANDRA_PARAMS=-Dcassandra -Dcassandra-foreground=yes

View File

@ -49,5 +49,26 @@ set CASSANDRA_CLASSPATH=%CLASSPATH%;"%CASSANDRA_HOME%\build\classes\main";%CASSA
REM Add the default storage location. Can be overridden in conf\cassandra.yaml
set CASSANDRA_PARAMS=%CASSANDRA_PARAMS% "-Dcassandra.storagedir=%CASSANDRA_HOME%\data"
REM JSR223 - collect all JSR223 engines' jars
for /r %%P in ("%CASSANDRA_HOME%\lib\jsr223\*.jar") do (
set CLASSPATH=%CLASSPATH%;%%~fP
)
REM JSR223/JRuby - set ruby lib directory
if EXIST "%CASSANDRA_HOME%\lib\jsr223\jruby\ruby" (
set JAVA_OPTS=%JAVA_OPTS% "-Djruby.lib=%CASSANDRA_HOME%\lib\jsr223\jruby"
)
REM JSR223/JRuby - set ruby JNI libraries root directory
if EXIST "%CASSANDRA_HOME%\lib\jsr223\jruby\jni" (
set JAVA_OPTS=%JAVA_OPTS% "-Djffi.boot.library.path=%CASSANDRA_HOME%\lib\jsr223\jruby\jni"
)
REM JSR223/Jython - set python.home system property
if EXIST "%$CASSANDRA_HOME%\lib\jsr223\jython\jython.jar" (
set JAVA_OPTS=%JAVA_OPTS% "-Dpython.home=%CASSANDRA_HOME%\lib\jsr223\jython"
)
REM JSR223/Scala - necessary system property
if EXIST "$CASSANDRA_HOME\lib\jsr223\scala\scala-compiler.jar" (
set JAVA_OPTS=%JAVA_OPTS% "-Dscala.usejavacp=true"
)
REM Add the sigar-bin path to the java.library.path CASSANDRA-7838
set JAVA_OPTS=%JAVA_OPTS% -Djava.library.path=%CASSANDRA_HOME%\lib\sigar-bin"

View File

@ -44,6 +44,27 @@ for jar in "$CASSANDRA_HOME"/lib/*.jar; do
CLASSPATH="$CLASSPATH:$jar"
done
# JSR223 - collect all JSR223 engines' jars
for jsr223jar in "$CASSANDRA_HOME"/lib/jsr223/*/*.jar; do
CLASSPATH="$CLASSPATH:$jsr223jar"
done
# JSR223/JRuby - set ruby lib directory
if [ -d "$CASSANDRA_HOME"/lib/jsr223/jruby/ruby ] ; then
export JVM_OPTS="$JVM_OPTS -Djruby.lib=$CASSANDRA_HOME/lib/jsr223/jruby"
fi
# JSR223/JRuby - set ruby JNI libraries root directory
if [ -d "$CASSANDRA_HOME"/lib/jsr223/jruby/jni ] ; then
export JVM_OPTS="$JVM_OPTS -Djffi.boot.library.path=$CASSANDRA_HOME/lib/jsr223/jruby/jni"
fi
# JSR223/Jython - set python.home system property
if [ -f "$CASSANDRA_HOME"/lib/jsr223/jython/jython.jar ] ; then
export JVM_OPTS="$JVM_OPTS -Dpython.home=$CASSANDRA_HOME/lib/jsr223/jython"
fi
# JSR223/Scala - necessary system property
if [ -f "$CASSANDRA_HOME"/lib/jsr223/scala/scala-compiler.jar ] ; then
export JVM_OPTS="$JVM_OPTS -Dscala.usejavacp=true"
fi
# set JVM javaagent opts to avoid warnings/errors
if [ "$JVM_VENDOR" != "OpenJDK" -o "$JVM_VERSION" \> "1.6.0" ] \
|| [ "$JVM_VERSION" = "1.6.0" -a "$JVM_PATCH_VERSION" -ge 23 ]

View File

@ -196,6 +196,42 @@ Function CalculateHeapSizes
}
}
#-----------------------------------------------------------------------------
Function SetJsr223Env
{
$cp = """$env:CLASSPATH"""
foreach ($jsrDir in Get-ChildItem -Path "$env:CASSANDRA_HOME\lib\jsr223")
{
foreach ($file in Get-ChildItem -Path "$env:CASSANDRA_HOME\lib\jsr223\$jsrDir\*.jar")
{
$file = $file -replace "\\", "/"
$cp = $cp + ";" + """$file"""
}
}
$env:CLASSPATH=$cp
# JSR223/JRuby - set ruby lib directory
if (Test-Path "$env:CASSANDRA_HOME\lib\jsr223\jruby\ruby")
{
$env:CASSANDRA_PARAMS=$env:CASSANDRA_PARAMS + " -Djruby.lib=$env:CASSANDRA_HOME\lib\jsr223\jruby"
}
# JSR223/JRuby - set ruby JNI libraries root directory
if (Test-Path "$env:CASSANDRA_HOME\lib\jsr223\jruby\jni")
{
$env:CASSANDRA_PARAMS=$env:CASSANDRA_PARAMS + " -Djffi.boot.library.path=$env:CASSANDRA_HOME\lib\jsr223\jruby\jni"
}
# JSR223/Jython - set python.home system property
if (Test-Path "$env:CASSANDRA_HOME\lib\jsr223\jython\jython.jar")
{
$env:CASSANDRA_PARAMS=$env:CASSANDRA_PARAMS + " -Dpython.home=$env:CASSANDRA_HOME\lib\jsr223\jython"
}
# JSR223/Scala - necessary system property
if (Test-Path "$env:CASSANDRA_HOME\lib\jsr223\scala\scala-compiler.jar")
{
$env:CASSANDRA_PARAMS=$env:CASSANDRA_PARAMS + " -Dscala.usejavacp=true"
}
}
#-----------------------------------------------------------------------------
Function ParseJVMInfo
{
@ -276,6 +312,7 @@ Function SetCassandraEnvironment
SetCassandraMain
BuildClassPath
SetJsr223Env
# Override these to set the amount of memory to allocate to the JVM at
# start-up. For production use you may wish to adjust this for your

View File

@ -0,0 +1,8 @@
Apache Cassandra User-Defined-Functions JSR 223 scripting
=========================================================
Unfortunately the JSR-223 support provided by the project https://github.com/ato/clojure-jsr223
and the related ones do not provide compileable script support.
The JSR-223 javax.script.Compilable implementation takes source file names or readers but not script sources
as all other JSR-223 implementations do.

View File

@ -0,0 +1,35 @@
Apache Cassandra User-Defined-Functions JSR 223 scripting
=========================================================
Using JSR-223 capable Groovy
Tested with version 2.3.6
Installation
------------
1. Download Groovy binary release
2. Unpack the downloaded archive into a temporary directory
3. Copy the jar groovy-all-2.3.6-indy.jar from the Groovy embeddable directory to $CASSANDRA_HOME/lib/jsr223/groovy
"indy" means "invokedynamic" and is a JVM instruction for scripting languages new to Java 7.
4. Restart your Cassandra daemon if it's already running
Cassandra log should contain a line like this:
INFO 10:49:45 Found scripting engine Groovy Scripting Engine 2.0 - Groovy 2.3.6 - language names: [groovy, Groovy]
Such a line appears when you already have scripted UDFs in your system or add a scripted UDF for the first time (see below).
Smoke Test
----------
To test Groovy functionality, open cqlsh and execute the following command:
CREATE OR REPLACE FUNCTION foobar ( input text ) RETURNS text LANGUAGE groovy AS 'return "foo";' ;
If you get the error
code=2200 [Invalid query] message="Invalid language groovy for 'foobar'"
Groovy for Apache Cassandra has not been installed correctly.
Notes / Java7 invokedynamic
---------------------------
Groovy provides jars that support invokedynamic bytecode instruction. These jars are whose ending with
"-indy.jar".

View File

@ -0,0 +1,5 @@
Apache Cassandra User-Defined-Functions JSR 223 scripting
=========================================================
Unfortunately Jaskell JSR-223 support is quite old and the Jaskell engine seems to be quite
unsupported. If you find a solution, please open a ticket at Apache Cassandra JIRA.

View File

@ -0,0 +1,54 @@
Apache Cassandra User-Defined-Functions JSR 223 scripting
=========================================================
Using JSR-223 capable JRuby
Tested with version 1.7.15
Installation
------------
1. Download JRuby binary release
2. Unpack the downloaded archive into a temporary directory
3. Copy everything from the JRuby lib directory to $CASSANDRA_HOME/lib/jsr223/jruby
4. Restart your Cassandra daemon if it's already running
Cassandra log should contain a line like this:
INFO 10:29:03 Found scripting engine JSR 223 JRuby Engine 1.7.15 - ruby jruby 1.7.15 - language names: [ruby, jruby]
Such a line appears when you already have scripted UDFs in your system or add a scripted UDF for the first time (see below).
Smoke Test
----------
To test JRuby functionality, open cqlsh and execute the following command:
CREATE OR REPLACE FUNCTION foobar ( input text ) RETURNS text LANGUAGE ruby AS 'return "foo";' ;
If you get the error
code=2200 [Invalid query] message="Invalid language ruby for 'foobar'"
JRuby for Apache Cassandra has not been installed correctly.
Ruby require/include
--------------------
You can use Ruby require and include in your scripts as in the following example:
CREATE OR REPLACE FUNCTION foobar ( input text ) RETURNS text LANGUAGE ruby AS '
require "bigdecimal"
require "bigdecimal/math"
include BigMath
a = BigDecimal((PI(100)/2).to_s)
return "foo " + a.to_s;
' ;
Notes / Java7 invokedynamic
---------------------------
See JRuby wiki pages https://github.com/jruby/jruby/wiki/ConfiguringJRuby and
https://github.com/jruby/jruby/wiki/PerformanceTuning for more information and optimization tips.

View File

@ -0,0 +1,33 @@
Apache Cassandra User-Defined-Functions JSR 223 scripting
=========================================================
Using JSR-223 capable Jython
Tested with version 2.3.5
Installation
------------
1. Download Jython binary release
2. Unpack the downloaded archive into a temporary directory
3. Copy the jar jython.jar from the Jython directory to $CASSANDRA_HOME/lib/jsr223/jython
4. Restart your Cassandra daemon if it's already running
Cassandra log should contain a line like this:
INFO 10:58:18 Found scripting engine jython 2.5.3 - python 2.5 - language names: [python, jython]
Such a line appears when you already have scripted UDFs in your system or add a scripted UDF for the first time (see below).
Smoke Test
----------
To test Jython functionality, open cqlsh and execute the following command:
CREATE OR REPLACE FUNCTION foobar ( input text ) RETURNS text LANGUAGE python AS '''foo''' ;
If you get the error
code=2200 [Invalid query] message="Invalid language python for 'foobar'"
Jython for Apache Cassandra has not been installed correctly.
Notes / Java7 invokedynamic
---------------------------
Jython currently targets Java6 only. They want to switch to Java7 + invokedynamic in Jython 3.

View File

@ -0,0 +1,37 @@
Apache Cassandra User-Defined-Functions JSR 223 scripting
=========================================================
Using JSR-223 capable Scala
Tested with version 2.11.2
Installation
------------
1. Download Scala binary release
2. Unpack the downloaded archive into a temporary directory
3. Copy the following jars from the Scala lib directory to $CASSANDRA_HOME/lib/jsr223/scala
scala-compiler.jar
scala-library.jar
scala-reflect.jar
4. Restart your Cassandra daemon if it's already running
Cassandra log should contain a line like this:
INFO 11:42:35 Found scripting engine Scala Interpreter 1.0 - Scala version 2.11.2 - language names: [scala]
Such a line appears when you already have scripted UDFs in your system or add a scripted UDF for the first time (see below).
Smoke Test
----------
To test Scala functionality, open cqlsh and execute the following command:
CREATE OR REPLACE FUNCTION foobar ( input text ) RETURNS text LANGUAGE scala AS 'return "foo";' ;
If you get the error
code=2200 [Invalid query] message="Invalid language scala for 'foobar'"
Scala for Apache Cassandra has not been installed correctly.
Notes / Java7 invokedynamic
---------------------------
Scala 2.10 has Java6 support only. 2.11 has experimental invokedynamic support (use at your own risk!).
2.12 introduces an upgrade directly to Java8 - see https://stackoverflow.com/questions/14285894/advantages-of-scala-emitting-bytecode-for-the-jvm-1-7