How to configure my plugin for working both with IntelliJ and Android Studio

Answered

Hello,
I'm (almost) a beginner in plugin creation (I created one a long time ago) and I would like to create a plugin that works BOTH with IntelliJ and with Android Studio (this to start with, because later I would like it to work also for Webstorm, PyCharm...). The principle is to use the parsing provided by IntelliJ (for Java for the moment, later for Kotlin, PHP...) thanks to the PSI. I've spent days reading and testing information at https://plugins.jetbrains.com/docs/intellij (and so on) and online tutorials, but I still can't configure my project (even before coding it). Can you help me?

Here is some information:

  • I created the plugin ('empty' plugin for now) from the github template presented the online documentation. No problem for that I guess.
  • I use a JDK 11. I guess this is what I have to do now (unlike before when I had to use the IntelliJ JDK).
  • I want to code my plugin in Java (not in Kotlin). The template generated Kotlin code (MyBundle.kt, listeners, services...). What to write to replace these code in Java ?
  • I don't know Kotlin (or very very little) and I usually develop in Java with Android Studio and Gradle. Should I keep the build.gradle.kst or replace it by build.gradle (and if yes, what to put in it ?) ? The formats of the parameters in these "build.gradle" are often written for one or the other and it is difficult for me to find my way around.
  • When I'll have succeeded in this step, I must also add a library (a jar) for my plugin to work. Do I only have to add this jar in the libraries of the 'project settings' or do I have to do something else?
  • Finally, when I run my 'empty' plugin, I get the errors :
WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.intellij.ui.JreHiDpiUtil to method sun.java2d.SunGraphicsEnvironment.isUIScaleEnabled()
WARNING: Please consider reporting this to the maintainers of com.intellij.ui.JreHiDpiUtil
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
2022-02-28 14:35:43,095 [ 12910] WARN - j.internal.DebugAttachDetector - Unable to start DebugAttachDetector, please add `--add-exports java.base/jdk.internal.vm=ALL-UNNAMED` to VM options
2022-02-28 14:35:52,544 [ 22359] WARN - .diagnostic.PerformanceWatcher - UI was frozen for 8674ms, details saved to C:\Users\Jean-Claude\IdeaProjects\pluginTemplateGradle_1\build\idea-sandbox\system\log\threadDumps-freeze-20220228-143548-IC-211.7628.21-8sec

Is this normal? If not, what to do?

I join my gradle.properties and plugin.xml files (Upload id: 2022_03_01_E9bT1d2SGKmmFc7M (files: plugin.xml, gradle.properties)

Thanks for your help...

JC

10 comments
Comment actions Permalink

Hi,

Answers below.

 

I want to code my plugin in Java (not in Kotlin). The template generated Kotlin code (MyBundle.kt, listeners, services...). What to write to replace these code in Java ?

You can remove Kotlin-related configuration from the gradle.build.kts file, so:

  • id("org.jetbrains.kotlin.jvm") version "1.6.10"
  • withType<KotlinCompile> {
      kotlinOptions.jvmTarget = it
    }

After that remove src/main/kotlin and src/test/kotlin directories and create src/main/java and src/test/java. I hope the rest is obvious.

 

I don't know Kotlin (or very very little) and I usually develop in Java with Android Studio and Gradle. Should I keep the build.gradle.kst or replace it by build.gradle (and if yes, what to put in it ?) ? The formats of the parameters in these "build.gradle" are often written for one or the other and it is difficult for me to find my way around.

I suggest keeping the build.gradle.kts file. Groovy gradle.build file is IMHO harder to maintain and by using the Kotlin Script approach, it will be easier to update your build file when we update the template.

 

When I'll have succeeded in this step, I must also add a library (a jar) for my plugin to work. Do I only have to add this jar in the libraries of the 'project settings' or do I have to do something else?

No, you should add it as Gradle project dependencies, e.g.:

build.gradle.kts:

...
dependencies {
  implementation("your:lib:1.0.0")
}
...

 

Regarding the "errors", you can safely ignore them as they are warnings, not errors.

0
Comment actions Permalink

Thank you. I adapted my files as shown below. It seems that my empty plugin is well recognized by Android Studio and IntelliJ.

configurations {
create("externalLibs")
}

dependencies {
// to integrate my jar
"externalLibs"(files("lib/wseJava.jar"))

implementation("io.cortical:retina-api-java-sdk:1.0.2")
}

// Configure Gradle IntelliJ Plugin - read more: https://github.com/JetBrains/gradle-intellij-plugin
intellij {
pluginName.set(properties("pluginName"))
version.set(properties("platformVersion"))
type.set(properties("platformType"))

// Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file.
plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty))
}

