apache / apache/grails-core

Grails 5.0.0.M2: inconsistent classpath in multi-module project with transitive plugins?

Open
#11,566 10 comments 0 reactions 1 assignee Claimed by @niravassar View on GitHub
status: awaiting feedback
Dominant language
Groovy
Stars
2.9k
Forks
975
Avg merge
1d 22h
Merged PRs (30d)
92

Description

We are migrating and trying out and older Grails 3.0.x application with Grails 4.1.0.M1. We have a not so trivial setup in a mono-repository structure which includes multiple grails applications, which together form some kind of platform, and some grails plugins that are shared by these applications. The repository itself is a multi-module gradle build.

For example we have some project dependencies like this:
pluginA --(depends)--> common-plugin
pluginB --(depends)--> common-plugin
myapp --(depends)--> [pluginA, pluginB]

We are developing with exploded-mode (each plugin has a gradle.properties file with `exploded=true`).

Some applications are working great in Grails 4.1.0.M1 but in one we are getting the following exception:
```
groovy.lang.MissingMethodException: No signature of method: xxx.web.upload.validation.UploaderOptionsRegistry.register() is applicable for argument types: (String, xxx.web.upload.validation.UploaderOptions) values: [default, xxx.web.upload.validation.UploaderOptions@72a26048]
Possible solutions: register(java.lang.String, xxx.web.upload.validation.UploaderOptions)
The following classes appear as argument class and as parameter class, but are defined by different class loader:
xxx.web.upload.validation.UploaderOptions (defined by 'jdk.internal.loader.ClassLoaders$AppClassLoader@7aec35a' and 'org.springframework.boot.devtools.restart.classloader.RestartClassLoader@64e844ce')
If one of the method suggestions matches the method you wanted to call,
then check your class loader setup.
```

Unfortunately I am not very experienced in the class loader debugging domain and I can't reproduce this exception in newly created module-module grails build. Also our real applications are fairly complex, so the exception might occur only in our specific constellation.

What I did discover though is the following: I did a print of the bootRun task's classpath and it seems that event though the plugins are exploded, sometimes the .jar AND the exploded classes folder is added. From my observation this seems to happen only when there is a dependency chain like _myapp -> plugin2 -> plugin1_ and not in a simple case of _myapp -> plugin_.

To show this, I created the example application with a multi-module gradle build. When running the application, the following is printed during bootRun:
```
C:\Users\david\IdeaProjects\grails-multi-module-problem\myapp\src\main\resources
C:\Users\david\IdeaProjects\grails-multi-module-problem\myapp\grails-app\views
C:\Users\david\IdeaProjects\grails-multi-module-problem\myapp\grails-app\i18n
C:\Users\david\IdeaProjects\grails-multi-module-problem\myapp\grails-app\conf
C:\Users\david\IdeaProjects\grails-multi-module-problem\myapp\build\classes\java\main
C:\Users\david\IdeaProjects\grails-multi-module-problem\myapp\build\classes\groovy\main
C:\Users\david\IdeaProjects\grails-multi-module-problem\myapp\gsp-classes
C:\Users\david\IdeaProjects\grails-multi-module-problem\myplugin2\build\libs\myplugin2-0.1.jar
C:\Users\david\IdeaProjects\grails-multi-module-problem\myplugin2\build\classes\groovy\main
C:\Users\david\IdeaProjects\grails-multi-module-problem\myplugin\build\resources\main
C:\Users\david\IdeaProjects\grails-multi-module-problem\myplugin\build\classes\groovy\main
```

As you can see myplugin2 is added as a jar-file to the classpath and also the classes folder. What also seems suspicious is that in the case of myplugin the resources folder is added to the classpath, but not in the case of myplugin2.

Since some classes of the plugins are available multiple times (through jar file and classes folder), I suspect this might be the problem of my initial exception about the class loader. But I can't be sure, since I could never reproduce it in a simple project.

Edit: the problem doesn't seem to happen when using the bootRun task directly, as it seems the exploded-configuration doesn't affect bootRun. I've been running the application through the run configuration in IntelliJ.

### Task List

- [x] Steps to reproduce provided
- [x] Stacktrace (if present) provided
- [x] Example that reproduces the problem uploaded to Github
- [x] Full description of the issue provided (see below)

### Steps to Reproduce

1. checkout exaple application
2. run application
3. see gradle output (println) from build.gradle during bootRun task

### Environment Information

- **Operating System**: Windows 10
- **Grails Version:** Grails 4.1.0.M1
- **JDK Version:** 11

### Example Application

https://github.com/davidkron/grails-multi-module-problem

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.