-->

Running a Grails 3 project with in line plugins

2019-07-05 14:43发布

问题:

I'm almost certain this is a stupid question but I do not know the answer to it :) I'm in the process of upgrading a project of mine from Grails 2.5 to 3 and trying to get to grips with the new inline plugin structure, the old way was working fine but struggling to get the new way working.

I have a directory structure as follows:


    /
    /settings.gradle
    /myApp             #contains a grails 3 application
    /myPlugin1         #contains a grails 3 plugin
    /myPlugin2         #contains a grails 3 plugin

/settings.gradle contains:


    include 'myPlugin1', 'myPlugin2'
    project(':myPlugin1').projectDir = new File('myPlugin1')
    project(':myPlugin2').projectDir = new File('myPlugin2')

My build.gradle in /myApp contains:


    compile project(":myPlugin1"), project(":myPlugin2")

The above, as far as I can tell is correct, because when I run 'gradle build' from the root it builds the plugins successfully. However, when I run


    grails run-app

From the myApp directory I get the following error:


    FAILURE: Build failed with an exception.

    * Where:
    Build file '/Users/donald/myApp/build.gradle' line: 76

    * What went wrong:
    A problem occurred evaluating root project 'myApp'.
    > Project with path ':myPlugin1' could not be found in root project 'myApp'.

    * Try:
    Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

    BUILD FAILED

    Total time: 1.572 secs
    | Error Error initializing classpath: Project with path ':myPlugin1' could not be found in root project 'myApp'. (Use --stacktrace to see the full trace)

So the question is really - how do I get my application to look in the right place for my inline plugins? I have tried creating a settings.gradle inside myApp and I get other errors like this:


    Plugin 'io.spring.dependency-management' is already on the script classpath. Plugins on the script classpath cannot be applied in the plugins {} block. Add  "apply plugin: 'io.spring.dependency-management'" to the body of the script to use the plugin.

Thanks in advance.

回答1:

Context

I created a multi-project test at github in order to provide a working solution. This multi-project test was created using Grails 3.2.11 and Java 1.7. You can download it from here: https://github.com/esalomon/multi-project-test3

Next you will find the instructions for its creation.

Projects creation

1 The multi-project folder is created:

mkdir multi-project-test3
cd multi-project-test3

2 The Grails Application and the plugins are created:

grails create-app myApp
grails create-plugin myPlugin1
grails create-plugin myPlugin2

3 The myApp's settings.gradle file is deleted:

rm myApp/settings.gradle

4 The multi-project's settings.gradle file is created with the next contents:

include 'myApp', 'myPlugin1', 'myPlugin2'
project(':myApp').name = 'myApp'

5 The myApp's build.gradle file is updated with the inline plugin references:

grails {
    plugins {
        compile project(":myPlugin1")
        compile project(":myPlugin2")
    }
}

Project test

Three controllers are created, one in each Grails project in order to test the application:

1 The myApp's controller is created:

cd myApp
grails create-controller myAppController

2 The myApp's controller is updated with the next code:

package myapp

class AppController {

    def index() {
        render "[${new Date()}] This is the myApp's appController's index response."
    }
}

3 The myPlugin1's controller is created:

cd myPlugin1
grails create-controller myPlugin1Controller

4 The myPlugin1's controller is updated with the next code:

package myplugin1

class Plugin1Controller {

    def index() {
        render "[${new Date()}] This is the myPlugin1's plugin1Controller's index response."
    }
}

5 The myPlugin2's controller is created:

cd myPlugin2
grails create-controller myPlugin2Controller

6 The myPlugin2's controller is updated with the next code:

package myplugin2

class Plugin2Controller {

    def index() {
        render "[${new Date()}] This is the myPlugin2's plugin2Controller's index response."
    }
}

Project execution

When the myApp project is executed with the run-app command, it displays the main Grails page with the three controllers, one from each Grails project:

cd myApp
grails run-app
| Running application...
Grails application running at http://localhost:8080 in environment: development

Conclusion

I hope this can help others, regards.