Do I need to write platformPlugins =['android','java'] to manage Java and Android code with my plugin in IntelliJ and Android Studio ?

# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
pluginSinceBuild = 211
pluginUntilBuild = 213.*

# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
platformType = IC
#platformVersion = 2021.1.3
platformVersion = 211.7628.21

# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
platformPlugins =

# Java language level used to compile sources and to generate the files for - Java 11 is required since 2020.3
javaVersion = 11

# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion = 7.4

# Opt-out flag for bundling Kotlin standard library.
# See https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library for details.
# suppress inspection "UnusedProperty"
kotlin.stdlib.default.dependency = false
0
Comment actions Permalink

Hi,

In the "platformPlugins" property you should add plugins that contain classes and functionalities required by your plugin. If you e.g., access Java PSI classes, then you should include com.intellij.java. If you plan to develop a plugin for Android Studio, take a look at:
https://plugins.jetbrains.com/docs/intellij/android-studio.html

Please note this is comma-separated list, without brackets.

0
Comment actions Permalink

Yes, as I said in the first post:

Here is my current configuration :

  • plugin.xml
<depends>intellij.modules.platform</depends>

<depends>com.intellij.modules.lang</depends>

<depends>com.intellij.modules.java-capable</depends> // correct ?

<depends>com.intellij.modules.androidstudio</depends> // error : cannot resolve plugin in dependencies

<depends>org.jetbrains.android</depends>                 // error : cannot resolve plugin in dependencies

 

  • build.gradle.kts
-         plugins {
   
// Java support
   
id("java")
    // Gradle IntelliJ Plugin
   
id("org.jetbrains.intellij") version "1.4.0"
   
// Gradle Changelog Plugin
   
id("org.jetbrains.changelog") version "1.3.1"
   
// Gradle Qodana Plugin
   
id("org.jetbrains.qodana") version "0.1.13"
}
  • gradle.properties
-         # See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
pluginSinceBuild = 211
pluginUntilBuild
= 213.*

# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
platformType = IC
#platformVersion = 2021.1.3
platformVersion = 211.7628.21 // to be compatible between IJ and Android Studio, OK ?

# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
platformPlugins = com.intellij.java, org.jetbrains.android // is it correct ????

# Java language level used to compile sources and to generate the files for - Java 11 is required since 2020.3
javaVersion = 11

# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion = 7.4

 

 

 

0
Comment actions Permalink

Hi,

Regarding:

<depends>com.intellij.modules.java-capable</depends>     // correct ?

No, it should be com.intellij.modules.java or com.intellij.java, depending on the versions you want to target, see:
https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html#modules-specific-to-functionality

and explanations under the table for the details.

Regarding:

platformPlugins = com.intellij.java, org.jetbrains.android    // is it correct ????

It's not correct, see: https://plugins.jetbrains.com/docs/intellij/android-studio.html#configuring-the-plugin-buildgradle-file

intellij { 
...
plugins = ['android']
}

Once you fix the above, the below should work:

<depends>com.intellij.modules.androidstudio</depends>    // error : cannot resolve plugin in dependencies
<depends>org.jetbrains.android</depends>                 // error : cannot resolve plugin in dependencies

Regarding:

platformVersion = 211.7628.21         // to be compatible between IJ and Android Studio, OK ?

The "android" plugin is important, the platform version from your file should be fine.

0
Comment actions Permalink

It is better, but I still have one problem in plugin.xml with android studio (see below). What to do ?

In build.gradle.KTS (I didn’t keep build.gradle as you proposed):

intellij {
    pluginName.set(properties("pluginName"))
    version.set(properties("platformVersion"))
    type.set(properties("platformType"))
plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty))
}

In gradle.properties, what to write?

platformPlugins = com.intellij.java, org.jetbrains.android (?)
platformPlugins = com.intellij.java, android (?)
platformPlugins = ... ?

In plugin.xml, always the same error with android studio:

    <depends>com.intellij.modules.platform</depends>
    <depends>com.intellij.modules.lang</depends>
    <depends>com.intellij.java</depends>
    <depends>com.intellij.modules.java</depends>
<depends>com.intellij.modules.androidstudio</depends>    // error : cannot resolve plugin in dependencies
   
<depends>org.jetbrains.android</depends> // OK now

 

0
Comment actions Permalink

Hi,

