kubernetes-client: Race condition triggered in java-generator for very big schemas
Describe the bug
Using different versions of Java produce different errors with the java-generator
Fabric8 Kubernetes Client version
SNAPSHOT
Steps to reproduce
curl -Ls https://raw.githubusercontent.com/istio/istio/master/manifests/charts/base/crds/crd-all.gen.yaml -o istio.yaml
sdk use java 11.0.17-tem
jbang io.fabric8:java-generator-cli:6.3.1 --add-extra-annotations --source istio.yaml --target ./src
Produces a stack-trace like:
Exception in thread "main" java.lang.AssertionError
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:603)
at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:678)
at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:737)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:159)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:661)
at io.fabric8.java.generator.CRGeneratorRunner.runOnSingleSource(CRGeneratorRunner.java:82)
at io.fabric8.java.generator.CRGeneratorRunner.run(CRGeneratorRunner.java:66)
at io.fabric8.java.generator.cli.GenerateJavaSources.run(GenerateJavaSources.java:77)
at picocli.CommandLine.executeUserObject(CommandLine.java:2026)
at picocli.CommandLine.executeHelpRequest(CommandLine.java:2012)
at picocli.CommandLine.executeHelpRequest(CommandLine.java:1983)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2268)
at picocli.CommandLine$RunLast.execute(CommandLine.java:2417)
at picocli.CommandLine.execute(CommandLine.java:2170)
at io.fabric8.java.generator.cli.GenerateJavaSources.main(GenerateJavaSources.java:81)
Caused by: java.lang.AssertionError
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:603)
at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:678)
at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:737)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:159)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:661)
at io.fabric8.java.generator.CRGeneratorRunner.lambda$runOnSingleSource$2(CRGeneratorRunner.java:93)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290)
at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Caused by: java.lang.AssertionError: I am not a child of my parent.
at com.github.javaparser.printer.DefaultPrettyPrinterVisitor.printOrphanCommentsBeforeThisChildNode(DefaultPrettyPrinterVisitor.java:1799)
at com.github.javaparser.printer.DefaultPrettyPrinterVisitor.visit(DefaultPrettyPrinterVisitor.java:1584)
at com.github.javaparser.printer.DefaultPrettyPrinterVisitor.visit(DefaultPrettyPrinterVisitor.java:53)
at com.github.javaparser.ast.expr.NormalAnnotationExpr.accept(NormalAnnotationExpr.java:74)
at com.github.javaparser.printer.DefaultPrettyPrinterVisitor.printMemberAnnotations(DefaultPrettyPrinterVisitor.java:94)
at com.github.javaparser.printer.DefaultPrettyPrinterVisitor.visit(DefaultPrettyPrinterVisitor.java:268)
at com.github.javaparser.printer.DefaultPrettyPrinterVisitor.visit(DefaultPrettyPrinterVisitor.java:53)
at com.github.javaparser.ast.body.ClassOrInterfaceDeclaration.accept(ClassOrInterfaceDeclaration.java:98)
at com.github.javaparser.printer.DefaultPrettyPrinterVisitor.visit(DefaultPrettyPrinterVisitor.java:215)
at com.github.javaparser.printer.DefaultPrettyPrinterVisitor.visit(DefaultPrettyPrinterVisitor.java:53)
at com.github.javaparser.ast.CompilationUnit.accept(CompilationUnit.java:133)
at com.github.javaparser.printer.DefaultPrettyPrinter.print(DefaultPrettyPrinter.java:95)
at com.github.javaparser.ast.Node.toString(Node.java:322)
at io.fabric8.java.generator.WritableCRCompilationUnit.writeAllJavaClasses(WritableCRCompilationUnit.java:58)
at io.fabric8.java.generator.CRGeneratorRunner.lambda$runOnSingleSource$1(CRGeneratorRunner.java:93)
... 10 more
Additional issues can be experienced by mixing and matching Java and kubernetes-client
versions, another example stack trace is:
java.lang.ArrayIndexOutOfBoundsException
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:490)
at java.base/java.util.concurrent.ForkJoinTask.getThrowableException(ForkJoinTask.java:603)
at java.base/java.util.concurrent.ForkJoinTask.reportException(ForkJoinTask.java:678)
at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:737)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateParallel(ForEachOps.java:159)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateParallel(ForEachOps.java:173)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:497)
at java.base/java.util.stream.ReferencePipeline$Head.forEach(ReferencePipeline.java:661)
at io.fabric8.java.generator.FileJavaGenerator.runOnSingleSource(FileJavaGenerator.java:87)
at io.fabric8.java.generator.FileJavaGenerator.run(FileJavaGenerator.java:71)
at io.fabric8.java.generator.cli.GenerateJavaSources.lambda$run$0(GenerateJavaSources.java:132)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1541)
at io.fabric8.java.generator.cli.GenerateJavaSources.run(GenerateJavaSources.java:132)
at picocli.CommandLine.executeUserObject(CommandLine.java:2026)
at picocli.CommandLine.executeHelpRequest(CommandLine.java:2012)
at picocli.CommandLine.executeHelpRequest(CommandLine.java:1983)
at picocli.CommandLine$AbstractParseResultHandler.execute(CommandLine.java:2268)
at picocli.CommandLine$RunLast.execute(CommandLine.java:2417)
at picocli.CommandLine.execute(CommandLine.java:2170)
at io.fabric8.java.generator.cli.GenerateJavaSources.main(GenerateJavaSources.java:136)
Caused by: java.lang.ArrayIndexOutOfBoundsException: Index 8 out of bounds for length 7
at java.base/java.util.ArrayList.add(ArrayList.java:487)
at java.base/java.util.ArrayList.add(ArrayList.java:499)
at com.github.javaparser.ast.Node.setParentNode(Node.java:435)
at com.github.javaparser.ast.NodeList.setAsParentNodeOf(NodeList.java:559)
at com.github.javaparser.ast.NodeList.own(NodeList.java:81)
at com.github.javaparser.ast.NodeList.add(NodeList.java:73)
at com.github.javaparser.ast.nodeTypes.NodeWithAnnotations.addAnnotation(NodeWithAnnotations.java:59)
at io.fabric8.java.generator.nodes.JObjectExtraAnnotations.addExtraAnnotations(JObjectExtraAnnotations.java:36)
at io.fabric8.java.generator.nodes.JObject.generateJava(JObject.java:156)
at io.fabric8.java.generator.nodes.JObject.generateJava(JObject.java:168)
at io.fabric8.java.generator.nodes.JArray.generateJava(JArray.java:51)
at io.fabric8.java.generator.nodes.JObject.generateJava(JObject.java:168)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:195)
at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:177)
at java.base/java.util.Spliterators$ArraySpliterator.forEachRemaining(Spliterators.java:948)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:474)
at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:913)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:578)
at io.fabric8.java.generator.CRGeneratorRunner.validateAndAggregate(CRGeneratorRunner.java:112)
at io.fabric8.java.generator.CRGeneratorRunner.generate(CRGeneratorRunner.java:97)
at io.fabric8.java.generator.FileJavaGenerator.lambda$runOnSingleSource$3(FileJavaGenerator.java:95)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1655)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:484)
at java.base/java.util.stream.ForEachOps$ForEachTask.compute(ForEachOps.java:290)
at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1020)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1656)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1594)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:183)
Expected behavior
The generator correctly run and generate the sources.
Runtime
other (please specify in additional context)
Kubernetes API Server version
1.25.3@latest
Environment
Windows, Linux, macOS
Fabric8 Kubernetes Client Logs
No response
Additional context
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 20 (10 by maintainers)
Thanks to @mariofusco that found out that the race condition is happening on this node incorrectly encoded: https://github.com/fabric8io/kubernetes-client/pull/4849/files#diff-a297bc569285c2dbea4f4c5d02362681ee8ea3be3156d3df20ea6d71b3dbb712R45
Thanks again for the support to everyone involved!
Thanks a lot for this honest explanation @jlerbsc and for staying involved in this issue/discussion, much appreciated!
Tomorrow both me and @mariofusco are probably going to spend a few more hours trying to narrow down this issue. If nothing comes up my proposed action plan would be to:
parallelStream
in favor of sequential processingCompilationUnits
here directly rendering theString
contentThis action is surely going to impact the performance, but, at this stage, we should favor the correctness and get back to performance when we see the need.