9. Why so slow?
• JVM initialization
• Loading Many Many 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).
14. groovyConsole
• Handy for trying Java/Groovy APIs, etc.
• But features as editor aren’t so rich:
• No code completion
• No syntax checking
• No auto import
• etc.
• I want to use my favorite IDE/editor!
18. $
time
groovyclient
-‐e
“println
‘Hello,
GroovyServ’”
Hello,
GroovyServ
real
0m0.031s
user
0m0.001s
sys
0m0.002s
Normal
Groovy:
real
0m0.823s
user
0m1.016s
sys
0m0.096s
19. Normal
Groovy User Groovy
Script
Shell Environment JavaVM
File System
C
LASSPATH
cm
d
line
args
stdinstdout
stderr
Ctrl-C
otherEN
Vs
exitstatus
System
.in
System
.out
System
.err
groovy
User Groovy
Script
20. Shell Environment
JavaVM
File System
User Groovy
Script
C
LASSPATH
cm
d
line
args
stdinstdout
stderr
Ctrl-C
otherEN
Vs
≪file≫
Authtoken
exitstatus
TCP/IP
System
.in
System
.out
System
.err
groovyservergroovyclient
GroovyServ
22. GroovyServ Way
• Write code with your favorite IDE/editor
• Run the code by using GroovyServ as
External Tool
• You can also see the result on a console
of IDE
27. How to Install
• Downloadable Binaries for
• Mac OS 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
28. No setting required
• If there is a binary set, you can use it:
• $
/xxx/groovyserv/bin/groovyclient
• Adding to PATH, you can easily use it:
• $
groovyclient
31. groovyclient
• Invokes a groovy file or one-liner code, by
sending a request to server
• Also invokes groovyserver process
automatically if not exists
32. groovyserver
• Invokes a JVM process as a server.
• Should be used only when you want to
specify special options.
• e.g.
• -‐v
verbose
option
• -‐-‐allow-‐from
for
remote
feature
33. Available for Other
JVM Languages
http://nobeans-en.blogspot.jp/2011/07/high-speed-start-up-
jythonclojure-by.html
34. Jython
$
alias
gythonserver="env
CLASSPATH=/your/jython.jar
groovyserver"
$
alias
gython="groovyclient
-‐e
'import
org.python.util.jython;
jython.main(args)'
-‐-‐"
$
gythonserver
-‐r
...
$
time
gython
-‐c
"print('Hello')"
Hello
real
0m0.057s
user
0m0.001s
sys
0m0.004s
35. Clojure
$
alias
glojureserver="env
CLASSPATH=/your/clojure.jar
groovyserver"
$
alias
glojure="groovyclient
-‐e
'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
36. • A script to get schedule data from
groupware
• As editor’s macro
• As mail filter
• etc.
Using at Runtime
37. Other Features
• Access Control
• Propagation of CLASSPATH
• Propagation of Environment Variables
• Handling System#exit()
• Dynamic CWD
44. How to run a specified test fast
• Run only 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>
46. If test phase not specified when run unit test,
integration phase is also run.
$
cat
test/unit/test/app/sample/FooTests.groovy
....
class
FooTests
{
void
testSomething()
{
//
do
nothing
}
}
$
time
grails
test-‐app
FooTests
|
Packaging
Grails
application.....
|
Tests
PASSED
-‐
view
reports
in
/xxx/test-‐reports
real
0m15.375s
user
0m35.119s
sys
0m1.858s
Oops!
50. $
time
grails
test-‐app
unit:
FooTests
|
Completed
1
unit
test,
0
failed
in
546ms
|
Tests
PASSED
-‐
view
reports
in
/xxx/test-‐reports
real
0m7.303s
user
0m18.068s
sys
0m0.909s
Less
59. How do you run a test while writing it?
• (A) By IDE support (GGTS, IntelliJ, etc.)
• (B) By “grails test-app” as standalone
• (C) By “grails test-app” via Interactive
Mode
• (D) Others
60. Interactive Mode
• Very very useful
• Makes command execution faster because
the JVM doesn't have to be restarted for
each command
• $
grails
• TAB completion is available
• Since Grails 2.0
62. But still there is trouble
• It needs frequent switching of windows
for use while writing code in IDE/editor
• To run a test, you must prepare:
• FQCN of target test class
• Test phase of target test class
67. Improx Plugin
• You can run a test
• Faster than general IDE supports
because using interactive mode
• Directly from IDE/editor without
complicated operations
93. improx-‐start
/
improx-‐stop
• improx-‐start
• Starts an interactive mode proxy server
• improx-‐stop
• Stops the interactive mode proxy server
which is running
94. improx-‐install-‐resources
• Installs “improx-resources” directory which
has some client scripts into your
application project
improx-‐resources/
!
scripts
#
improxClient.groovy
#
improxClient.sh
#
improxSmartInvoker.groovy
!
improxSmartInvoker.sh
100. grails
test-‐app
unit:
sample.SampleUnitTests
$
improxSmartInvoker.sh
/path/to/yourApp/
test/unit/sample/SampleUnitTests.groovy
Runs the following command
on the interactive mode:
101. grails
test-‐app
integration:
sample.SampleIntegTests
$
improxSmartInvoker.sh
/path/to/yourApp/test
/integration/sample/SampleIntegTests.groovy
Runs the following command
on the interactive mode:
126. All you have to do is
to set
improxSmartInvoker
as External Tool
of IDE/editor
http://kobo.github.io/grails-improx/guide/integrationWithEditors.html
135. Under the hood
• Client-Server Communication
• Access Control
• Propagation of CLASSPATH
• Propagation of Environment Variables
• Handling System#exit()
• Dynamic CWD
146. InvocationRequest
'Cwd:' cwd LF
'Arg:' arg1 LF
'Arg:' arg2 LF
:
'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').
147. StreamRequest
'Size:' size LF
LF
body from STDIN
where:
size is the size of body to send to server. size==-1 means
client exited.
body from STDIN is byte sequence from standard input.
149. StreamResponse
'Channel:' id LF
'Size:' size LF
LF
body for 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.
152. Client Address Checking / Authtoken
• Request only from loopback 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.
153. -‐-‐allow-‐from
• By default, A request only from loop-back
address is available.
• You can allow specified addresses.
$
groovyserver
-‐-‐allow-‐from
192.168.1.1
SECURITY RISK: Be careful when using this option
154. -‐-‐authtoken
• By default, authtoken is generated
automatically.
• You can specify any string.
SECURITY RISK: Be careful when using this option
$
groovyserver
-‐-‐authtoken
MY_AUTHTOKEN
187. groovyclient options
• -‐Cenv
substr
• Passes environment variables of 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
201. $ cd /tmp
$ groovyserver -r
$ cd /home/nobeans
$ 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.
202. CWD of client should be
set to server
for each invocation.
But, ...
204. Solution
• Setting to “user.dir” system property
• It affects File#getAbsolutePath()
• Changing CWD of native JVM process
• Many classes don’t use “user.dir” to
complete an absolute path.
• But, JNI is troublesome...
205. JNA is easy way to use native API
UnixLibC.groovy:
interface
UnixLibC
extends
com.sun.jna.Library.Library
{
int
chdir(String
dir)
int
setenv(String
envVarName,
String
envVarValue,
int
overwrite)
}
pom.xml:
dependency
groupIdnet.java.dev.jna/groupId
artifactIdjna/artifactId
version3.2.2/version
/dependency
Usage:
def
libc
=
com.sun.jna.Native.loadLibrary(c,
UnixLibC.class)
libc.chdir(“/tmp/foo/bar”)
206. $ cd /tmp
$ groovyserver -r
$ cd /home/nobeans
$ 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!