2 * Copyright 2004-2005 the original author or authors.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * Gant script that executes Grails using an embedded Jetty server
20 * @author Graeme Rocher
25 import org
.codehaus
.groovy
.grails
.commons
.GrailsClassUtils as GCU
26 import org
.mortbay
.jetty
.*
27 import org
.mortbay
.jetty
.nio
.*
28 import org
.mortbay
.jetty
.handler
.*
29 import org
.mortbay
.jetty
.webapp
.*
30 import org
.mortbay
.jetty
.plus
.naming
.*
33 import org
.codehaus
.groovy
.tools
.RootLoader
34 import org
.codehaus
.groovy
.grails
.plugins
.PluginManagerHolder
35 import org
.codehaus
.groovy
.grails
.cli
.GrailsScriptRunner
38 Ant
.property(environment
:"env")
39 grailsHome
= Ant
.antProject
.properties
."env.GRAILS_HOME"
42 autoRecompile
= System
.getProperty("disable.auto.recompile") ?
!(System
.getProperty("disable.auto.recompile").toBoolean()) : true
44 // How often should recompilation occur while the application is running (in seconds)?
46 recompileFrequency
= System
.getProperty("recompile.frequency")
47 recompileFrequency
= recompileFrequency ? recompileFrequency
.toInteger() : 3
50 includeTargets
<< new File ( "${grailsHome}/scripts/Package.groovy" )
53 shouldPackageTemplates
=true
58 target ('default': "Run's a Grails application in Jetty") {
59 depends( checkVersion
, configureProxy
, packageApp
)
63 target ( runApp
: "Main implementation that executes a Grails application") {
64 System
.setProperty('org.mortbay.xml.XmlParser.NotValidating', 'true')
66 println
"Running Grails application.."
67 def server
= configureHttpServer()
68 profile("start server") {
71 event("StatusFinal", ["Server running. Browse to http://localhost:$serverPort$serverContextPath"])
72 } catch(Throwable t
) {
74 event("StatusFinal", ["Server failed to start: $t"])
77 target( watchContext
: "Watches the WEB-INF/classes directory for changes and restarts the server if necessary") {
78 long lastModified
= classesDir
.lastModified()
79 boolean keepRunning
= true
80 boolean isInteractive
= System
.getProperty("grails.interactive.mode") == "true"
83 def daemonThread
= new Thread( {
84 println
"--------------------------------------------------------"
85 println
"Application loaded in interactive mode, type 'exit' to shutdown server or your command name in to continue (hit ENTER to run the last command):"
87 def reader
= new BufferedReader(new InputStreamReader(System
.in
))
88 def cmd
= reader
.readLine()
91 if(cmd
== 'exit' || cmd
== 'quit') break
92 if(cmd
!= 'run-app') {
93 scriptName
= cmd ? GrailsScriptRunner
.processArgumentsAndReturnScriptName(cmd
) : scriptName
95 def now
= System
.currentTimeMillis()
96 GrailsScriptRunner
.callPluginOrGrailsScript(scriptName
)
97 def end
= System
.currentTimeMillis()
98 println
"--------------------------------------------------------"
99 println
"Command [$scriptName] completed in ${end-now}ms"
103 println
"Cannot run the 'run-app' command. Server already running!"
106 println
"--------------------------------------------------------"
107 println
"Application loaded in interactive mode, type 'exit' to shutdown server or your command name in to continue (hit ENTER to run the last command):"
109 cmd
= reader
.readLine()
110 } catch (IOException e
) {
115 println
"Stopping Grails server..."
120 daemonThread
.daemon
= true
126 lastModified
= recompileCheck(lastModified
) {
130 Thread currentThread
= Thread
.currentThread()
131 ClassLoader contextLoader
= currentThread
.getContextClassLoader()
132 classLoader
= new URLClassLoader([classesDir
.toURI().toURL()] as URL
[], contextLoader
)
133 currentThread
.setContextClassLoader classLoader
134 PluginManagerHolder
.pluginManager
= null
138 grailsServer
.setHandler( webContext
)
140 } catch (Throwable e
) {
141 GrailsUtil
.sanitizeStackTrace(e
)
146 sleep(recompileFrequency
* 1000)
150 target( configureHttpServer
: "Returns a jetty server configured with an HTTP connector") {
151 def server
= new Server()
152 grailsServer
= server
153 def connectors
= [new SelectChannelConnector()]
154 connectors
[0].setPort(serverPort
)
155 server
.setConnectors( (Connector
[])connectors
)
157 server
.setHandler( webContext
)
158 event("ConfigureJetty", [server
])
162 target( setupWebContext
: "Sets up the Jetty web context") {
163 webContext
= new WebAppContext("${basedir}/web-app", serverContextPath
)
164 def configurations
= [org
.mortbay
.jetty
.webapp
.WebInfConfiguration
,
165 org
.mortbay
.jetty
.plus
.webapp
.Configuration
,
166 org
.mortbay
.jetty
.webapp
.JettyWebXmlConfiguration
,
167 org
.mortbay
.jetty
.webapp
.TagLibConfiguration
]*.newInstance()
168 def jndiConfig
= new org
.mortbay
.jetty
.plus
.webapp
.EnvConfiguration()
169 if(config
.grails
.development
.jetty
.env
) {
170 def res
= resolveResources(config
.grails
.development
.jetty
.env
)
172 jndiConfig
.setJettyEnvXml(res
[0].URL
)
175 configurations
.add(1,jndiConfig
)
176 webContext
.configurations
= configurations
177 webContext
.setDefaultsDescriptor("${grailsHome}/conf/webdefault.xml")
178 webContext
.setClassLoader(classLoader
)
179 webContext
.setDescriptor(webXmlFile
.absolutePath
)
182 target( stopServer
: "Stops the Grails Jetty server") {
186 event("StatusFinal", ["Server stopped"])