Classes • .... from Disk http://en.wikipedia.org/wiki/Java_performance#Startup_time “ It seems that much of the startup time is due to IO- bound operations rather than JVM initialization or class loading (the rt.jar class data file alone is 40 MB and the JVM must seek a lot of data in this huge file).
LASSPATH cm d line args stdin stdout stderr Ctrl-C other EN Vs ≪file≫ Authtoken exit status TCP/IP System .in System .out System .err groovyserver groovyclient GroovyServ
X (built at Mac OS X 10.8 (x86_64)) • Windows • bundled in Groovy Windows Installer • (built at WindowsXP (32bit) (x86)) • (built at Windows7 (64bit) (AMD64)) • Linux (i386) (linked with glibc 2.9) • Self-build (required Gradle) • Homebrew (only Mac) • $ brew install groovyserv • http://kobo.github.io/groovyserv/howtoinstall.html
'import clojure.main;main.main(args)' -‐-‐" $ glojureserver -‐r ... $ time glojure -‐e "(println 'Hello)" Hello real 0m0.053s user 0m0.001s sys 0m0.004s main method of closure.main class
a unit test • test-‐app unit: <FQCN of TestClass> • Run only a integration test • test-‐app integration: <FQCN of TestClass> • Run only a functional test • test-‐app functional: <FQCN of TestClass>
test, 0 failed in 546ms | Tests PASSED -‐ view reports in /xxx/test-‐reports real 0m7.303s user 0m18.068s sys 0m0.909s Lessthanahalfofprevioussample! Specifying a phase can avoid running an extra phase Without a phase: real 0m15.375s user 0m35.119s sys 0m1.858s
character is '^]'. help ...... Usage (optionals marked with *): grails [environment]* [options]* [target] [arguments]* ...(snipped)... uninstall-‐plugin upgrade war wrapper $
data converted based on a protocol into output stream of socket Hello, GroovyServ! if Channel header == ”err” To STDERR if Channel header == ”out” To STDOUT Client console
: 'Env:' <env1>=<value1> LF 'Env:' <env2>=<value2> LF : 'Cp:' <classpath> LF 'AuthToken:' <authToken> LF LF where: <cwd> is current working directory. <arg1>,<arg2>.. are commandline arguments which must be encoded by Base64. (optional) <env1>,<env2>.. are environment variable names which sent to the server. (optional) <value1>,<valeu2>.. are environment variable values which sent to the server. (optional) <classpath> is the value of environment variable CLASSPATH. (optional) <authToken> is authentication value which certify client is the user who invoked the server. LF is line feed (0x0a, '\n').
STDERR/STDOUT> where: <id> is 'out' or 'err', where 'out' means standard output of the program. 'err' means standard error of the program. <size> is the size of chunk. <body from STDERR/STDOUT> is byte sequence from standard output/error.
address is allowed. • Authtoken is generated and stored into a file when server process starts. • $HOME/.groovy/groovyserver/authtoken-‐<PORT> • Authtoken always is used for checking that the request is from valid owner user.
which a name includes specified substr • -‐Cenv-‐all • pass all environment variables • -‐Cenv-‐exclude <substr> • don't pass environment variables of which a name includes specified substr
cat test.txt Can you read me? $ groovyclient -e ‘println(new File(“test.txt”).text)’ Caught: java.io.FileNotFoundException: test.txt (No such file or directory) ...SNIP... ≪process≫ groovyserver CWD=/tmp I wanna use “test.txt” of current directory. Is it “/tmp/test.txt” ? Hmm, such a file not found.
File#getAbsolutePath() • Changing CWD of native JVM process • Many classes don’t use “user.dir” to complete an absolute path. • But, JNI is troublesome...
cat test.txt Can you read me? $ groovyclient -e ‘println(new File(“test.txt”).text)’ Can you read me? ≪process≫ groovyserver CWD=/tmp I wanna use “test.txt” of current directory. ≪process≫ groovyserver CWD=/home/nobeans Is it “/home/nobeans/test.txt” ? OK, I got it. Yes!