How to run a custom grails command from grails executable jar/war - grails

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?

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.

Related

GRAILS --- what's the difference between commands grails war and gradle build?

I've heard you should type command
grails war
to build your project. I've thought to this point that Gradle is responsible for building the app in Grails. I've been doing the latter with conviction that my app is built. So what's the difference between
grails war
and
gradle build
?
Is it just that grails war is gradle build + create the war file?
It is not that simple to compare Grails and Gradle. Gradle is a build tool, while Grails is a web application framework.
However, Grails provides a command line tool, that's described in the docs:
Grails incorporates the powerful build system Gant, which is a Groovy wrapper around Apache Ant.
So, Grails does not use Gradle.
The basic usage of the grails command looks the following:
grails [environment]* [command name]
Where especially the command name parameter must be one out of predefined values. You can find the documentation on the war command here.
The basic usage of the gradle command looks the following:
gradle [option...] [task...]
The listed task parameters can be names of tasks created either in the build.gradle script or by plugins. All mentioned tasks and their respective task dependencies will be executed. If you use the Gradle War Plugin, it will generate a war task, which will also (transitively) be added as a task dependency of the build task. So whenever you call gradle build, a WAR file will be created. You can also call this task directly via gradle war.
EDIT
I just learned that Grails can or even does use Gradle beginning at a certain version. I even found a list on which Grails command calls which Gradle task. According to this list, calling grails war is equivalent to calling gradle assemble. The assemble task directly depends on the war task.
gradle build is a Gradle lifecycle task which usually consists of other tasks required to build a software like compileJava and other lifecycle tasks like assemble and check.
In case of Grails it delegates build to Gradle and to war task and it doesn't include check lifecycle during which unit tests will be executed.

How to run the grails default commands from a custom script in grails

I need to run the grails default commands like clean, compile, prod war using the code.
I am created a custom script in my project and i need to run these commands through codes.
My custom script is given below.
class CustomDeploy extends Script {
def run() {
// my code for running commands.
}
}
please help me.
You can create a Grails script, which has access to gradle.
http://docs.grails.org/latest/guide/commandLine.html#creatingCustomScripts

Test files in classpath

Ive created a folder resources under test/integration path to store data files that will be used during integration test phase.
I use then
private static final Resource jsonCategory = new ClassPathResource("resources/testdata.json")
It's working on local with simple test-app (no special options) however when jenkings takes the code and try to run the tests they are failing because
java.io.FileNotFoundException: class path resource [resources/testdata.json] cannot be resolved to URL because it does not exist
I've checked that files are in the same location ... but it seems that by unknown reason jenking cannot find them in the classpath.
Might this be possible? ... do you have any idea about how to make jenkins resolve the same classpath i have in my local?
By the way the command line that jenkins uses looks like:
grails -Dgrails.work.dir=/var/lib/jenkins/workspace/myapp-develop//target -Dgrails.env=TEST clean --non-interactive --plain-output --refresh-dependencies
What i can see is that those files are not in that work.dir ... shall them be there?
Try to put your file under test/resources/testdata.file and access it via new File("test/resources/testdata.file).

grails run 'plugin' tests from 'app'

I have a grails 'app' (say myapp) and a custom plugin (say myplugin) which are working together just fine.
I have some 'integration' tests in myapp and I can run them just fine from the app by doing cd myapp; grails test-app
I also have some 'integration' tests in myplugin and I can run them just fine from the plugin by doing cd myplugin; grails test-app
My problem is, that there does not seem to be any way to run myplugin test from myapp. E.g. what I'm trying to do is do a cd myapp; grails test-app to run both myapp and myplugin tests.
Is is even possible to do so?
Plugin tests aren't distributed by default, and if they were (it's certainly possible to manually or automatically get them included in the zip) you shouldn't treat the plugin as a Grails plugin project, but rather an installable plugin. Pretend the plugin isn't source code but compiled classes. The fact that the files' extensions are .groovy, .gsp, .java, etc. should be considered a coincidence.
The plugin's BuildConfig.groovy is not included with the plugin zip, and this likely has important dependencies and/or other info needed to run anything in the plugin. To run the tests, run them from the plugin source directory.

grails doesn't generate ant build file

I'm a beginner of Grail. I learned from the quick-start tutorial that the grails create-app will generate a build.xml for Ant.
I execute the command. but couldn't get the build.xml file. Is there missing any steps? Any help is appreciated.
As Don said you really don't need it. But if you want the build.xml that used to be automatically created, run
grails integrate-with --ant
See http://grails.org/doc/latest/ref/Command%20Line/integrate-with.html
Grails may generate a build.xml file "under the hood", but there's no reason for you to worry about this, because you don't work with Ant directly when developing with Grails. Instead you use Grails commands (like create-app) to create, build, test, deploy, etc. Grails applications.
The create-app command creates a new application. To run the application, execute the command grails run-app from the root directory of the project.

Resources