Did you configure the runIde task according to:
https://plugins.jetbrains.com/docs/intellij/android-studio.html#configuring-the-plugin-pluginxml-file

so it points to Android Studio installation?

Also, please do not post the same question in multiple channels (https://stackoverflow.com/questions/71335106/how-to-configure-my-plugin-for-working-both-with-intellij-and-android-studio) because it can engage multiple people trying to help you at the same time which is just a waste of resources. Please respect our time. If you do it (what is not recommended), then at least link in both places, so people can see if the problem is already solved. The recommended channel is this forum.

0
Comment actions Permalink

Hello
Sorry to waste your time, but as I had already wasted more than two weeks trying to find the solution to my problems by myself, reading all the Jetbrains docs (on plugins and others), dozens of posts here and there, without ever getting an answer to my problems, I had first launched a request on stackoverflow, and as I didn't get any answer, I looked for another place to post my questions.

When I will have a definitive answer to my problems, I was going to put the solution in my two posts, but for the moment, I still don't have it :-(

To answer your question, I don't know how to configure the runIde for the build.gradle.KTS, and moreover the doc indicates a path for Mac and no information for Windows.  I tried all a set of writings, for example :

    runIde{ideDir("/Applications/Android Studio.app")}
or runIde{ideDir("C:\Program Files\Android Studio\binstudio64.exe"))}, 

but it is the ideDir parameter that blocks. I understand that it is the syntax that is not good, but I don't know what to write.

 

0
Comment actions Permalink

Hi,

You should set directory path, not to the exe file, according to runIde doc:
https://github.com/JetBrains/gradle-intellij-plugin#running-dsl

Of course you must have Android Studio installed locally. If your Android Studio is installed in C:\Program Files\Android Studio, then it should be (I assume you use Kotlin build.gradle.kts file):

runIde {
ideDir = file('C:/Program Files/Android Studio')
}

It is fine to use "/" for Windows-specific paths in Gradle.

0
Comment actions Permalink

Hello
I still have the error in the dependencies, but otherwise it seems to work pretty well, at least enough for me to finally start coding the plugin.

<depends>com.intellij.modules.androidstudio</depends>    // error : cannot resolve plugin in dependencies


I put below the 3 files, it may possibly help someone.

  • plugin.xml
<!-- Plugin Configuration File. Read more: https://plugins.jetbrains.com/docs/intellij/plugin-configuration-file.html -->
<idea-plugin>
    <id>com......</id>
    <name>My plugin name</name>
    <vendor email="my email@foo.com" url="http://mywebpage">My company</vendor>

    <!-- please see https://plugins.jetbrains.com/docs/intellij/plugin-compatibility.html
        on how to target different products -->
    <depends>com.intellij.modules.platform</depends>
    <depends>com.intellij.modules.lang</depends>
    <depends>com.intellij.java</depends>
    <depends>com.intellij.modules.java</depends>
<!--    <depends>com.intellij.modules.androidstudio</depends>    // error : cannot resolve plugin in dependencies-->
    <depends>org.jetbrains.android</depends>

    <extensions defaultExtensionNs="com.intellij">
    </extensions>

    <applicationListeners>
    </applicationListeners>

    <change-notes><![CDATA[
      my change notes...
    ]]>
    </change-notes>

    <actions>
    </actions>

</idea-plugin>

 

  • build.gradle.kts
import org.jetbrains.changelog.markdownToHTML

fun properties(key: String) = project.findProperty(key).toString()

plugins {
    // Java support
    id("java")
    // Gradle IntelliJ Plugin
    id("org.jetbrains.intellij") version "1.4.0"
    // Gradle Changelog Plugin
    id("org.jetbrains.changelog") version "1.3.1"
    // Gradle Qodana Plugin
    id("org.jetbrains.qodana") version "0.1.13"
}

group = properties("pluginGroup")
version = properties("pluginVersion")

// Configure project's dependencies
repositories {
    mavenCentral()
}

dependencies {
    implementation(files("lib/myJar.jar"))
    implementation(files("lib/json-20211205.jar"))
}


// Configure Gradle IntelliJ Plugin - read more: https://github.com/JetBrains/gradle-intellij-plugin
intellij {
    pluginName.set(properties("pluginName"))
    version.set(properties("platformVersion"))
    type.set(properties("platformType"))

    // Plugin Dependencies. Uses `platformPlugins` property from the gradle.properties file.
    plugins.set(properties("platformPlugins").split(',').map(String::trim).filter(String::isNotEmpty))
}

