A Maven plugin for running Kotlin Symbol Processing (KSP) on JVM projects.
This plugin integrates KSP (Kotlin Symbol Processing) into Maven builds, allowing you to process Kotlin source files with annotation processors that use the KSP API.
Check out the blog post.
- Maven 3.6.0 or higher
- JDK 11 or higher
- Kotlin 2.2.21 or a compatible version
Minimal setup with a custom KSP processor:
<build>
<plugins>
<plugin>
<groupId>me.kpavlov.ksp.maven</groupId>
<artifactId>ksp-maven-plugin</artifactId>
<version>[LATEST VERSION]</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
<!-- KSP processors are plugin dependencies, not project dependencies -->
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-ksp-processor</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>2.2.21</version>
<executions>
<execution>
<id>compile</id>
<goals>
<goal>compile</goal>
</goals>
<phase>compile</phase>
</execution>
</executions>
</plugin>
</plugins>
<sourceDirectory>src/main/kotlin</sourceDirectory>
</build>All available configuration options:
<plugin>
<groupId>me.kpavlov.ksp.maven</groupId>
<artifactId>ksp-maven-plugin</artifactId>
<version>[LATEST VERSION]</version>
<executions>
<execution>
<goals>
<goal>process</goal>
</goals>
</execution>
</executions>
<configuration>
<!-- Main source directory to process (default: ${project.build.sourceDirectory}) -->
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<!-- Additional source directories (default: none) -->
<sourceDirs>
<sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
<sourceDir>${project.basedir}/src/generated/kotlin</sourceDir>
</sourceDirs>
<!-- Output directory for generated Kotlin sources (default: ${project.build.directory}/generated-sources/ksp) -->
<kotlinOutputDir>${project.build.directory}/generated-sources/ksp</kotlinOutputDir>
<!-- Output directory for generated Java sources (default: ${project.build.directory}/generated-sources/ksp) -->
<javaOutputDir>${project.build.directory}/generated-sources/ksp</javaOutputDir>
<!-- Output directory for compiled classes (default: ${project.build.directory}/ksp-classes) -->
<classOutputDir>${project.build.directory}/ksp-classes</classOutputDir>
<!-- Output directory for resources (default: ${project.build.directory}/generated-resources/ksp) -->
<resourceOutputDir>${project.build.directory}/generated-resources/ksp</resourceOutputDir>
<!-- KSP output directory (default: ${project.build.directory}/ksp) -->
<kspOutputDir>${project.build.directory}/ksp</kspOutputDir>
<!-- Cache directory for incremental processing (default: ${project.build.directory}/ksp-cache) -->
<cachesDir>${project.build.directory}/ksp-cache</cachesDir>
<!-- Enable incremental processing (default: false) -->
<incremental>true</incremental>
<!-- Enable incremental compilation logging (default: false) -->
<incrementalLog>true</incrementalLog>
<!-- Kotlin language version (default: 2.2) -->
<languageVersion>2.2</languageVersion>
<!-- Kotlin API version (default: 2.2) -->
<apiVersion>2.2</apiVersion>
<!-- JVM default mode for interfaces (default: disable) -->
<jvmDefaultMode>disable</jvmDefaultMode>
<!-- KSP processor options as key-value pairs (default: none) -->
<apOptions>
<option1>value1</option1>
<option2>value2</option2>
</apOptions>
<!-- Continue build on processing errors (default: false) -->
<ignoreProcessingErrors>false</ignoreProcessingErrors>
<!-- Treat all warnings as errors (default: false) -->
<allWarningsAsErrors>false</allWarningsAsErrors>
<!-- Map annotation arguments in Java sources (default: true) -->
<mapAnnotationArgumentsInJava>true</mapAnnotationArgumentsInJava>
<!-- Module name (default: ${project.artifactId}) -->
<moduleName>my-module</moduleName>
<!-- JVM target version (default: 11) -->
<jvmTarget>17</jvmTarget>
<!-- Skip KSP processing (default: false, can be set via -Dksp.skip=true) -->
<skip>false</skip>
<!-- Add generated sources to compilation (default: true) -->
<addGeneratedSourcesToCompile>true</addGeneratedSourcesToCompile>
<!-- Enable debug output (default: false) -->
<debug>false</debug>
</configuration>
<!-- KSP processors are plugin dependencies, not project dependencies -->
<dependencies>
<dependency>
<groupId>com.example</groupId>
<artifactId>my-ksp-processor</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>The plugin runs in the generate-sources phase by default:
- KSP processors run and generate code
- Generated sources are automatically added to the compilation source roots (when
addGeneratedSourcesToCompileistrue) - The Kotlin compiler compiles both original and generated sources
Skip KSP processing via command line:
mvn clean install -Dksp.skip=trueOr in your pom.xml:
<configuration>
<skip>true</skip>
</configuration>If you see "No KSP processors found in dependencies":
- Verify your processor is added as a plugin dependency (inside
<plugin><dependencies>section), not as a project dependency - Check the processor JAR contains
META-INF/services/com.google.devtools.ksp.processing.SymbolProcessorProvider - Ensure the dependency scope is not
test
If the Kotlin compiler can't find generated sources:
- Verify
addGeneratedSourcesToCompileistrue(default) - Check that KSP plugin runs before Kotlin compilation
- Verify output directories are correct
If incremental compilation causes problems:
- Disable it:
<incremental>false</incremental> - Clean the cache:
mvn clean - Delete
${project.build.directory}/ksp-cache
Enable debug output to see detailed processing information:
<configuration>
<debug>true</debug>
</configuration>This will log:
- Found KSP processors
- Processor classloader details
- Processor providers
- KSP configuration
- Incremental changes (if enabled)
Build, verify, install the plugin and test with sample project:
make buildFormat code:
make formatRun linting:
make lintGenerate API documentation:
make apidocsRun all checks (format, lint, build):
make allBuild and install the plugin:
mvn clean installTest with the sample project:
cd sample-project
mvn clean compileContributions are welcome! Please follow the Kotlin coding conventions and ensure all tests pass.