Open chrisbrookes opened 7 years ago
Workaround that forces ordering of assetCompile on each Grails project - in a root build.gradle:
def grailsProjects() {
[project(':app1'), project(':app2'), project(':app3')]
}
def lastProject
grailsProjects().each { grailsProject ->
grailsProject.afterEvaluate {
if (lastProject) {
tasks.getByPath("$grailsProject.path:assetCompile").mustRunAfter tasks.getByPath("$lastProject.path:assetCompile")
}
lastProject = grailsProject
}
}
Funky, but seems to work.
I ran into this and bumped the version to 2.14.7
. Seems to have resolved the issue for me.
After we made all of our projects use the same plugin version, 3.0.11
, this is happening very frequently now. I believe this issue to still be present.
Caused by: java.util.ConcurrentModificationException: (No message provided)Close stacktrace
at asset.pipeline.AssetCompiler.getAllAssets(AssetCompiler.groovy:384)
at asset.pipeline.AssetCompiler.compile(AssetCompiler.groovy:133)
at asset.pipeline.AssetCompiler$compile.call(Unknown Source)
at asset.pipeline.gradle.AssetCompile.compile(AssetCompile.groovy:235)
at org.gradle.internal.reflect.JavaMethod.invoke(JavaMethod.java:73)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.doExecute(StandardTaskAction.java:46)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:39)
at org.gradle.api.internal.project.taskfactory.StandardTaskAction.execute(StandardTaskAction.java:26)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:794)
at org.gradle.api.internal.AbstractTask$TaskActionWrapper.execute(AbstractTask.java:761)
...
Working off @chrisbrookes approach I eventually ran into a dependency loop issue when a project required a jar from another project.
Gradle will not run tasks in parallel that have overlapping output directories. This can be used to serialize the tasks and avoid dependency issues:
getAllprojects().findAll { proj ->
proj.afterEvaluate {
try {
def assetTask = tasks.getByPath("$proj.path:assetCompile")
assetTask.outputs.dir "${rootProject.buildDir}/asset-serialize"
} catch(UnknownTaskException e) {}
}
}
Same for gradle 7.6.4 and grails 6.1.0
Caused by: java.util.ConcurrentModificationException
at asset.pipeline.AssetCompiler.getAllAssets(AssetCompiler.groovy:380)
at asset.pipeline.AssetCompiler.compile(AssetCompiler.groovy:131)
at asset.pipeline.AssetCompiler$compile$0.call(Unknown Source)
at asset.pipeline.gradle.AssetCompile.compile(AssetCompile.groovy:138)
I think we could try here
def getAllAssets() {
def filesToProcess = []
// FIXME Create a copy of resolvers here
AssetPipelineConfigHolder.resolvers.each { resolver ->
def files = resolver.scanForFiles(getExcludesForPathKey(resolver.name), getIncludesForPathKey(resolver.name))
filesToProcess += files
}
filesToProcess.unique { a, b -> a.path <=> b.path }
return filesToProcess //Make sure we have a unique set
}
Or use CopyOnWriteArrayList
I can send a PR with either way when repo owners confirm
Hotfix for build.gradle.kts in case you don't have a lot of grails modules
// In :module2
tasks.withType(AssetCompile).configureEach {
dependsOn ":module1:assetCompile"
}
Steps to Reproduce
~/.gradle/gradle.properties
:Expected Behaviour
Should build all Grails apps with no errors.
Actual Behaviour
Intermittent errors (sometime it works), not always the same message. Stacktraces and error examples below, but they all seem to happen in this area:
java.util.ConcurrentModificationException
java.lang.ArrayIndexOutOfBoundsException / Cannot get property 'name' on null object
Workaround is to not use parallel builds, but with our large multi-project build (that has several Grails projects as well as plain Java projects etc), we are forfeiting large build time savings.
Environment Information