// Configure Gradle Changelog Plugin - read more: https://github.com/JetBrains/gradle-changelog-plugin
changelog {
    version.set(properties("pluginVersion"))
    groups.set(emptyList())
}

// Configure Gradle Qodana Plugin - read more: https://github.com/JetBrains/gradle-qodana-plugin
qodana {
    cachePath.set(projectDir.resolve(".qodana").canonicalPath)
    reportPath.set(projectDir.resolve("build/reports/inspections").canonicalPath)
    saveReport.set(true)
    showReport.set(System.getenv("QODANA_SHOW_REPORT")?.toBoolean() ?: false)
}

tasks {
    // Set the JVM compatibility versions
    properties("javaVersion").let {
        withType<JavaCompile> {
            sourceCompatibility = it
            targetCompatibility = it
        }
    }

    runIde {
        // to run the plugin with Android Studio
        ideDir.set(file("C:/Program Files/Android/Android Studio"))
        // comment the line above to run the plugin with IntelliJ instead of Android Studio
    }

    wrapper {
        gradleVersion = properties("gradleVersion")
    }

    patchPluginXml {
        version.set(properties("pluginVersion"))
        sinceBuild.set(properties("pluginSinceBuild"))
        untilBuild.set(properties("pluginUntilBuild"))

        // Extract the <!-- Plugin description --> section from README.md and provide for the plugin's manifest
        pluginDescription.set(
            projectDir.resolve("README.md").readText().lines().run {
                val start = "<!-- Plugin description -->"
                val end = "<!-- Plugin description end -->"

                if (!containsAll(listOf(start, end))) {
                    throw GradleException("Plugin description section not found in README.md:\n$start ... $end")
                }
                subList(indexOf(start) + 1, indexOf(end))
            }.joinToString("\n").run { markdownToHTML(this) }
        )

        // Get the latest available change notes from the changelog file
        changeNotes.set(provider {
            changelog.run {
                getOrNull(properties("pluginVersion")) ?: getLatest()
            }.toHTML()
        })
    }

    // Configure UI tests plugin
    // Read more: https://github.com/JetBrains/intellij-ui-test-robot
    runIdeForUiTests {
        systemProperty("robot-server.port", "8082")
        systemProperty("ide.mac.message.dialogs.as.sheets", "false")
        systemProperty("jb.privacy.policy.text", "<!--999.999-->")
        systemProperty("jb.consents.confirmation.enabled", "false")
    }

    signPlugin {
        certificateChain.set(System.getenv("CERTIFICATE_CHAIN"))
        privateKey.set(System.getenv("PRIVATE_KEY"))
        password.set(System.getenv("PRIVATE_KEY_PASSWORD"))
    }

    publishPlugin {
        dependsOn("patchChangelog")
        token.set(System.getenv("PUBLISH_TOKEN"))
        // pluginVersion is based on the SemVer (https://semver.org) and supports pre-release labels, like 2.1.7-alpha.3
        // Specify pre-release label to publish the plugin in a custom Release Channel automatically. Read more:
        // https://plugins.jetbrains.com/docs/intellij/deployment.html#specifying-a-release-channel
        channels.set(listOf(properties("pluginVersion").split('-').getOrElse(1) { "default" }.split('.').first()))
    }
}

 

  • gradle.properties
# IntelliJ Platform Artifacts Repositories
# -> https://plugins.jetbrains.com/docs/intellij/intellij-artifacts.html

pluginGroup = com.....
pluginName = my plugin name
# SemVer format -> https://semver.org
pluginVersion = 0.0.1

# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
pluginSinceBuild = 211
pluginUntilBuild = 213.*

# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
platformType = IC
#platformVersion = 2021.1.3
platformVersion = 211.7628.21


# Plugin Dependencies -> https://plugins.jetbrains.com/docs/intellij/plugin-dependencies.html
# Example: platformPlugins = com.intellij.java, com.jetbrains.php:203.4449.22
platformPlugins = com.intellij.java, org.jetbrains.android

# Java language level used to compile sources and to generate the files for - Java 11 is required since 2020.3
javaVersion = 11

# Gradle Releases -> https://github.com/gradle/gradle/releases
gradleVersion = 7.4

# Opt-out flag for bundling Kotlin standard library.
# See https://plugins.jetbrains.com/docs/intellij/kotlin.html#kotlin-standard-library for details.
# suppress inspection "UnusedProperty"
kotlin.stdlib.default.dependency = false

Thank you for your help.

JC

0

Please sign in to leave a comment.