1
votes

I'm using grails 3.2.8. I am generating an executable war file from my grails project that has web functionality in it. However, I've also written some custom grails commands that I'd like to be able to run in production (as cron jobs) from an executable jar/war that I build from the same grails project. I can run them in my development environment as "grails run-cmd ...", but I'd like to be able to deploy an executable jar/war file and run the custom command from the executable jar/war. In other words, I want to deploy a war file for web stuff to one server, and I want to deploy an executable jar file for some cron jobs all from a single grails project. I know how build/run the war file--grails makes that easy. However, I really have no idea how to generate an executable jar file from my project that allows me to run my custom grails commands as cron jobs. Can anyone tell me how to do this?

1
Thanks for the quick response, but the solutions discussed in the link you posted really aren't what I'm looking for. The best solution I have right now (which is also mentioned in your link) is to just deploy my grails project in its source form to production and run "grails run-command" from my cron jobs, but I'd really prefer to package it up as a single executable jar and run my cron jobs that way. It seems like this should be possible, but I don't know how to do it (and the grails docs are no help here, either). - Jon Oler

1 Answers

2
votes

I have found something that seems to work. I've modified the Application.groovy class in my grails project to look like this:

import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
import grails.ui.command.GrailsApplicationContextCommandRunner

class Application extends GrailsAutoConfiguration {
  static void main(String[] args) {
    if (args.length > 0 && args[0] == "run-command") {
      // If the first argument is 'run-command', then we just want to run a command as if we were running
      // 'grails run-command <grails-custom-command> <args>...'. We are adding the capability of running commands here
      // because this is the class that is run from the executable war generated by running 'grails war'. If we just do the same
      // thing that grails does to run a command, then the commands seem to execute just fine.
      args = args.tail()
      // The following code is copied from GrailsApplicationContextCommandRunner.main(). It is what grails does to make
      // 'grails run-command' work from the grails console/command line. When upgrading grails, it may be necessary to update
      // this code...
      def runner = new GrailsApplicationContextCommandRunner(args[0], Application)
      runner.run(args)
    } else {
      GrailsApp.run(Application, args)
    }
  }
}

I have also changed the dependency in build.gradle for the grails-console dependency from 'console' to 'compile':

compile "org.grails:grails-console" // changed from 'console' dependency since we want to be able to run custom grails commands from the executable jar/war

This is because the GrailsApplicationContextCommandRunner class is in grails-console.

With these changes in place, I can still run the war file with:

java -jar myWarFile.war

However, I am now also able to run my custom commands with the exact same war file like this:

java -jar myWarFile.war run-command my-command <command args>

It seems like there should be a better way to do this, so it would be great if the grails team would comment (and if there isn't a better way, then the grails team should consider adding running custom commands from the executable war file as a grails feature request), but I do seem to be able to run my custom commands from the executable war file this way.