Non deterministic behavior with exceptions.
Summary of problem
We have a big java project in which we use spotless, but sometimes we get a "ClassNotFound" exception on buildRelase task.
The not found class and when it happens is totally random, there is no underlying cause.
In 50% of cases it runs successfully, without errors, in the rest it crashes.
Gradle version
- localhost: 8.3
- GitLab CI/CD: 7.5
- another colleague localhost: 8.4
Spotless version
- 6.20
- 6.23.3
Operating system and version
- Windows 10/11
- Ubuntu 23
- Ubuntu 22
- Gitlab CI/CD - Docker image: gradle:7.5.0-jdk18
Fromatting (Eclipse) Config
https://gist.github.com/N3cr0s1s/00bbc1bc6fbbe6da5e29e54a19defe35
Stacktrace
> Task :base-utilities:spotlessJava FAILED
Step 'eclipse jdt formatter' found problem in 'src/test/java/com/horvatha/hash/Base64Encode.java':
null
java.lang.reflect.InvocationTargetException
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:119)
at java.base/java.lang.reflect.Method.invoke(Method.java:577)
at com.diffplug.spotless.extra.java.EclipseJdtFormatterStep.lambda$apply$0(EclipseJdtFormatterStep.java:67)
at com.diffplug.spotless.FormatterFunc$NeedsFile.apply(FormatterFunc.java:154)
at com.diffplug.spotless.FormatterStepImpl$Standard.format(FormatterStepImpl.java:82)
at com.diffplug.spotless.FormatterStep$Strict.format(FormatterStep.java:103)
at com.diffplug.spotless.Formatter.compute(Formatter.java:246)
at com.diffplug.spotless.PaddedCell.calculateDirtyState(PaddedCell.java:203)
at com.diffplug.spotless.PaddedCell.calculateDirtyState(PaddedCell.java:190)
at com.diffplug.gradle.spotless.SpotlessTaskImpl.processInputFile(SpotlessTaskImpl.java:105)
at com.diffplug.gradle.spotless.SpotlessTaskImpl.performAction(SpotlessTaskImpl.java:89)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
at java.base/java.lang.reflect.Method.invoke(Method.java:577)
<org.gradle.internal.... too many lines>
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.NoClassDefFoundError: org/eclipse/jdt/internal/compiler/impl/CharConstant
at org.eclipse.jdt.internal.compiler.ast.CharLiteral.computeValue(CharLiteral.java:79)
at org.eclipse.jdt.internal.compiler.ast.CharLiteral.<init>(CharLiteral.java:28)
at org.eclipse.jdt.internal.compiler.parser.Parser.consumeToken(Parser.java:10430)
at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:13114)
at org.eclipse.jdt.internal.compiler.parser.Parser.parse(Parser.java:13508)
at org.eclipse.jdt.internal.compiler.ast.MethodDeclaration.parseStatements(MethodDeclaration.java:251)
at org.eclipse.jdt.internal.compiler.ast.TypeDeclaration.parseMethods(TypeDeclaration.java:1143)
at org.eclipse.jdt.core.dom.CompilationUnitResolver.parse(CompilationUnitResolver.java:656)
at org.eclipse.jdt.core.dom.ASTParser.internalCreateAST(ASTParser.java:1264)
at org.eclipse.jdt.core.dom.ASTParser.createAST(ASTParser.java:868)
at org.eclipse.jdt.internal.formatter.DefaultCodeFormatter.parseSourceCode(DefaultCodeFormatter.java:317)
at org.eclipse.jdt.internal.formatter.DefaultCodeFormatter.prepareFormattedCode(DefaultCodeFormatter.java:221)
at org.eclipse.jdt.internal.formatter.DefaultCodeFormatter.format(DefaultCodeFormatter.java:185)
at org.eclipse.jdt.internal.formatter.DefaultCodeFormatter.format(DefaultCodeFormatter.java:167)
at com.diffplug.spotless.extra.glue.jdt.EclipseJdtFormatterStepImpl.format(EclipseJdtFormatterStepImpl.java:43)
at java.base/jdk.internal.reflect.DirectMethodHandleAccessor.invoke(DirectMethodHandleAccessor.java:104)
... 130 more
Caused by: java.lang.ClassNotFoundException: org.eclipse.jdt.internal.compiler.impl.CharConstant
at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:445)
at com.diffplug.spotless.FeatureClassLoader.findClass(FeatureClassLoader.java:79)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
... 146 more
Same build, different class not found:
Caused by: java.lang.NoClassDefFoundError: org/eclipse/jdt/internal/compiler/parser/Scanner$ScanContextDetector
Caused by: java.lang.ClassNotFoundException: org.eclipse.jdt.internal.compiler.parser.Scanner$ScanContextDetector
Thanks for the bug report.
- does it happen with just a regular
spotlessApply/spotlessCheck, or only withbuildRelase - This is besides the point, but I wouldn't expect a release task to use Spotless...
With just a regular spotlessApply / spotlessCheck we don't get this exception,but not only the buildRelease task produces this error.
There is such a task that generates classes from an xsd, and sometimes it also throws an error.
ext.stGeneratePmGraph = { graphPath, dynamicArguments = [], graphDir = '', taskName = 'stGeneratePmGraph' ->
task "$taskName"( type: JavaExec ) {
mainClass = 'xxx.xxx.SchemaToolApp'
classpath = configurations.schemaTool
args = [
'CreatePmGraph',
resourceLocator( graphPath, graphDir ),
sources
] + dynamicArguments
jvmArgs = []
finalizedBy 'spotlessJavaApply'
}
}
In the meantime, we discovered how to reproduce the error, by running 2 gradle tasks in one command, e.g.
gradle cleanAll buildRelease
And the release task runs spotless because they are depends on the compile task of the modules. Like this:
// ---------- formatting ----------
spotless {
java {
eclipse().configFile( '../../formatting.xml' )
lineEndings(com.diffplug.spotless.LineEnding.WINDOWS)
}
}
compileJava.dependsOn {
if (project.hasProperty('ci')) {
[] // as a temporary solution, we use a flag so that it does not run in a CI environment
}
else {
tasks.spotlessJavaApply
}
}