External Builder API Specific Implementation Details
I'm working on a custom language plugin to write Latex in Intellij IDEA. While attempting to add a feature to compile Latex to PDF, I found this http://www.jetbrains.org/intellij/sdk/docs/reference_guide/frameworks_and_external_apis/external_builder_api.html
documentation, but I would like to know more specific details. In particular, besides extending `BuildTargetScopeProvider`, which other classes do I need to extend? What configuration changes must I make to my `plugin.xml` file? I have tried to looking at existing custom language plugins such as the Scala plugin (https://github.com/JetBrains/intellij-scala), but learning directly from the existing code has been difficult to manage on my own, and I would appreciate any help.
Thank you,
Philip Axelrod
Please sign in to leave a comment.
After looking at some more examples and reviewing the documentation again, here is the current state of my plugin.
I have extended the following classes:
`TargetBuilder` extended by `LatexBuilder`
`BuilderService` extended by `LatexBuilderService`
`BuildTargetScopeProvider` extended by `LatexBuildScopeProvider`
`BuildRootDescriptor` extended by `LatexBuildRootDescriptor`
`BuildTarget` extended by `LatexBuildTarget`
`BuildTargetType` extended by `LatexBuildTargetType`
In addition, I created a "services" folder in the "META-INF" folder. In the "services" folder I created a
"org.jetbrains.jps.incremental.BuilderService" file which contains the following text
build.builders.LatexBuilderService
which is the fully qualified name for the `LatexBuilderService` class which extends `BuilderService.` I also added the following text in the extensions tag in my plugin.xml
<compiler.buildTargetScopeProvider implementation="build.scope.LatexBuildScopeProvider"/>
<compileServer.plugin classpath ="/home/philip/IdeaProjects/latex-compile-proof-of-concept/build/libs/latex-compile-1.0-SNAPSHOT.jar" />
Where "/home/philip/IdeaProjects/latex-compile-proof-of-concept/build/libs/latex-compile-1.0-SNAPSHOT.jar" is the path to the jar resulting from running the gradle build task.
After all this, I confirmed with print statements that the `getBuildTargetScopes` method in `LatexBuildScopeProvider` which extends `BuildTargetScopeProvider` is called whenever the build project button is pressed. However, no other methods in the other classes are called. In particular, `build` in `LatexBuilder` which extends `TargetBuilder` is never called. How should I resolve this issue? Am I forgetting any steps here?
Thanks,
Philip Axelrod
<compileServer.plugin> in plugin.xml must have value "latex-compile-1.0-SNAPSHOT.jar" and the jar has to be deployed in classpath root.
See a simple setup in Plugin-Devkit plugin in IJ Community sources.
Please post/link to full sources to help diagnosis.
<compileServer.plugin classpath= ... should be relative to <my-plugin-base-dir>/lib.
If the jar as in <my-plugin-base-dir>/lib/jps-ext, it should be
<extensions defaultExtensionNs="com.intellij">
<compileServer.plugin classpath ="jps-ext/latex-compile-1.0-SNAPSHOT.jar" />
</extensions>
I posted a link to a Github repo with my code here:
https://github.com/PhilipAxelrod/Intellij-Latex-Compilation
When I changed the path to the jar as described by Serge Baranov and Yann Cebron above, the following happens. I run the plugin, press the build project button in the IDE that pops up, and I get the following compile error:
Error:Internal error: (java.lang.NoClassDefFoundError) Could not initialize class org.jetbrains.jps.incremental.TargetTypeRegistry$Holder
java.lang.NoClassDefFoundError: Could not initialize class org.jetbrains.jps.incremental.TargetTypeRegistry$Holder
at org.jetbrains.jps.incremental.TargetTypeRegistry.getInstance(TargetTypeRegistry.java:35)
at org.jetbrains.jps.builders.impl.BuildTargetRegistryImpl.<init>(BuildTargetRegistryImpl.java:44)
at org.jetbrains.jps.cmdline.BuildRunner.load(BuildRunner.java:81)
at org.jetbrains.jps.cmdline.BuildSession.runBuild(BuildSession.java:279)
at org.jetbrains.jps.cmdline.BuildSession.run(BuildSession.java:135)
at org.jetbrains.jps.cmdline.BuildMain$MyMessageHandler.lambda$channelRead0$0(BuildMain.java:229)
at org.jetbrains.jps.service.impl.SharedThreadPoolImpl.lambda$executeOnPooledThread$0(SharedThreadPoolImpl.java:42)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:514)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at java.base/java.lang.Thread.run(Thread.java:844)
In addition, this change didn't triggered any of my print statements in LatedBuilder/LatexBuilderService
I want to emphasize that this is a Compile error. I've added a screenshot to clarify
I can't find where you build the jps.jar to be deployed next to your plugin's jar in your build.gradle. See http://www.jetbrains.org/intellij/sdk/docs/reference_guide/frameworks_and_external_apis/external_builder_api.html?search=buil#registering-a-plugin-for-external-builder
I have been building the jar using the gradle "build" command and then manually copying it over to the appropriate directory. This is because I couldn't seem to find a "| ‘Prepare Plugin Module for deployment" action as specified in the documentation. I will look for it again and try using it.
"Prepare Plugin Module for deployment" is only available when building plugin with Plugin Devkit project, but not when using Gradle. Only the JPS related functionality must be bundled in the JPS.jar, not the full plugin.
I see. I also noticed that the documentation says "Sources of a plugin for External Builder should be put in a separate module. " In my case, which source files should be in which modules, or is my organization fine as it is now?
I found this plugin using JPS and Gradle: https://github.com/ignatov/intellij-erlang