6

I would like to run a spring application on cloudfoundry as a one-off task using the java buildpack.

Please note that my app is not a web application but a spring batch application that also uses spring cloud task.

Here is my manifest:

---
buildpack: https://github.com/cloudfoundry/java-buildpack.git
memory: 1024M
env:
  APPLICATION_URL: http://bignibou-server.cfapps.io/
  APPLICATION_MAIL_NO_REPLY_ADDRESS: balteo@bignibou-server.cfapps.io
  SPRING_PROFILES_ACTIVE: cloud

applications:
- name: bignibou-server
  path: bignibou-server/build/libs/bignibou-server.jar
  env:
    APPLICATION_GOOGLE_API_KEY: ******************
- name: bignibou-batch
  path: bignibou-batch/build/libs/bignibou-batch.jar
  no-hostname: true
  no-route: true
  command: null
  health-check-type: none
  env:
    JAVA_OPTS: -Dspring.batch.job.names=messagesDigestMailingJob

Whenever I push the app, it is detected as a worker app:

App bignibou-batch is a worker, skipping route creation

which is what I want.

But then it tries to start the batch as a web application (still whilst deploying the app)... See:

2017-03-24T22:33:50.828+01:00 [CELL/0] [OUT] Destroying container
2017-03-24T22:33:50.854+01:00 [API/3] [OUT] Process has crashed with type: "web"
2017-03-24T22:33:50.873+01:00 [API/3] [OUT] App instance exited with guid befc8bf2-d338-45e1-90b9-430ff3b09a3f payload: {"instance"=>"", "index"=>0, "reason"=>"CRASHED", "exit_description"=>"2 error(s) occurred:\n\n* Codependent step exited\n* cancelled", "crash_count"=>1, "crash_timestamp"=>1490391230813627797, "version"=>"8f92e459-a6c7-4558-bc0b-09ac398eb069"}
2017-03-24T22:33:51.473+01:00 [CELL/0] [OUT] Successfully destroyed container
2017-03-24T22:33:51.634+01:00 [CELL/0] [OUT] Creating container
2017-03-24T22:33:52.478+01:00 [CELL/0] [OUT] Successfully created container
2017-03-24T22:33:56.824+01:00 [APP/PROC/WEB/0] [OUT] JVM Memory Configuration: -XX:MaxMetaspaceSize=164239K -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=25984K -Xmx295151K -XX:MaxDirectMemorySize=10M
2017-03-24T22:33:56.827+01:00 [APP/PROC/WEB/0] [ERR] JVM Memory Configuration: -XX:ReservedCodeCacheSize=240M -XX:CompressedClassSpaceSize=25984K -Xmx295151K -XX:MaxDirectMemorySize=10M -XX:MaxMetaspaceSize=164239K
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] . ____ _ __ _ _
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] /\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] \\/ ___)| |_)| | | | | || (_| | ) ) ) )
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] ' |____| .__|_| |_|_| |_\__, | / / / /
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] =========|_|==============|___/=/_/_/_/
2017-03-24T22:33:59.073+01:00 [APP/PROC/WEB/0] [OUT] ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
2017-03-24T22:33:59.075+01:00 [APP/PROC/WEB/0] [OUT] :: Spring Boot :: (v1.5.2.RELEASE)
2017-03-24T22:33:59.266+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.256 INFO 16 --- [ main] pertySourceApplicationContextInitializer : Adding 'cloud' PropertySource to ApplicationContext
2017-03-24T22:33:59.381+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.359 WARN 16 --- [ main] o.c.r.o.s.cloud.AbstractCloudConnector : No suitable service info creator found for service elasticsearch Did you forget to add a ServiceInfoCreator?
2017-03-24T22:33:59.389+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.388 INFO 16 --- [ main] nfigurationApplicationContextInitializer : Adding cloud service auto-reconfiguration to ApplicationContext
2017-03-24T22:33:59.465+01:00 [APP/PROC/WEB/0] [OUT] 2017-03-24 21:33:59.451 INFO 16 --- [ main] com.bignibou.batch.Batch : Starting Batch on a1e87528-637d-4dae-62ab-0538e48fb49b with PID 16 (/home/vcap/app/BOOT-INF/classes started by vcap in /home/vcap/app)

