Open sdedic opened 1 year ago
Looks like related to to annotation processing because of the mention TypeElementVisitor
in the error log.
Is the build successful in Eclipse? If the application can be launched successfully in Eclipse, then the build should be fine. @sdedic
Would you please take a look as well? @testforstephen
Good point: although the project demo4
opens fine (no errros in Problems after project open), Build/run actions in Eclipse behave strangely (note: I do not routinely use Eclipse, so I may need guidance in obtaining logs etc):
Project | Build Automatically
is disabled, Build Project
action has (seemingly) no effect, run fails with java.lang.ClassNotFoundException: com.example4.Application
.No build
or bin
directory is created. Build Automatically
is enabled, bin
is created on project open and app launch works.Actually the behaviour with explicit builds (Automatic build disabled) is quite erratic. I tried to close/open project(s) and restart Eclipse IDE
bin
is created on project open. Sometimes not.build
is created on IDE start or project open, with just resources. In one test run, neither build
or bin
appeared no matter what I've tried (Build Project, Build All, Clean + Build, ...)Build Project
produces classes into bin
folder, but sometimes not - there are just resources in build
No errors are logged in Problems window or Error Log. I can't find a pattern in the behaviour.Note: I mentioned Eclipse just because I thought the compilation + problems engine is mostly the same as in vscode lang server for java, so I was surprised with the behaviour difference.
This is a known issue of ECJ compiler, see https://github.com/eclipse-jdt/eclipse.jdt.core/issues/543.
ECJ requires all indirect dependencies in the build path when compiling a project. But in your sample micronaut project, there is a dependency micronaut-context-4.0.1.jar (io.micronaut.scheduling.async.validation.AsyncTypeElementVisitor)
that references an implicit dependency micronaut-core-processor-4.0.1.jar (io.micronaut.inject.visitor.TypeElementVisitor)
, which cannot be found in the project build path.
The workaround is to explicitly add the missing dependency micronaut-core-processor
to the project dependencies list.
implementation('io.micronaut:micronaut-core-processor:4.0.1')
@testforstephen hm ! micronaut-context
currently lists micronaut-core-processor
just as compileOnly
dependency (which is not exported to consumers ?) - would it help if it was present also as the micronaut-context
s annotationProcessor
or compileOnlyApi
dependency ?
Anyway, gradle buildsys is apparently able to build the project, it seems to collect "somehow" the dependencies properly - shouldn't be the project info on par with that ?
To anwer myself. No: annotationProcessor
is not transitive, and compileOnlyApi
would leak the core-processor to application's compile classpath (as opposed to be only available to APs as a runtime dependency).
The suggested workaround is not 'correct' as well, as it leaks internal AP dependencies to the consuming project(s).
BTW the issue affects also Maven (see demom4)
which has a different annotation CP construction rules (and also does not work when imported to vscode)
this is unfortunate behaviour of Eclipse JDT. No wonder nobody it is rarely used when annotation processors are used extensively.
I have tried to implement a workaround https://github.com/micronaut-projects/micronaut-core/pull/9634 in Micronaut, but this may come up again as this is clearly broken behaviour of the IDE
So 4.0.2 is out and the build problem is gone, but now it doesn't look like annotation processors are running at all
So 4.0.2 is out and the build problem is gone, but now it doesn't look like annotation processors are running at all
Here is the exception log for this failure.
!ENTRY org.eclipse.jdt.apt.pluggable.core 4 1 2023-08-02 14:39:18.047
!MESSAGE Exception thrown by Java annotation processor io.micronaut.annotation.processing.BeanDefinitionInjectProcessor@237cb634
!STACK 0
java.lang.Exception: org.eclipse.jdt.internal.compiler.problem.AbortCompilation:
at org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:172)
at org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.round(RoundDispatcher.java:124)
at org.eclipse.jdt.internal.compiler.apt.dispatch.BaseAnnotationProcessorManager.processAnnotations(BaseAnnotationProcessorManager.java:172)
at org.eclipse.jdt.internal.apt.pluggable.core.dispatch.IdeAnnotationProcessorManager.processAnnotations(IdeAnnotationProcessorManager.java:138)
at org.eclipse.jdt.internal.compiler.Compiler.processAnnotations(Compiler.java:953)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:450)
at org.eclipse.jdt.internal.compiler.Compiler.compile(Compiler.java:426)
at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:406)
at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.compile(BatchImageBuilder.java:214)
at org.eclipse.jdt.internal.core.builder.AbstractImageBuilder.compile(AbstractImageBuilder.java:338)
at org.eclipse.jdt.internal.core.builder.BatchImageBuilder.build(BatchImageBuilder.java:79)
at org.eclipse.jdt.internal.core.builder.JavaBuilder.buildAll(JavaBuilder.java:276)
at org.eclipse.jdt.internal.core.builder.JavaBuilder.build(JavaBuilder.java:188)
at org.eclipse.core.internal.events.BuildManager$2.run(BuildManager.java:1023)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:247)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:303)
at org.eclipse.core.internal.events.BuildManager$1.run(BuildManager.java:392)
at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:45)
at org.eclipse.core.internal.events.BuildManager.basicBuild(BuildManager.java:395)
at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:506)
at org.eclipse.core.internal.events.BuildManager.basicBuildLoop(BuildManager.java:454)
at org.eclipse.core.internal.events.BuildManager.build(BuildManager.java:536)
at org.eclipse.core.internal.resources.Workspace.buildInternal(Workspace.java:524)
at org.eclipse.core.internal.resources.Workspace.build(Workspace.java:413)
at org.eclipse.jdt.ls.core.internal.handlers.BuildWorkspaceHandler.buildWorkspace(BuildWorkspaceHandler.java:63)
at org.eclipse.jdt.ls.core.internal.handlers.JDTLanguageServer.lambda$27(JDTLanguageServer.java:966)
at org.eclipse.jdt.ls.core.internal.handlers.JDTLanguageServer.lambda$56(JDTLanguageServer.java:1166)
at java.base/java.util.concurrent.CompletableFuture$UniApply.tryFire(CompletableFuture.java:646)
at java.base/java.util.concurrent.CompletableFuture$Completion.exec(CompletableFuture.java:483)
at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: org.eclipse.jdt.internal.compiler.problem.AbortCompilation:
at org.eclipse.jdt.internal.core.builder.NameEnvironment.findClass(NameEnvironment.java:521)
at org.eclipse.jdt.internal.core.builder.NameEnvironment.findType(NameEnvironment.java:591)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.lambda$0(LookupEnvironment.java:240)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForTypeFromModules(LookupEnvironment.java:375)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.askForType(LookupEnvironment.java:239)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.getType(LookupEnvironment.java:1735)
at org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment.getType(LookupEnvironment.java:1704)
at org.eclipse.jdt.internal.compiler.apt.model.ElementsImpl9.getTypeElement(ElementsImpl9.java:100)
at org.eclipse.jdt.internal.compiler.apt.model.ElementsImpl9.getTypeElement(ElementsImpl9.java:72)
at io.micronaut.annotation.processing.visitor.JavaVisitorContext.getClassElement(JavaVisitorContext.java:191)
at io.micronaut.annotation.processing.visitor.JavaClassElement.getAccessibleStaticCreators(JavaClassElement.java:612)
at io.micronaut.inject.ast.ClassElement.findStaticCreator(ClassElement.java:295)
at io.micronaut.inject.ast.ClassElement.getPrimaryConstructor(ClassElement.java:230)
at io.micronaut.annotation.processing.visitor.JavaClassElement.getPrimaryConstructor(JavaClassElement.java:603)
at io.micronaut.inject.processing.DeclaredBeanElementCreator.createBeanDefinitionVisitor(DeclaredBeanElementCreator.java:101)
at io.micronaut.inject.processing.DeclaredBeanElementCreator.buildInternal(DeclaredBeanElementCreator.java:82)
at io.micronaut.inject.processing.AbstractBeanElementCreator.build(AbstractBeanElementCreator.java:72)
at io.micronaut.annotation.processing.BeanDefinitionInjectProcessor.process(BeanDefinitionInjectProcessor.java:210)
at org.eclipse.jdt.internal.compiler.apt.dispatch.RoundDispatcher.handleProcessor(RoundDispatcher.java:142)
... 34 more
Looks like the annotation processors used in this sample project do not generate new source files but manipulate the existing source file Demo4Test
in memory and affect the generated class files. I'm not an expert of Java annotation processing, I'm not sure if this is allowed by spec.
ECJ compiler will abort the compilation when it detects some source files have been changed during compilation. In case you're interested to investigate the compiler further, here is the ECJ compiler code that throws the exception.
@testforstephen we do not manipulate the AST at all in Micronaut, the call here causing the issue is a simple lookup by class name:
io.micronaut.annotation.processing.visitor.JavaVisitorContext.getClassElement(JavaVisitorContext.java:191)
All it does is call Element.getTypeElement(..)
public Optional<ClassElement> getClassElement(String name, ElementAnnotationMetadataFactory annotationMetadataFactory) {
TypeElement typeElement = elements.getTypeElement(name);
if (typeElement == null) {
// maybe inner class?
typeElement = elements.getTypeElement(name.replace('$', '.'));
}
return Optional.ofNullable(typeElement)
.map(typeElement1 -> elementFactory.newClassElement(typeElement1, annotationMetadataFactory));
}
There are no issues with with this with javac. That said we will look if we can place yet another workaround for Eclipse JDT into the codebase.
btw how do you get to those logs?
I pushed another workaround for this bug in Eclipse JDT https://github.com/micronaut-projects/micronaut-core/pull/9660
Here is a more simple testcase for this bug. maven-ap
contains just a simple AP implementation. You need to mvn install
it first, then open maven-ap2
in vscode. Recompile the project (works fine), then make a change in .java file and save. CompilationAborted
is rendered as a problem in the editor. The processor does not 'change' anything, just generates new sources.
I suggest to upgrade the bug description, as the bug potentially affects way more APs than just Micronaut's one.
btw how do you get to those logs?
F1 -> Java: Open Java Language Server Log File
Here is a more simple testcase for this bug. maven-ap contains just a simple AP implementation. You need to mvn install it first, then open maven-ap2 in vscode. Recompile the project (works fine), then make a change in .java file and save. CompilationAborted is rendered as a problem in the editor. The processor does not 'change' anything, just generates new sources.
A related Eclipse bug - https://bugs.eclipse.org/bugs/show_bug.cgi?id=547970
Note though that this ticket actually talks about 2 different issues:
Environment
Steps To Reproduce
Projects created for Micronaut 3.10 (3.9.x) works OK, projects targetting Micronaut 4.x fail to work properly in vscode. The sample projects are attached: demo4.zip (gradle Micronaut 4.0.1), demom4.zip (maven Micronaut 4.0.1), demo2.zip(gradle, Micronaut 3.10-SNAPSHOT -- working). During testing and switching projects, the demo4 project appeared to load OK two times, but mostly fails. The seemingly successful opens were:
open demo2, then create new window and open demo4 there. Appeared without Problems once (further attempt failed with the reported problem)
open demo2, then Close Folder, and Open Folder demo4 in the current vscode (empty) window. (again, once seemed to load OK, other attempts fail) In both successful cases, I can't say for sure the progress for "Opening Java projects" appeared at all, maybe the extension did not load fully (?)
demo2.zip -- working
demo4.zip -- fails
demom4.zip -- fails too
Logs: jdtls.log
Current Result
Rebuild All
orRebuild Project
actions fail. The problems window shows the following messages:The application fails to launch:
Expected Result
No problems :) or just normal code issues.
Additional Informations
Default (system) Java version:
vscode version:
Installed extensions:
Suprisingly, opening the projects in Eclipse J2EE IDE shows no problems - screenshots of the Problems window: