Gradle HttpFileServer, keep running, but kill on ctrl+c - gradle

During my Gradle build I need to run a simple web server to serve some static content. I’m using Gradle’s integrated classes for that.
Here's a very simple version of my build.gradle:
apply plugin: 'groovy'
task server() {
doLast {
def root = new File(project.buildDir, '/site')
def port = 8765
def factory = new SimpleHttpFileServerFactory();
def server = factory.start(root, port)
println "HTTP server started on $port"
}
}
I'm facing the following two issues:
When running gradle server, gradle executes, starts the server, and then quits (with the daemon obviously staying in the background and the server running, which leads to the second problem)
I’ve no possibility to stop the server through gradle. When running gradle server again, I get an exception because the port is in use.
I’d fancy either of the following solutions:
When running gradle server, gradle keeps running until I hit ctrl+c, then the server is killed as well
There are two tasks, gradle startServer and gradle stopServer which are used to start and stop
How can I achieve this or is there a different, better solution?

A little hack-ish but it works, the server task will hang and the SIGKILL will kill the server too
apply plugin: 'groovy'
task server() {
doLast {
def root = new File(project.buildDir, '/site')
def port = 8765
def factory = new SimpleHttpFileServerFactory();
def server = factory.start(root, port)
println "HTTP server started on $port"
while(true) Thread.sleep(1000)
}
}

Related

Vert.x address already in use: bind - Not kill processes (Windows)

I'm creating a simple REST Server using Vert.x on intelliJ IDEA. When I run to test it, processes never are stopped after clicking the stop button from intelliJ. I undestand this because if I try to run, stop and rerun will appear the error "Address already in use: bind" so each time I must search java processes and kill them by Task Manager. Someone know a better solution?
I resolved changing in my build.gradle.kts this line of code:
tasks.withType<JavaExec> { args = listOf("run", mainVerticleName, "--redeploy=$watchForChange", "--launcher-class=$launcherClassName", "--on-redeploy=$doOnChange")}
With this:
tasks.withType<JavaExec> { args = listOf("run", mainVerticleName, "--launcher-class=$launcherClassName", "--on-redeploy=$doOnChange")}
So I removed the "--redeploy=$watchForChange" and it works fine.

Connect Travis CI to SonarQube through a HAProxy with Basic Auth using Gradle

I'm trying to setup SonarQube for a Gradle project. I get it to play locally, but when using Travis CI I, run into problems. Travis cannot reach the SonarQube server through the HAProxy.
SonarQube server is behind a HAProxy with Basic Access Authentication. I have tried to use the name and password both as sonar.login/sonar.password and as auth credentials in the URL, but with no success.
sonarqubeSonarQube server [https://sonar.<domain>.com] can not be reached
or
sonarqubeSonarQube server [https://<name>:<password>#sonar.<domain>.com] can not be reached
Basically my build.gradle file contains this:
plugins {
id "org.sonarqube" version "2.0.1"
}
sonarqube {
properties {
properties["sonar.host.url"] = getProperty('SONAR_URL')
properties["sonar.login"] = getProperty('SONAR_USERNAME')
properties["sonar.password"] = getProperty('SONAR_PASSWORD')
}
}
I had to remove the 'systemProp.' prefix to the properties in order to get it to work locally.
When running locally, I have a init.gradle file that contains this section, and it works nice.
allprojects {
ext.set('SONAR_URL', 'http://localhost:9000')
ext.set('SONAR_USERNAME', 'admin')
ext.set('SONAR_PASSWORD', 'admin')
...
}
On Travis CI, I try to add environment variables for the job:
ORG_GRADLE_PROJECT_SONAR_PASSWORD ••••••••••••••••
ORG_GRADLE_PROJECT_SONAR_USERNAME ••••••••••••••••
ORG_GRADLE_PROJECT_SONAR_URL ••••••••••••••••
How can I get Travis CI to reach the sonar server that we have?

Running Play service from Gradle

I am attempting to use a Gradle task to run a Play service, but I'm finding the Gradle task will hang (presumably waiting for a return value from the Play bootstrap script).
What I'm doing from the Play side is simply:
sbt dist
Which produces a .zip distribution (like 'myproject.zip'), which I then expand where I want to run this service from.
On the Gradle side, I was thinking I would do something like this:
task start(type: Exec) {
workingDir "myproject/bin"
commandLine './myproject'
}
This does indeed start up the Play service just fine, but the Gradle task will hang indefinitely (until you do a control+C).
The most obvious thing that came to mind to try was something like:
task start(type: Exec) {
workingDir "myproject/bin"
commandLine 'nohup ./myproject &'
}
But that ends in a dead end:
Execution failed for task ':start'.
> A problem occurred starting process 'command 'nohup ./playservicetemplate &''
It seems like this is a really common use case, so I'm wondering if there is an obvious solution that I'm overlooking.
There is perhaps a more Gradle-ish way to do this, but I solved it by leveraging ProcessBuilder. My new task looks like:
task start {
ProcessBuilder builder = new ProcessBuilder("./myproject")
builder.directory(new File("myproject/bin"))
builder.start()
}
Obviously, you can get a lot fancier with this (a quick Google of 'java processbuilder' will net you pages upon pages of examples), but this will do the trick for my purposes.

Running two Gradle application tasks concurrently in same project

It looks like when I try to run a second Gradle task for the same project in a different window, the second one blocks on a lock. Is there a straightforward way around this?
What I'm trying to do: My project has a couple server subprojects that both use the application plugin. I'd like to start both (e.g., $ gradle :server1:run) so I could connect and try them out.
I know I can write a task to deploy the two servers to a test area and start them there, but the application:run task is convenient during development for one application, so I'd like to use it for two if possible.
I'm using Gradle 2.7.
Here is what I ended up doing. Rather than using the application plugin's run task, I used installDist, and wrote a simple task to run the generated start script. Then I extended it by creating a simple service script that I stored under src/dist/bin. The script handles start, stop, and status operations. The final result:
ext.installDir = "$buildDir/install/" + project.name
ext.command = "$installDir/bin/" + project.name
task start(type:Exec, dependsOn:'installDist') {
description "Starts the " + applicationName + " application"
workingDir "$installDir"
commandLine "$command", "start"
}
task stop(type:Exec, dependsOn:'installDist') {
description "Stops the " + applicationName + " application"
workingDir "$installDir"
commandLine "$command", "stop"
}
task status(type:Exec, dependsOn:'installDist') {
description "Displays the " + applicationName + " application status"
workingDir "$installDir"
commandLine "$command", "status"
}
Now from the parent project I can just type:
$ gradlew start
to start both servers and
$ gradlew stop
to shut them both down.

Run exe outside of gradle scope

I am trying to kick of an exe (mongodb) from gradle, but need that exe to run outside of gradle scope so that the gradle task is not blocked for ever.
task startMongo(type: Exec) {
executable "$buildDir/mongo/mongod.exe"
args "--dbpath=$buildDir/mongo/data/db"
}
Mongodb starts fine, but the task is blocked as the mongo server waits for connections.
2014-12-10T14:30:33.018-0700 [initandlisten] waiting for connections on port 27017
Robert - thank you. I wrote a custom gradle task and started the exe in background.
class MyTask extends DefaultTask {
#TaskAction
void startProcess() {
ProcessBuilder processBuilder = new ProcessBuilder()
processBuilder.command('exe-path', 'arg')
processBuilder.start()
}

Resources