Plugins annotations are not added to index in jar file if implemented in kotlin in src/main/java source tree

I have this MWE project:

├── pom.xml
└── src
    └── main
        └── kotlin
            └── PluginTest.kt

with pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>

        <parent>
                <groupId>org.scijava</groupId>
                <artifactId>pom-scijava</artifactId>
                <relativePath />
                <version>27.0.1</version>
        </parent>

        <groupId>org.janelia.saalfeldlab</groupId>
        <artifactId>test</artifactId>
        <version>0.1.0-SNAPSHOT</version>

        <properties>
                <package-name>org.janelia.saalfeldlab.test</package-name>
                <enforcer.skip>true</enforcer.skip>
<!--    Kotlin version-->
                <kotlin.version>1.3.50</kotlin.version>

<!--    JUnit-->
                <junit-jupiter.version>5.5.2</junit-jupiter.version>
        </properties>

        <repositories>
                <repository>
                        <id>imagej.public</id>
                        <url>https://maven.scijava.org/content/groups/public</url>
                </repository>
        </repositories>

        <dependencies>
                <dependency>
                        <groupId>org.scijava</groupId>
                        <artifactId>scijava-common</artifactId>
                </dependency>
        </dependencies>
</project>

and PluginTest.kt

import org.scijava.plugin.Plugin
import org.scijava.plugin.SciJavaPlugin

@Plugin(type = SciJavaPlugin::class)
class PluginTest : SciJavaPlugin

After building this with mvn clean package, the jar file target/test-0.1.0-SNAPSHOT.jar contains the plugin index META-INF/json/org.scijava.plugin.Plugin:

{"class":"PluginTest","values":{"type":"org.scijava.plugin.SciJavaPlugin"}}

If change the source root from src/main/kotlin to src/main/java, things get weird:

mv src/main/kotlin src/main/java
mvn -Pkotlin clean package

Now, target/test-0.1.0-SNAPSHOT.jar does not contain a META-INF/json directory. Is it generally not possible to use SciJava annotations with Kotlin in the src/main/java source root? Also, strangely, I ran into this situation in Paintera (much larger project) but only on Windows and not on Linux. The fix is, of course, easy: Just move all your kotlin files into src/main/kotlin but we have a few big PRs open, so I wonder if there is a pom-scijava solution without moving any files before those PRs are merged.

Possibly related to Plugins written in Groovy not seen by PluginService

Maybe fixed with:

@hanslovsky Would you care to give it a try? I didn’t test. :wink:

@skalarproduktraum @uschmidt83 Any particular reason that src/main/java was not included in the kapt processing? If this is a bad idea for some reason, we can revert it.

As an aside, I was wondering: why would you want Kotlin code in src/main/java? Isn’t that the wrong place?

Finally, it doesn’t look like we run kapt on src/test folders at all right now. Should we? Java sources in src/test do have their annotations processed (implicitly by apt in the compilation step).

2 Likes

Yes, I will, thank you for looking into this!

Because I can :wink: More seriously, though, I was starting to add Kotlin files/convert Java files to Kotlin in a Java project and the easiest way forward was to just have them in the same source root. An easy fix would be to move them into the src/main/kotlin root but we have a few large PRs coming up and I would like to avoid meaningless conflicts that just make merging harder. In the meantime, we do need a short-term solution for this problem that appears to happen only on Windows machines in a more complex case.

1 Like

@ctrueden I tried for this MWE, and it worked. Here is what I did:

  1. clone and mvn clean install pom-scijava-base master
  2. mvn clean install local copy of pom-scijava with parent version 9.0.1-SNAPSHOT (needed -Denforcer.skip=true)
  3. update my MWE pom parent to 28.0.0-SNAPSHOT

Now, the jar contains META-INF/json/org.scijava.plugin.Plugin:

{"class":"PluginTest","values":{"type":"org.scijava.plugin.SciJavaPlugin"}}

Thanks for the fix! I will update Paintera to consider src/main/java for kapt until releases are available.

1 Like

Glad to hear it worked.

For what it’s worth: the way I avoid the enforcer snapshot issues is to set the version of pom-scijava-base to 999, mvn install it, then change pom-scijava also to version 999 and extending pom-scijava-base version 999, install that, and then set my project (in this case MWE) to extend pom-scijava 999. This avoids enforcer snapshot errors without skipping the entire enforcer ruleset. Later, you can find ~/.m2/repository -name 999 -type d -exec rm -rf {} \; or whatever to remove them if you want (or just leave them, since they don’t really hurt anything).

2 Likes