Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 326 lines (283 sloc) 11.734 kB
3e17890 1.1 branch is now trunk
graeme authored
1 /*
2 * Copyright 2004-2005 the original author or authors.
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16 import org.codehaus.groovy.grails.plugins.PluginManagerHolder
17 import org.codehaus.groovy.grails.cli.GrailsScriptRunner
18 import grails.util.GrailsUtil
19
20 import grails.web.container.EmbeddableServerFactory
21 import grails.web.container.EmbeddableServer
22
23 /**
69c8376 @graemerocher Fix for GRAILS-5055 "Server parameter to eventConfigureJetty is null …
graemerocher authored
24 * Gant script that executes Grails using an embedded server
3e17890 1.1 branch is now trunk
graeme authored
25 *
26 * @author Graeme Rocher
27 *
28 * @since 0.4
29 */
30
081c7a6 @graemerocher Grails 1.2 now uses Tomcat as the default server
graemerocher authored
31 includeTargets << grailsScript("_GrailsPlugins")
3e17890 1.1 branch is now trunk
graeme authored
32
835947f @burtbeckwith cleanup
burtbeckwith authored
33 SCHEME_HTTP = "http"
34 SCHEME_HTTPS = "https"
3e17890 1.1 branch is now trunk
graeme authored
35
b735e73 @pledbrook Fix for GRAILS-4364: automatic server restarts now remember whether
pledbrook authored
36 // Keep track of whether we're running in HTTPS mode in case we need
37 // to restart the server.
38 usingSecureServer = false
3e17890 1.1 branch is now trunk
graeme authored
39
40 grailsServer = null
41 grailsContext = null
42 autoRecompile = System.getProperty("disable.auto.recompile") ? !(System.getProperty("disable.auto.recompile").toBoolean()) : true
43
44 // How often should recompilation occur while the application is running (in seconds)?
45 // Defaults to 3s.
46 recompileFrequency = System.getProperty("recompile.frequency")
47 recompileFrequency = recompileFrequency ? recompileFrequency.toInteger() : 3
48
49 shouldPackageTemplates = true
50
51 // This isn't used within this script but may come in handy for scripts
52 // that depend on this one.
53 ant.path(id: "grails.runtime.classpath", runtimeClasspath)
54
55 /**
56 * Runs the application in dev mode, i.e. with class-reloading.
57 */
58 target(runApp: "Main implementation that executes a Grails application") {
59 runInline(SCHEME_HTTP, serverHost, serverPort, serverPortHttps)
60 }
61
62 /**
63 * Runs the application in dev mode over HTTPS.
64 */
65 target(runAppHttps: "Main implementation that executes a Grails application with an HTTPS listener") {
66 runInline(SCHEME_HTTPS, serverHost, serverPort, serverPortHttps)
67 }
68
69 /**
70 * Runs the application using the WAR file directly.
71 */
72 target (runWar : "Main implementation that executes a Grails application WAR") {
73 runWar(SCHEME_HTTP, serverHost, serverPort, serverPortHttps)
74 }
75
76
77 /**
78 * Runs the application over HTTPS using the WAR file directly.
79 */
80 target (runWarHttps : "Main implementation that executes a Grails application WAR") {
81 runWar(SCHEME_HTTPS, serverHost, serverPort, serverPortHttps)
82 }
83
84 private EmbeddableServerFactory loadServerFactory() {
85 def load = { name -> classLoader.loadClass(name).newInstance() }
86
87
081c7a6 @graemerocher Grails 1.2 now uses Tomcat as the default server
graemerocher authored
88 String defaultServer = "org.grails.tomcat.TomcatServerFactory"
89 def containerClass = getPropertyValue("grails.server.factory", defaultServer)
3e17890 1.1 branch is now trunk
graeme authored
90 EmbeddableServerFactory serverFactory
91 try {
92 serverFactory = load(containerClass)
93 }
835947f @burtbeckwith cleanup
burtbeckwith authored
94 catch (ClassNotFoundException cnfe) {
95 if (containerClass == defaultServer) {
081c7a6 @graemerocher Grails 1.2 now uses Tomcat as the default server
graemerocher authored
96 println "WARNING: No default container found, installing Tomcat.."
6bbf23a @graemerocher fixed code causing MME
graemerocher authored
97 doInstallPlugin "tomcat", GrailsUtil.grailsVersion
0bf3e1f @graemerocher Fixed by clearing plugin settings cache (wrong method signature)
graemerocher authored
98 pluginSettings.clearCache()
081c7a6 @graemerocher Grails 1.2 now uses Tomcat as the default server
graemerocher authored
99 compilePlugins()
6447df7 @graemerocher another fix for the failing functional tests
graemerocher authored
100 loadPlugins()
835947f @burtbeckwith cleanup
burtbeckwith authored
101 serverFactory = load(containerClass)
081c7a6 @graemerocher Grails 1.2 now uses Tomcat as the default server
graemerocher authored
102 }
103 }
3e17890 1.1 branch is now trunk
graeme authored
104 catch (Throwable e) {
105 GrailsUtil.deepSanitize(e)
106 e.printStackTrace()
107 event("StatusFinal", ["Failed to load container [$containerClass]: ${e.message}"])
108 exit(1)
109 }
110 return serverFactory
111 }
112
113 private runInline(scheme, host, httpPort, httpsPort) {
114 EmbeddableServerFactory serverFactory = loadServerFactory()
115 grailsServer = serverFactory.createInline("${basedir}/web-app", webXmlFile.absolutePath, serverContextPath, classLoader)
116 runServer server: grailsServer, host:host, httpPort: httpPort, httpsPort: httpsPort, scheme:scheme
117 startPluginScanner()
118 }
119
120 private runWar(scheme, host, httpPort, httpsPort) {
121 EmbeddableServerFactory serverFactory = loadServerFactory()
122 grailsServer = serverFactory.createForWAR(warName, serverContextPath)
123
571b481 @graemerocher fix for failing functional tests
graemerocher authored
124 grails.util.Metadata.getCurrent().put(grails.util.Metadata.WAR_DEPLOYED, "true")
3e17890 1.1 branch is now trunk
graeme authored
125 runServer server:grailsServer, host:host, httpPort:httpPort, httpsPort: httpsPort, scheme: scheme
126
127 }
128
129 /**
130 * Runs the Server. You can pass these named arguments:
131 *
132 * server - The server instance to use (required).
133 * port - The network port the server is running on (used to display the URL) (required).
134 * scheme - The network scheme to display in the URL (optional; defaults to "http").
135 */
136 runServer = { Map args ->
137 try {
138 println "Running Grails application.."
139 def message = "Server running. Browse to http://${args.host ?: 'localhost'}:${args.httpPort}$serverContextPath"
140
141 EmbeddableServer server = args["server"]
835947f @burtbeckwith cleanup
burtbeckwith authored
142 if (server.hasProperty('eventListener')) {
0f88cc9 @graemerocher registration of event listener and grailsConfig not tied to Jetty
graemerocher authored
143 server.eventListener = this
144 }
835947f @burtbeckwith cleanup
burtbeckwith authored
145 if (server.hasProperty('grailsConfig')) {
0f88cc9 @graemerocher registration of event listener and grailsConfig not tied to Jetty
graemerocher authored
146 server.grailsConfig = config
3e17890 1.1 branch is now trunk
graeme authored
147 }
148
149 profile("start server") {
835947f @burtbeckwith cleanup
burtbeckwith authored
150 if (args.scheme == 'https') {
b735e73 @pledbrook Fix for GRAILS-4364: automatic server restarts now remember whether
pledbrook authored
151 usingSecureServer = true
3e17890 1.1 branch is now trunk
graeme authored
152 server.startSecure args.host, args.httpPort, args.httpsPort
153
154 // Update the message to reflect the fact we are running HTTPS as well.
155 message += " or https://${args.host ?: 'localhost'}:${args.httpsPort}$serverContextPath"
156 }
157 else {
158 server.start args.host, args.httpPort
159 }
160 }
161 event("StatusFinal", [message])
835947f @burtbeckwith cleanup
burtbeckwith authored
162 }
163 catch (Throwable t) {
3e17890 1.1 branch is now trunk
graeme authored
164 GrailsUtil.deepSanitize(t)
835947f @burtbeckwith cleanup
burtbeckwith authored
165 if (!(t instanceof SocketException) && !(t.cause instanceof SocketException)) {
3e17890 1.1 branch is now trunk
graeme authored
166 t.printStackTrace()
835947f @burtbeckwith cleanup
burtbeckwith authored
167 }
3e17890 1.1 branch is now trunk
graeme authored
168 event("StatusFinal", ["Server failed to start: $t"])
169 exit(1)
170 }
171 }
172
173 /**
174 * Starts the plugin scanner. Call this after starting the server if you
175 * want changes to artifacts automatically detected and loaded.
176 */
177 target(startPluginScanner: "Starts the plugin manager's scanner that detects changes to artifacts.") {
178 // Start the plugin change scanner.
dd99f59 @graemerocher fix for potential NPE when application shuts down
graemerocher authored
179 PluginManagerHolder.pluginManager?.startPluginChangeScanner()
3e17890 1.1 branch is now trunk
graeme authored
180 }
181
6779eb9 @alkemist When stopping the running server, also stop the plugin change scanner.
alkemist authored
182 target(stopPluginScanner: "Stops the plugin manager's scanner that detects changes to artifacts.") {
dd99f59 @graemerocher fix for potential NPE when application shuts down
graemerocher authored
183 PluginManagerHolder.pluginManager?.stopPluginChangeScanner()
6779eb9 @alkemist When stopping the running server, also stop the plugin change scanner.
alkemist authored
184 }
185
3e17890 1.1 branch is now trunk
graeme authored
186 /**
187 * Keeps the server alive and checks for changes in domain classes or
188 * source files under "src". If any changes are detected, the servlet
189 * container is restarted.
190 */
191 target(watchContext: "Watches the WEB-INF/classes directory for changes and restarts the server if necessary") {
192 depends(classpath)
193
194 long lastModified = classesDir.lastModified()
195 boolean keepRunning = true
196 boolean isInteractive = System.getProperty("grails.interactive.mode") == "true"
197
198 if (isInteractive) {
199 def daemonThread = new Thread({
200 println "--------------------------------------------------------"
201 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):"
202
203 def reader = new BufferedReader(new InputStreamReader(System.in))
204 def cmd = reader.readLine()
205 def scriptName
206 while (cmd != null) {
207 if (cmd == 'exit' || cmd == 'quit') break
208 if (cmd != 'run-app') {
209 scriptName = cmd ? GrailsScriptRunner.processArgumentsAndReturnScriptName(cmd) : scriptName
210 if (scriptName) {
211 def now = System.currentTimeMillis()
212 GrailsScriptRunner.callPluginOrGrailsScript(scriptName)
213 def end = System.currentTimeMillis()
214 println "--------------------------------------------------------"
215 println "Command [$scriptName] completed in ${end - now}ms"
216 }
217 }
218 else {
219 println "Cannot run the 'run-app' command. Server already running!"
220 }
221 try {
222 println "--------------------------------------------------------"
223 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):"
224
225 cmd = reader.readLine()
835947f @burtbeckwith cleanup
burtbeckwith authored
226 }
227 catch (IOException e) {
3e17890 1.1 branch is now trunk
graeme authored
228 cmd = ""
229 }
230 }
231
232 println "Stopping Grails server..."
233 grailsServer.stop()
234 PluginManagerHolder.pluginManager.stopPluginChangeScanner()
235 keepRunning = false
236
237 })
238 daemonThread.daemon = true
239 daemonThread.run()
240 }
241
242 def killFile = new File("${basedir}/.kill-run-app")
243 while (keepRunning) {
244 if (autoRecompile) {
245 lastModified = recompileCheck(lastModified) {
246 try {
247 grailsServer.stop()
248 compile()
249 Thread currentThread = Thread.currentThread()
2a33cfa @graemerocher fix for GRAILS-6124 "On auto reloading MissingMethodException is thro…
graemerocher authored
250 def classesDirs = [classesDir,
251 pluginClassesDir].collect { it.toURI().toURL() }
835947f @burtbeckwith cleanup
burtbeckwith authored
252
2a33cfa @graemerocher fix for GRAILS-6124 "On auto reloading MissingMethodException is thro…
graemerocher authored
253 classLoader = new URLClassLoader(classesDirs as URL[], rootLoader)
3e17890 1.1 branch is now trunk
graeme authored
254 currentThread.setContextClassLoader classLoader
255 PluginManagerHolder.pluginManager = null
256 // reload plugins
257 loadPlugins()
b735e73 @pledbrook Fix for GRAILS-4364: automatic server restarts now remember whether
pledbrook authored
258
259 if (usingSecureServer) {
260 runAppHttps()
261 }
262 else {
263 runApp()
264 }
835947f @burtbeckwith cleanup
burtbeckwith authored
265 }
266 catch (Throwable e) {
3e17890 1.1 branch is now trunk
graeme authored
267 logError("Error restarting container",e)
268 exit(1)
269 }
270 }
271 }
272 sleep(recompileFrequency * 1000)
273
274 // Check whether the kill file exists. This is a hack for the
275 // functional tests so that we can stop the servers that are
276 // started.
277 if (killFile.exists()) {
69c8376 @graemerocher Fix for GRAILS-5055 "Server parameter to eventConfigureJetty is null …
graemerocher authored
278 println "Stopping server..."
3e17890 1.1 branch is now trunk
graeme authored
279 grailsServer.stop()
280 killFile.delete()
281 keepRunning = false
282 }
283 }
284 }
285
286 target(keepServerAlive: "Idles the script, ensuring that the server stays running.") {
287 def keepRunning = true
288 def killFile = new File("${basedir}/.kill-run-app")
289 while (keepRunning) {
290 sleep(recompileFrequency * 1000)
291
292 // Check whether the kill file exists. This is a hack for the
293 // functional tests so that we can stop the servers that are
294 // started.
295 if (killFile.exists()) {
69c8376 @graemerocher Fix for GRAILS-5055 "Server parameter to eventConfigureJetty is null …
graemerocher authored
296 println "Stopping server..."
3e17890 1.1 branch is now trunk
graeme authored
297 grailsServer.stop()
298 killFile.delete()
299 keepRunning = false
300 }
301 }
302 }
303
69c8376 @graemerocher Fix for GRAILS-5055 "Server parameter to eventConfigureJetty is null …
graemerocher authored
304 target(stopServer: "Stops the Grails servlet container") {
3e17890 1.1 branch is now trunk
graeme authored
305 if (grailsServer) {
5518da2 @graemerocher handle server stoppage errors more elegantly
graemerocher authored
306 try {
307 grailsServer.stop()
308 }
309 catch (Throwable e) {
310 GrailsUtil.deepSanitize(e)
311 e.printStackTrace()
312 println "Error stopping server: ${e.message}"
313 }
835947f @burtbeckwith cleanup
burtbeckwith authored
314
6779eb9 @alkemist When stopping the running server, also stop the plugin change scanner.
alkemist authored
315 try {
316 stopPluginScanner()
317 }
318 catch (Throwable e) {
319 GrailsUtil.deepSanitize(e)
320 e.printStackTrace()
321 println "Error stopping plugin change scanner: ${e.message}"
322 }
3e17890 1.1 branch is now trunk
graeme authored
323 }
324 event("StatusFinal", ["Server stopped"])
325 }
Something went wrong with that request. Please try again.