CORE-57 - Surface javac diagnostics for runtime compile failures#180
CORE-57 - Surface javac diagnostics for runtime compile failures#180sam-ross wants to merge 1 commit into
Conversation
|
KealanTolandChronicle
left a comment
There was a problem hiding this comment.
Overall looks good, just one small comment about thread safety string appending, approved!
| fileManagerMap.put(classLoader, fileManager); | ||
| } | ||
| final Map<String, byte[]> compiled = compileFromJava(className, javaCode, printWriter, fileManager); | ||
| final CompilationResult compilation = compileFromJavaResult(className, javaCode, printWriter, fileManager); |
There was a problem hiding this comment.
Is it worth having the compilation result examined from within the compileFromJavaResult() method to reduce complexity in this method?
Also this way, changing of the method signature may not be required as it can still return the Map<String, byte[]> of the compiled classes if it is a success and the className exists in the map of compiled (as its provided to the compileFromJava() method. Then to allow for diagnostics to be used, you can pass in the StringBuilder on the call - this can determine whether the caller actually cares about diagnostics and add the detail if it's asked for
There was a problem hiding this comment.
Good point @benbonavia, I’ve moved the compile-result checks out of loadFromJava(...) into a private compileFromJavaOrThrow(...) helper, so the caller method is simpler while keeping the existing package-private compileFromJava(...) behavior unchanged.
I did not move the throwing directly into compileFromJavaResult(...) because that method is also used to preserve the existing compileFromJava(...) contract of returning Map<String, byte[]>, including an empty map on javac failure.
I also kept CompilationResult rather than passing diagnostics in as an out-parameter. loadFromJava(...) needs the success flag as well as the diagnostics so it can distinguish “javac failed” from “javac succeeded but did not produce the requested className”. That distinction is the main CORE-57 fix, so I think keeping it explicit is clearer than inferring it from a map plus a mutable diagnostics argument.
I’ve also since split the rest of loadFromJava(...) into smaller helpers for the Sonar complexity issue: cache lookup, file-manager lookup, class definition, class-file writing, and final loaded-class lookup are now separated while preserving the existing locking behavior.
benbonavia
left a comment
There was a problem hiding this comment.
Please reduce the complexity as per the sonar analysis
|
Hi @benbonavia, this is ready for re-review. I’ve refactored the method Sonar flagged at loadFromJava(...). The cache lookup, file-manager lookup, compile-result validation, class definition loop, class-file writing, and final lookup are now split into private helpers. The public method is now a short orchestration path, while preserving the existing synchronisation and duplicate-definition guard behaviour. |



CORE-57 - Surface javac diagnostics for runtime compile failures
Summary
Surfaces javac diagnostics directly when runtime compilation fails, instead of masking the real compile failure as a generated-class
ClassNotFoundException.Context
CachedCompiler.compileFromJava(...)returns an empty map when javac fails. Previously,CachedCompiler.loadFromJava(...)did not distinguish that failure from a successful compile with no classes to define, and still calledclassLoader.loadClass(className).With module-style classloaders, this can produce a misleading
ClassNotFoundExceptionfor the generated class name, hiding the actual javac diagnostics such as missing symbols or unresolved types.Changes
CompilationResultpath inCachedCompiler.compileFromJava(...)behavior.PrintWriter.loadFromJava(...)to throw diagnosticClassNotFoundExceptionimmediately when javac compilation fails.defineClass(...)instead of falling through toclassLoader.loadClass(...).Verification