| description("Runs a Grails application") { |
| usage "grails run-app" |
| synonyms 'run' |
| flag name:'debug-jvm', description:"Starts the JVM in debug mode allowing attachment of a remote debugger" |
| flag name:'https', description:"Starts Grails in HTTPS mode on port 8443" |
| flag name:'port', description:"Specifies the port which to start Grails on (defaults to 8080 or 8443 for HTTPS)" |
| flag name:'host', description:"Specifies the host to bind to" |
| flag name:'verbose', description:"Show more output from the build during startup" |
| } |
| |
| if(!commandLine.isEnvironmentSet()) { |
| System.setProperty('grails.env', 'dev') |
| } else { |
| System.setProperty('grails.env', commandLine.environment) |
| } |
| // add debug flag if present |
| try { |
| |
| def arguments = [] |
| |
| if( !(flag('verbose') || console.verbose)) { |
| arguments << '--quiet' |
| } |
| |
| arguments << '-Dgrails.management.endpoints.shutdown.enabled=true' |
| |
| arguments.addAll commandLine.remainingArgs |
| |
| Integer port = flag('port')?.toInteger() ?: config.getProperty('server.port', Integer) |
| String host = flag('host') ?: config.getProperty('server.address', String) |
| |
| commandLine.systemProperties.each { key, value -> |
| arguments << "-D${key}=$value".toString() |
| } |
| |
| arguments << "-Dgrails.run.active=true" |
| |
| if(port) { |
| arguments << "-Dgrails.server.port=$port" |
| } |
| if(host) { |
| arguments << "-Dgrails.server.address=$host" |
| } |
| |
| if(flag('https')) { |
| if(!port) { |
| arguments << "-Dgrails.server.port=8443" |
| } |
| if(!System.getProperty('grails.server.ssl.key-store')) { |
| def keystoreDir = new File(buildDir, "ssl") |
| def keystoreFile = new File(keystoreDir, 'keystore') |
| |
| boolean keyStoreParametersAvailable = false |
| if(!keystoreFile.exists()) { |
| console.updateStatus "Generating SSL certificate" |
| if ( createSSLCertificate(keystoreDir) ) { |
| keyStoreParametersAvailable = true |
| console.updateStatus "Generated SSL certificate" |
| } |
| else { |
| console.warn "Unable to automatically generate SSL certificate, manual configuration required. Set 'server.ssl.key-store' in application.yml" |
| } |
| } |
| else { |
| keyStoreParametersAvailable = true |
| } |
| if(keyStoreParametersAvailable) { |
| arguments << "-Dgrails.server.ssl.key-store=${keystoreFile}" |
| arguments << "-Dgrails.server.ssl.key-store-password=123456" |
| arguments << "-Dgrails.server.ssl.key-password=123456" |
| } |
| } |
| } |
| |
| console.updateStatus "Running application..." |
| |
| if(!org.grails.cli.GrailsCli.isInteractiveModeActive()) { |
| if(flag('debug-jvm')) { |
| gradle."bootRun --debug-jvm"(*arguments) |
| } |
| else { |
| gradle."bootRun"(*arguments) |
| } |
| } |
| else { |
| def future |
| if(flag('debug-jvm')) { |
| future = gradle.async."bootRun --debug-jvm"(*arguments) |
| } |
| else { |
| future = gradle.async."bootRun"(*arguments) |
| } |
| |
| while(!isServerAvailable(host ?: "localhost", port ?: 8080)) { |
| console.indicateProgress() |
| if(future.done) { |
| // the server exited for some reason, so break |
| if(future.get() instanceof Throwable) { |
| break |
| } |
| } |
| sleep(100); |
| } |
| |
| System.setProperty("run-app.running", "true") |
| if(!Boolean.getBoolean("run-app.shutdown.hook.registered")) { |
| System.setProperty("run-app.shutdown.hook.registered", "true") |
| addShutdownHook { |
| if(Boolean.getBoolean("run-app.running")) { |
| try { |
| stopApp() |
| } |
| catch(e) { |
| // ignore |
| } |
| } |
| } |
| isShutdownHookRegistered = true |
| } |
| |
| sleep 500 |
| } |
| |
| } |
| catch(org.gradle.tooling.BuildCancelledException e) { |
| console.updateStatus("Application stopped") |
| return true |
| } |
| catch(Throwable e) { |
| console.error "Failed to start server", e |
| return false |
| } |
| |
| protected boolean createSSLCertificate(File keystoreDir) { |
| |
| if (!keystoreDir.exists() && !keystoreDir.mkdir()) { |
| throw new RuntimeException("Unable to create keystore folder: $keystoreDir.canonicalPath") |
| } |
| |
| def keyToolClass = getKeyToolClass() |
| if(keyToolClass) { |
| try { |
| def keystoreFile = new File(keystoreDir, "keystore") |
| keyToolClass.main( |
| "-genkey", |
| "-alias", "localhost", |
| "-dname", "CN=localhost,OU=Test,O=Test,C=US", |
| "-keyalg", "RSA", |
| "-validity", "365", |
| "-storepass", "key", |
| "-keystore", keystoreFile.absolutePath, |
| "-storepass", "123456", |
| "-keypass", "123456") |
| } |
| catch(Throwable e) { |
| return false |
| } |
| |
| return true |
| } |
| else { |
| return false |
| } |
| } |
| |
| protected Class getKeyToolClass() { |
| try { |
| try { |
| // Sun JDK 8 |
| return Class.forName( 'sun.security.tools.keytool.Main' ) |
| } |
| catch(ClassNotFoundException e1) { |
| try { |
| // Sun pre-JDK 8 |
| return Class.forName( 'sun.security.tools.KeyTool' ) |
| } |
| catch (ClassNotFoundException e2) { |
| // no try/catch for this one, if neither is found let it fail |
| return Class.forName( 'com.ibm.crypto.tools.KeyTool' ) |
| } |
| } |
| } |
| catch(Throwable e) { |
| return null |
| } |
| } |