Closed uehaj closed 8 years ago
This problem come from
poses System.getSecurityManager().checkExit(0).
For grovyserver, call of exit() can be detected by only SecurityManager#checkExit(0). In other words, groovyserv detects only call of SecurityManager.checkExit(), not call of System.exit() itself.
tihs is serious problem.
possible solutions are:
AST trnsfornation(for example change EXIT_ON_CLOSE to DISPOSE_ON_CLOSE) is useless because this is not only groovy problem. Invoked Java class might have called setDefaultCloseOperation().
another solution is:
javax.swing.JFrame.metaClass.setDefaultCloseOperation = {}
you can skip checExit easily. but it has the same problem with AST transformation.
From http://d.hatena.ne.jp/nemo_kaz/20080730
import groovy.swing.SwingBuilder
import java.awt.Color
import java.awt.BorderLayout as BL
import javax.swing.WindowConstants as WC
import javax.swing.BorderFactory as BF
import javax.swing.JOptionPane
swing = new SwingBuilder()
paint = swing.action(
name: 'Run',
closure: this.&paintGraph,
mnemonic: 'R',
accelerator: 'ctrl R'
)
about = swing.action(
name: 'About',
closure: this.&showAbout,
mnemonic: 'A',
accelerator: 'F1'
)
frame = swing.frame(title:'2次元ランダムウォーク',
location:[100,100], size:[300,300],
defaultCloseOperation:WC.EXIT_ON_CLOSE) {
menuBar (){
menu(mnemonic:'A','Action'){
menuItem(action:paint)
}
glue()
menu(mnemonic:'H','Help'){
menuItem(action:about)
}
}
panel (border:BF.createEmptyBorder(6,6,6,6)) {
borderLayout()
vbox(constraints: BL.CENTER,border:BF.createTitledBorder('Runボタンを押すたびに100回動きます')) {
panel(id:'canvas')
}
hbox (constraints: BL.SOUTH){
hstrut(width:10)
button(action:paint)
}
}
}
frame.show()
def labeledSpinner(label, value){
swing.label(label)
swing.hstrut()
swing.spinner(id:label, stateChanged:this.&paintGraph,
model:swing.spinnerNumberModel(value:value))
}
gfx = swing.canvas.graphics
gfx.color = new Color(255, 255, 150)
gfx.color = Color.red
xpos = 100
ypos = 100
def paintGraph(event) {
int width = swing.canvas.size.width
int height = swing.canvas.size.height
1.upto(100) {
xdir = Math.random()
ydir = Math.random()
if (xdir <0.3333 && xpos >5) { xpos-=5 }
if (xdir >0.6666 && (xpos < width-5)) { xpos+=5 }
if (ydir <0.3333 && ypos >5) { ypos-=5 }
if (ydir >0.6666 && (ypos <height-5)) { ypos+=5 }
gfx.fillRect(xpos,ypos,4,4)
}
}
void showAbout(event) {
JOptionPane.showMessageDialog(frame,
'''2次元ランダムウォーク
赤い四角がランダムに歩きます。''')
}
Using v1.0.0:
$ groovyclient randomWalk.groovy
Caught: java.lang.RuntimeException: Failed to create component for 'frame' reason: java.awt.HeadlessException
java.lang.RuntimeException: Failed to create component for 'frame' reason: java.awt.HeadlessException
at randomWalk.run(randomWalk.groovy:21)
at groovyx.groovyserv.GroovyMain2.processOnce(GroovyMain2.java:609)
at groovyx.groovyserv.GroovyMain2.run(GroovyMain2.java:391)
at groovyx.groovyserv.GroovyMain2.process(GroovyMain2.java:377)
at groovyx.groovyserv.GroovyMain2.processArgs(GroovyMain2.java:130)
at groovyx.groovyserv.GroovyInvokeHandler.invokeGroovy(GroovyInvokeHandler.groovy:133)
at groovyx.groovyserv.GroovyInvokeHandler.run(GroovyInvokeHandler.groovy:61)
Caused by: java.awt.HeadlessException
... 7 more
src/main/go/server/server.go
// -Djava.awt.headless=true: without this, annoying to switch an active process to it when new process is created as daemon
- "-Djava.awt.headless=true " +
This causes java.awt.HeadlessException
.
However, the following error occurs even though the option is disabled.
....
2016/03/15 15:05:11,125 [DEBUG] (java.lang.ThreadGroup[name=system,maxpri=10]) (ClientConnection:108) Sent exit status 5 [13/356]
2016/03/15 15:05:11,132 [DEBUG] (java.lang.ThreadGroup[name=system,maxpri=10]) (ClientConnection:156) PipedOutputStream is closed
2016/03/15 15:05:11,139 [DEBUG] (java.lang.ThreadGroup[name=system,maxpri=10]) (ClientConnection:126) PipedInputStream is closed
2016/03/15 15:05:11,145 [DEBUG] (java.lang.ThreadGroup[name=system,maxpri=10]) (ClientConnection:133) Socket is closed
2016/03/15 15:05:11,151 [DEBUG] (java.lang.ThreadGroup[name=system,maxpri=10]) (RequestWorker:170) Closed safely: 5
2016/03/15 15:05:11,157 [DEBUG] (java.lang.ThreadGroup[name=system,maxpri=10]) (RequestWorker:176) Terminated
2016/03/15 15:05:11,158 [DEBUG] (GServThreadGroup:62612:1) (GroovyInvokeHandler:187) Found 0 sub thread(s): []
2016/03/15 15:05:11,163 [DEBUG] (java.lang.ThreadGroup[name=system,maxpri=10]) (RequestWorker:176) Terminated
2016/03/15 15:05:11,166 [DEBUG] (GServThreadGroup:62612:1) (EnvironmentVariables:87) putenv(PWD, /tmp)
2016/03/15 15:05:11,174 [DEBUG] (GServThreadGroup:62612:1) (GroovyInvokeHandler:85) Thread is dead
2016/03/15 15:05:11,180 [DEBUG] (GServThreadGroup:62612:1) (RequestWorker:131) Handler is dead: GroovyInvokeHandler
2016/03/15 15:05:11,188 [DEBUG] (GServThreadGroup:62612:1) (RequestWorker:195) Exited: 0: System.exit(0) is called
groovyx.groovyserv.SystemExitException: System.exit(0) is called
at groovyx.groovyserv.NoExitSecurityManager2.checkExit(NoExitSecurityManager2.java:33)
at javax.swing.JFrame.setDefaultCloseOperation(JFrame.java:398)
at java.lang.reflect.Method.invoke(Method.java:498)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:2702)
at groovy.lang.MetaClassImpl.setProperty(MetaClassImpl.java:3746)
at groovy.util.FactoryBuilderSupport.setNodeAttributes(FactoryBuilderSupport.java:1097)
at groovy.util.FactoryBuilderSupport.handleNodeAttributes(FactoryBuilderSupport.java:979)
at groovy.util.FactoryBuilderSupport.createNode(FactoryBuilderSupport.java:725)
at groovy.util.FactoryBuilderSupport.dispatchNodeCall(FactoryBuilderSupport.java:857)
at groovy.util.FactoryBuilderSupport.doInvokeMethod(FactoryBuilderSupport.java:781)
at groovy.util.FactoryBuilderSupport.invokeMethod(FactoryBuilderSupport.java:501)
at randomWalk.run(randomWalk.groovy:21)
at groovy.lang.GroovyShell.runScriptOrMainOrTestOrRunnable(GroovyShell.java:263)
at groovy.lang.GroovyShell.run(GroovyShell.java:227)
at groovy.lang.GroovyShell.run(GroovyShell.java:157)
at groovyx.groovyserv.GroovyMain2.processOnce(GroovyMain2.java:609)
at groovyx.groovyserv.GroovyMain2.run(GroovyMain2.java:391)
at groovyx.groovyserv.GroovyMain2.process(GroovyMain2.java:377)
at groovyx.groovyserv.GroovyMain2.processArgs(GroovyMain2.java:130)
at java.lang.reflect.Method.invoke(Method.java:498)
at groovy.lang.MetaMethod.doMethodInvoke(MetaMethod.java:325)
at groovyx.groovyserv.GroovyInvokeHandler.invokeGroovy(GroovyInvokeHandler.groovy:133)
at java.lang.reflect.Method.invoke(Method.java:498)
at groovyx.groovyserv.GroovyInvokeHandler.run(GroovyInvokeHandler.groovy:61)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
(sanitized)
2016/03/15 15:05:11,200 [DEBUG] (GServThreadGroup:62612:1) (RequestWorker:146) Another handler StreamRequestHandler is canceling by GroovyInvokeHandler
2016/03/15 15:05:11,208 [DEBUG] (GServThreadGroup:62612:1) (ClientConnection:108) Sent exit status 0
....
That's described in https://github.com/kobo/groovyserv/issues/8#issuecomment-347800.
This issue is difficult. And I don't think that there is many cases which you want to run GUI program with GroovServ. So, I won't fix it for the moment.
I'll add this as a restriction to documentation.
http://groups.google.com/group/groovyserv/browse_thread/thread/cf629f359c0853a6