Compile project in unit test

Answered

Our IntelliJ plug-in needs to compile the project it is used on and then access the generated `.class` files. How can I do this inside an IntelliJ plug-in test?

I tried to compile by setting the output location, saving the project and running a build task on the project:

 

public class WriteTestsTest extends LightJavaCodeInsightFixtureTestCase
{
// ...
compilerProjectExtension.setCompilerOutputPointer(pointer);
PlatformTestUtil.saveProject(getProject());
ProjectTaskManager projectTaskManager = ProjectTaskManager.getInstance(getProject());
ProjectTaskManagerImpl.waitForPromise(projectTaskManager.build(buildModule));

 

According to the log, this appears to invoke some compiler, although I can't find the produced `.class` files in the location I indicated. However, more importantly, `PlatformTestUtil.saveProject(getProject());` as well as the build task seem to create a whole set of `VirtualFilePointer` instances which are never disposed, and are thus leading to test failures like the following:

 

[2]: com.intellij.openapi.util.TraceableDisposable$DisposalException: Virtual pointer 'jar://C:/Users/Pascal/.gradle/caches/modules-2/files-2.1/com.jetbrains.intellij.idea/ideaIC/2019.3/5a74bbe98a814d61e6069abd0902b46668f1278c/ideaIC-2019.3/plugins/java/lib/jdkAnnotations.jar!/' hasn't been disposed: --------------Creation trace:
java.lang.Throwable
at com.intellij.openapi.util.TraceableDisposable.<init>(TraceableDisposable.java:31)
at com.intellij.openapi.vfs.impl.VirtualFilePointerImpl.<init>(VirtualFilePointerImpl.java:38)
at com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl.getOrCreate(VirtualFilePointerManagerImpl.java:359)
at com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl.create(VirtualFilePointerManagerImpl.java:244)
at com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl.create(VirtualFilePointerManagerImpl.java:162)
at com.intellij.openapi.vfs.impl.VirtualFilePointerContainerImpl.create(VirtualFilePointerContainerImpl.java:343)
at com.intellij.openapi.vfs.impl.VirtualFilePointerContainerImpl.add(VirtualFilePointerContainerImpl.java:142)
at com.intellij.openapi.projectRoots.impl.RootsAsVirtualFilePointers.addRoot(RootsAsVirtualFilePointers.java:56)
at com.intellij.openapi.projectRoots.impl.ProjectJdkImpl.addRoot(ProjectJdkImpl.java:332)
at com.intellij.openapi.projectRoots.impl.JavaSdkImpl.attachIDEAAnnotationsToJdk(JavaSdkImpl.java:294)
at com.intellij.openapi.projectRoots.impl.JavaSdkImpl.attachJdkAnnotations(JavaSdkImpl.java:272)
at com.intellij.openapi.projectRoots.impl.JavaSdkImpl.createJdk(JavaSdkImpl.java:376)
at com.intellij.openapi.projectRoots.JavaSdk.createJdk(JavaSdk.java:21)
at com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl.getInternalJdk(JavaAwareProjectJdkTableImpl.java:29)
at com.intellij.compiler.server.BuildManager.lambda$getRuntimeSdk$17(BuildManager.java:964)
at java.util.Optional.orElseGet(Optional.java:267)
at com.intellij.compiler.server.BuildManager.getRuntimeSdk(BuildManager.java:963)
at com.intellij.compiler.server.BuildManager.getBuildProcessRuntimeSdk(BuildManager.java:934)
at com.intellij.compiler.server.BuildManager.launchBuildProcess(BuildManager.java:1006)
at com.intellij.compiler.server.BuildManager.lambda$null$10(BuildManager.java:799)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at com.intellij.util.concurrency.BoundedTaskExecutor.doRun(BoundedTaskExecutor.java:222)
at com.intellij.util.concurrency.BoundedTaskExecutor.access$200(BoundedTaskExecutor.java:30)
at com.intellij.util.concurrency.BoundedTaskExecutor$1.execute(BoundedTaskExecutor.java:201)
at com.intellij.util.ConcurrencyUtil.runUnderThreadName(ConcurrencyUtil.java:221)
at com.intellij.util.concurrency.BoundedTaskExecutor$1.run(BoundedTaskExecutor.java:190)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

 

My assumption is thus that I am misusing the IntelliJ fixture. What is the correct way to work with a project in an IntelliJ plug-in unit test which can be compiled and whose resulting `.class` files can be accessed by a third party tool?

2
1 comment

Please take a look at com.intellij.compiler.BaseCompilerTestCase and descendants for such tests (e.g. com.intellij.compiler.ModuleCompileScopeTest)

0

Please sign in to leave a comment.