which is not what I want...

So my questions are:

  • How can I configure my manifest in order for the batch app to be pushed properly without starting automatically - I just want the binaries pushed to cf so that I can run tasks later on...
  • How can I start my spring batch as a cf task on cloudfoundry?
balteo
  • 23,602
  • 63
  • 219
  • 412

2 Answers2

4

How can I configure my manifest in order for the batch app to be pushed properly without starting automatically - I just want the binaries pushed to cf so that I can run tasks later on... How can I start my spring batch as a cf task on cloudfoundry?

In order to run a task, you need an app to be deployed and to be completely staged (so there's a droplet). You can then cf run-task <app> <task-cmd>.

A couple ideas:

First option, you could use a manifest.yml like this:

---
applications:
- name: spring-music
  memory: 32M
  path: build/libs/spring-music.war
  health-check-type: none
  no-route: true
  command: while [ 1 == 1 ]; do sleep 9999; done
  buildpack: java_buildpack

This will setup an app with a very small memory limit and a command that essentially does nothing forever (the forever part is key so that the app will completely stage and start). We also set the health check to none and no route, so that no route is bound and no TCP health check is done. You can optionally set your build pack.

Then run cf push. The app should stage and start OK. After that you can cf run-task as many times as you want. You can optionally stop the app.

Second option, just push your app without making any special manifest.yml configurations. The app should stage properly, fail to start running then after it's failed you can cf stop the app. From there, you should be able to cf run-task as many times as you want.

You might also be able to use the v3 API directly, which would give you some additional flexibility, but all the interaction is manual via cf curl at this point.

If you want to see a concrete example of how to use cf run-task, see Selwyn's answer.

Daniel Mikusa
  • 13,716
  • 1
  • 22
  • 28
  • Thanks for the reply. Can you please explain what command to pass to the run task? Is it a `java -jar ...`? It seems the jar ends up exploded in the droplet... – balteo Mar 27 '17 at 06:42
  • 2
    It's literally the command that you want the task to run. It could be as simple as `echo 1`, but more likely `java -jar ...`. You might need to `cf ssh` into the container to work out the paths. The Java build pack doesn't put `java` on the PATH so you need to use a full or relative path when referencing it. You can also look at the output of staging the app, it will list the command that the build pack generated to run your app which also has path information. – Daniel Mikusa Mar 27 '17 at 12:45
  • Thank you @DanielMikusa ! It helped me to have "running" app in PCF for spring-batch (which runs once based on PCF scheduler and then process terminates) – user1697575 Dec 03 '18 at 19:45
  • @Daniel I am very confused on this. I have a spring boot 2.0 app that I want to run as a task on pcf. It has the spring-cloud-task project as a dependency and implements a CommandLineRunner interface. When I deploy the app to cloud foundry my command looks like this: pastebin.com/KHNw33JM How do I run this as a task? If I specify my own command in the manifest.yaml file it overwrite the generated start command contents and I cannot run a task without specifying a command... :/ – Selwyn Jan 06 '19 at 11:07
0

push your app like so to pcf

cf push --health-check-type none -p myapp-0.0.1-SNAPSHOT.jar myapp

use the special task launcher to start your app as a task. You can also append arguments after the ".JarLauncher arg1" that will show up as string[] args to your main method or CommandLineRunner

Runs the task using the Task runner. This support for tasks is built into the platform.

cf run-task myapp ".java-buildpack/open_jdk_jre/bin/java org.springframework.boot.loader.JarLauncher arg1" --name my-task

Note link below also shows you have to schedule it

Source: https://github.com/joshlong/cf-task-demo

Selwyn
  • 3,118
  • 1
  • 26
  • 33
  • This is all fine, you're missing the spirit of the original question though. The point was not just how to run a task, but how to run a task when all you have are one-off tasks to run (i.e. no long running task/app). – Daniel Mikusa Jan 06 '19 at 19:22
  • @Daniel fair points, I was personally stuck on the execution part and could not find any where on docs or stackoverflow on how to properly run a springboot up as a task on pcf, so I just documented it here. – Selwyn Jan 07 '19 at 05:47