Vadim Salajan
Vadim Salajan

Reputation: 205

How to create a custom Kotlin Inspection for Intellij Idea programmatically

I want to create a plugin for Intellij Idea which provides additional inspections for Kotlin language. Following the example from official documentation for creating inspections for Java, I ended up with following code, which is not working.

Here is the link to a repository with this project: https://bitbucket.org/magycbytes/kotlin-inspections/src/master/

Links to example I followed:

This is the provider for inspections.

package com.magicbytes.kotlin.inspections;

import com.intellij.codeInspection.InspectionToolProvider;
import com.magicbytes.kotlin.inspections.ExampleInspection;
import org.jetbrains.annotations.NotNull;

public class ExampleProvider implements InspectionToolProvider {
    @NotNull
    @Override
    public Class[] getInspectionClasses() {
        return new Class[]{ExampleInspection.class};
    }
}

This is the actual inspection subclass. For the sake of shortness it's doing nothing, but should be loaded. Note: I changed the superclass to AbstractKotlinInspection

package com.magicbytes.kotlin.inspections;

import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.idea.inspections.AbstractKotlinInspection;

public class ExampleInspection extends AbstractKotlinInspection {
    @Nls
    @NotNull
    @Override
    public String getDisplayName() {
        return "Kotlin Test";
    }
}

My buid.gradle file looks like this:

plugins {
    id 'java'
    id 'org.jetbrains.intellij' version '0.3.2'
}

group 'com.magicbytes'
version '1.0-SNAPSHOT'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

intellij {
    version '2018.1.4'
    plugins 'kotlin'
}

Mine plugin.xml looks like this:

<idea-plugin>
    <id>com.magicbytes.kotlin.inspections</id>
    <name>Plugin display name here</name>
    <description></description>

    <depends>org.jetbrains.kotlin</depends>

    <extensions defaultExtensionNs="com.intellij">
        <!-- Add your extensions here -->
        <inspectionToolProvider implementation="com.magicbytes.kotlin.inspections.ExampleProvider"/>
    </extensions>

    <actions>
    </actions>
</idea-plugin>

I did all the linking with plugin.xml file. But when I'm running I'm getting exception in testing IDE. Appreciate any insight. NOTE: I'm using runIde to debug the plugin.

Exception which I'm getting..

 java.lang.ClassNotFoundException: ExampleProvider PluginClassLoader[com.magicbytes.kotlin.inspections, 1.0-SNAPSHOT] com.intellij.ide.plugins.cl.PluginClassLoader@6f989177
com.intellij.openapi.extensions.impl.PicoPluginExtensionInitializationException: java.lang.ClassNotFoundException: ExampleProvider PluginClassLoader[com.magicbytes.kotlin.inspections, 1.0-SNAPSHOT] com.intellij.ide.plugins.cl.PluginClassLoader@6f989177
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.getComponentInstance(ExtensionComponentAdapter.java:96)
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.getExtension(ExtensionComponentAdapter.java:119)
    at com.intellij.openapi.extensions.impl.ExtensionPointImpl.processAdapters(ExtensionPointImpl.java:246)
    at com.intellij.openapi.extensions.impl.ExtensionPointImpl.getExtensions(ExtensionPointImpl.java:191)
    at com.intellij.openapi.extensions.Extensions.getExtensions(Extensions.java:102)
    at com.intellij.openapi.extensions.Extensions.getExtensions(Extensions.java:89)
    at com.intellij.openapi.extensions.ExtensionPointName.getExtensions(ExtensionPointName.java:50)
    at com.intellij.codeInspection.ex.InspectionToolRegistrar.ensureInitialized(InspectionToolRegistrar.java:54)
    at com.intellij.codeInspection.ex.InspectionToolRegistrar.createTools(InspectionToolRegistrar.java:127)
    at com.intellij.codeInspection.ex.InspectionSearchableOptionContributor.processOptions(InspectionSearchableOptionContributor.java:34)
    at com.intellij.ide.ui.search.SearchableOptionPreloader.preload(SearchableOptionPreloader.java:49)
    at com.intellij.openapi.application.Preloader.lambda$null$0(Preloader.java:74)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:157)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:543)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:488)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:94)
    at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:144)
    at com.intellij.openapi.application.Preloader.lambda$initComponent$1(Preloader.java:72)
    at com.intellij.util.concurrency.BoundedTaskExecutor$2.run(BoundedTaskExecutor.java:212)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: ExampleProvider PluginClassLoader[com.magicbytes.kotlin.inspections, 1.0-SNAPSHOT] com.intellij.ide.plugins.cl.PluginClassLoader@6f989177
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.loadImplementationClass(ExtensionComponentAdapter.java:161)
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.getComponentImplementation(ExtensionComponentAdapter.java:66)
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.getComponentInstance(ExtensionComponentAdapter.java:73)
    ... 21 more
Caused by: java.lang.ClassNotFoundException: ExampleProvider PluginClassLoader[com.magicbytes.kotlin.inspections, 1.0-SNAPSHOT] com.intellij.ide.plugins.cl.PluginClassLoader@6f989177
    at com.intellij.ide.plugins.cl.PluginClassLoader.loadClass(PluginClassLoader.java:63)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.loadImplementationClass(ExtensionComponentAdapter.java:158)
    ... 23 more
Caused by:

java.lang.RuntimeException: java.lang.ClassNotFoundException: ExampleProvider PluginClassLoader[com.magicbytes.kotlin.inspections, 1.0-SNAPSHOT] com.intellij.ide.plugins.cl.PluginClassLoader@6f989177
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.loadImplementationClass(ExtensionComponentAdapter.java:161)
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.getComponentImplementation(ExtensionComponentAdapter.java:66)
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.getComponentInstance(ExtensionComponentAdapter.java:73)
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.getExtension(ExtensionComponentAdapter.java:119)
    at com.intellij.openapi.extensions.impl.ExtensionPointImpl.processAdapters(ExtensionPointImpl.java:246)
    at com.intellij.openapi.extensions.impl.ExtensionPointImpl.getExtensions(ExtensionPointImpl.java:191)
    at com.intellij.openapi.extensions.Extensions.getExtensions(Extensions.java:102)
    at com.intellij.openapi.extensions.Extensions.getExtensions(Extensions.java:89)
    at com.intellij.openapi.extensions.ExtensionPointName.getExtensions(ExtensionPointName.java:50)
    at com.intellij.codeInspection.ex.InspectionToolRegistrar.ensureInitialized(InspectionToolRegistrar.java:54)
    at com.intellij.codeInspection.ex.InspectionToolRegistrar.createTools(InspectionToolRegistrar.java:127)
    at com.intellij.codeInspection.ex.InspectionSearchableOptionContributor.processOptions(InspectionSearchableOptionContributor.java:34)
    at com.intellij.ide.ui.search.SearchableOptionPreloader.preload(SearchableOptionPreloader.java:49)
    at com.intellij.openapi.application.Preloader.lambda$null$0(Preloader.java:74)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:157)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:543)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:488)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:94)
    at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:144)
    at com.intellij.openapi.application.Preloader.lambda$initComponent$1(Preloader.java:72)
    at com.intellij.util.concurrency.BoundedTaskExecutor$2.run(BoundedTaskExecutor.java:212)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: java.lang.ClassNotFoundException: ExampleProvider PluginClassLoader[com.magicbytes.kotlin.inspections, 1.0-SNAPSHOT] com.intellij.ide.plugins.cl.PluginClassLoader@6f989177
    at com.intellij.ide.plugins.cl.PluginClassLoader.loadClass(PluginClassLoader.java:63)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
    at java.lang.Class.forName0(Native Method)
    at java.lang.Class.forName(Class.java:348)
    at com.intellij.openapi.extensions.impl.ExtensionComponentAdapter.loadImplementationClass(ExtensionComponentAdapter.java:158)
    ... 23 more

Upvotes: 3

Views: 1200

Answers (1)

yeputons
yeputons

Reputation: 9238

After I've imported your GitHub repo and built it locally I've found out that ./build/libs/kotlin.inspections-1.0-SNAPSHOT.jar includes META-INF only, but no classes. I suspect it's because your source code is located under ./src/main/src, not ./src/main/java as it's typical for Gradle projects, so it simply assumes you have no code at all.

After renaming that inner src directory into java the error changed to

class com.magicbytes.kotlin.inspections.ExampleInspection: group display name should be overridden or configured via XML class com.magicbytes.kotlin.inspections.ExampleInspection
java.lang.Throwable: class com.magicbytes.kotlin.inspections.ExampleInspection: group display name should be overridden or configured via XML class com.magicbytes.kotlin.inspections.ExampleInspection
    at com.intellij.openapi.diagnostic.Logger.error(Logger.java:123)
    at com.intellij.codeInspection.InspectionProfileEntry.getGroupDisplayName(InspectionProfileEntry.java:230)
    at com.intellij.codeInspection.InspectionProfileEntry.getGroupPath(InspectionProfileEntry.java:239)
    at com.intellij.codeInspection.ex.InspectionToolWrapper.getGroupPath(InspectionToolWrapper.java:161)
    at com.intellij.codeInspection.ex.InspectionSearchableOptionContributor.processOptions(InspectionSearchableOptionContributor.java:40)
    at com.intellij.ide.ui.search.SearchableOptionPreloader.preload(SearchableOptionPreloader.java:49)
    at com.intellij.openapi.application.Preloader.lambda$null$0(Preloader.java:74)
    at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$1(CoreProgressManager.java:157)
    at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:580)
    at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:525)
    at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:85)
    at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:144)
    at com.intellij.openapi.application.Preloader.lambda$initComponent$1(Preloader.java:72)
    at com.intellij.util.concurrency.BoundedTaskExecutor$2.run(BoundedTaskExecutor.java:212)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

which is much better and looks like a separate problem with your code violating some contract.

Upvotes: 1

Related Questions