[KAPT] Disable JPMS when running annotation processing
If sources contain module-info.java javac tries to validate modules existence/visibility during AP phase and fails, because we don't specify modules-path/patch-module. All these checks will be done in kotlin compiler and in javac for java classes. And it is not necessary to do it in AP too. So we go for easiest path possible - disable jpms for AP. #KT-32202 Fixed
This commit is contained in:
+38
-1
@@ -676,4 +676,41 @@ open class Kapt3IT : Kapt3BaseIT() {
|
||||
assertContains("Javac options: {-source=1.8}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testJpmsModule() {
|
||||
//jpms is part of java >= 9
|
||||
val javaHome = File(System.getProperty("jdk9Home")!!)
|
||||
Assume.assumeTrue("JDK 9 isn't available", javaHome.isDirectory)
|
||||
val options = defaultBuildOptions().copy(javaHome = javaHome)
|
||||
|
||||
val project = Project("jpms-module", directoryPrefix = "kapt2")
|
||||
|
||||
project.build("build", options = options) {
|
||||
assertSuccessful()
|
||||
assertKaptSuccessful()
|
||||
assertTasksExecuted(":compileKotlin", ":compileJava")
|
||||
assertFileExists("build/generated/source/kapt/main/lab/TestClassGenerated.java")
|
||||
assertFileExists(kotlinClassesDir() + "lab/TestClass.class")
|
||||
}
|
||||
|
||||
project.build("build", options = options) {
|
||||
assertSuccessful()
|
||||
assertTasksUpToDate(":compileKotlin", ":compileJava")
|
||||
}
|
||||
|
||||
project.projectDir.getFileByName("InjectedClass.kt").modify { text ->
|
||||
text.checkedReplace(
|
||||
"//placeholder",
|
||||
"fun someChange() = null"
|
||||
)
|
||||
}
|
||||
|
||||
project.build("build", options = options) {
|
||||
assertSuccessful()
|
||||
assertKaptSuccessful()
|
||||
assertTasksExecuted(":compileKotlin", ":compileJava")
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: "java"
|
||||
apply plugin: "kotlin"
|
||||
apply plugin: "kotlin-kapt"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
||||
implementation "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
|
||||
kapt "org.jetbrains.kotlin:annotation-processor-example:$kotlin_version"
|
||||
|
||||
implementation 'com.google.dagger:dagger:2.33'
|
||||
kapt 'com.google.dagger:dagger-compiler:2.33'
|
||||
|
||||
//jpms module provider
|
||||
implementation "org.apache.logging.log4j:log4j-api:2.14.0"
|
||||
}
|
||||
|
||||
compileKotlin.kotlinOptions.allWarningsAsErrors = true
|
||||
|
||||
compileJava {
|
||||
doFirst {
|
||||
options.compilerArgs += [
|
||||
//workaround to make classpath into modules for java compilation so auto modules would work
|
||||
'--module-path', classpath.asPath,
|
||||
//provide compiled kotlin classes to javac (needed for java/kotlin mixed sources to work)
|
||||
'--patch-module', "my.module=${sourceSets.main.output.asPath}"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
//starting from gradle 6.4 it has built in jpms support
|
||||
//still as for now it doesn't work with fully legacy jars (with no module's descriptor)
|
||||
//so we need workaround above till we get AP packed as module
|
||||
//java {
|
||||
// modularity.inferModulePath.set(true)
|
||||
//}
|
||||
+1
@@ -0,0 +1 @@
|
||||
kapt.verbose=true
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package dagger_example;
|
||||
|
||||
import dagger.Component;
|
||||
|
||||
@Component(modules = {ExampleModule.class})
|
||||
public interface ApplicationComponent {
|
||||
void inject(Main main);
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
package dagger_example;
|
||||
|
||||
import dagger.Binds;
|
||||
import dagger.Module;
|
||||
|
||||
@Module
|
||||
public abstract class ExampleModule {
|
||||
@Binds
|
||||
public abstract Injected bindInjected(InjectedImpl impl);
|
||||
|
||||
@Binds
|
||||
public abstract OtherInjected bindOtherInjected(OtherInjectedImpl impl);
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
package dagger_example;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class Main {
|
||||
@Inject
|
||||
Injected injected;
|
||||
|
||||
@Inject
|
||||
OtherInjected otherInjected;
|
||||
|
||||
public static void main(String[] args) {
|
||||
new Main().example();
|
||||
}
|
||||
|
||||
private void example() {
|
||||
DaggerApplicationComponent.create().inject(this);
|
||||
System.out.println(injected.getMessage());
|
||||
}
|
||||
}
|
||||
+6
@@ -0,0 +1,6 @@
|
||||
package dagger_example;
|
||||
|
||||
public interface OtherInjected {
|
||||
|
||||
public String getMessage();
|
||||
}
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package dagger_example;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
public class OtherInjectedImpl implements OtherInjected {
|
||||
|
||||
@Inject
|
||||
public OtherInjectedImpl() {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMessage() {
|
||||
return "zzzz";
|
||||
}
|
||||
}
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
module my.module {
|
||||
requires kotlin.stdlib;
|
||||
requires org.apache.logging.log4j;
|
||||
requires annotation.processor.example;
|
||||
|
||||
requires dagger;
|
||||
requires javax.inject;
|
||||
//because dagger generates classes with @javax.annotation.processing.Generated
|
||||
requires java.compiler;
|
||||
}
|
||||
+14
@@ -0,0 +1,14 @@
|
||||
package dagger_example
|
||||
|
||||
import javax.inject.Inject
|
||||
|
||||
interface Injected {
|
||||
|
||||
val message: String
|
||||
}
|
||||
|
||||
class InjectedImpl @Inject constructor() : Injected {
|
||||
override val message = "This is injected1: " + SomeOtherClass().callMe()
|
||||
|
||||
//placeholder
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package dagger_example
|
||||
|
||||
class SomeOtherClass {
|
||||
|
||||
fun callMe() = "hell1o"
|
||||
fun changeMe() = null
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package lab
|
||||
|
||||
@example.ExampleAnnotation
|
||||
@example.ExampleSourceAnnotation
|
||||
@example.ExampleBinaryAnnotation
|
||||
@example.ExampleRuntimeAnnotation
|
||||
public class TestClass {
|
||||
|
||||
@example.ExampleAnnotation
|
||||
public val testVal: String = "text"
|
||||
|
||||
@example.ExampleAnnotation
|
||||
public fun testFunction(): TestClassGenerated = TestClassGenerated()
|
||||
|
||||
}
|
||||
+17
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package test
|
||||
|
||||
import org.apache.logging.log4j.util.Base64Util
|
||||
import org.apache.logging.log4j.*
|
||||
|
||||
@example.ExampleAnnotation
|
||||
class ModuleUser {
|
||||
|
||||
fun useSomethingFromModule(): String = Base64Util.encode("test")
|
||||
|
||||
fun haveSomeUsageInSignature(): Logger = TODO("I have nothing")
|
||||
}
|
||||
@@ -120,12 +120,10 @@ open class KaptContext(val options: KaptOptions, val withJdk: Boolean, val logge
|
||||
options.compileClasspath + options.compiledSources + options.classesOutputDir
|
||||
}
|
||||
|
||||
putJavacOption("CLASSPATH", "CLASS_PATH",
|
||||
compileClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
||||
putJavacOption("CLASSPATH", "CLASS_PATH", compileClasspath.makePathsString())
|
||||
|
||||
@Suppress("SpellCheckingInspection")
|
||||
putJavacOption("PROCESSORPATH", "PROCESSOR_PATH",
|
||||
options.processingClasspath.joinToString(File.pathSeparator) { it.canonicalPath })
|
||||
putJavacOption("PROCESSORPATH", "PROCESSOR_PATH", options.processingClasspath.makePathsString())
|
||||
|
||||
put(Option.S, options.sourcesOutputDir.canonicalPath)
|
||||
put(Option.D, options.classesOutputDir.canonicalPath)
|
||||
@@ -164,4 +162,10 @@ open class KaptContext(val options: KaptOptions, val withJdk: Boolean, val logge
|
||||
compiler.close()
|
||||
fileManager.close()
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val MODULE_INFO_FILE = "module-info.java"
|
||||
|
||||
private fun Iterable<File>.makePathsString(): String = joinToString(File.pathSeparator) { it.canonicalPath }
|
||||
}
|
||||
}
|
||||
|
||||
+13
-4
@@ -38,9 +38,18 @@ fun KaptContext.doAnnotationProcessing(
|
||||
|
||||
val wrappedProcessors = processors.map { ProcessorWrapper(it) }
|
||||
|
||||
val javaSourcesToProcess = run {
|
||||
//module descriptor should be in root package, but here we filter it from everywhere (bc we don't have knowledge about root here)
|
||||
val filtered = javaSourceFiles.filterNot { it.name == KaptContext.MODULE_INFO_FILE }
|
||||
if (filtered.size != javaSourceFiles.size) {
|
||||
logger.info("${KaptContext.MODULE_INFO_FILE} is removed from sources files to disable JPMS")
|
||||
}
|
||||
filtered
|
||||
}
|
||||
|
||||
val compilerAfterAP: JavaCompiler
|
||||
try {
|
||||
if (javaSourceFiles.isEmpty() && binaryTypesToReprocess.isEmpty() && additionalSources.isEmpty()) {
|
||||
if (javaSourcesToProcess.isEmpty() && binaryTypesToReprocess.isEmpty() && additionalSources.isEmpty()) {
|
||||
if (logger.isVerbose) {
|
||||
logger.info("Skipping annotation processing as all sources are up-to-date.")
|
||||
}
|
||||
@@ -55,10 +64,10 @@ fun KaptContext.doAnnotationProcessing(
|
||||
}
|
||||
|
||||
if (logger.isVerbose) {
|
||||
logger.info("Processing java sources with annotation processors: ${javaSourceFiles.joinToString()}")
|
||||
logger.info("Processing java sources with annotation processors: ${javaSourcesToProcess.joinToString()}")
|
||||
logger.info("Processing types with annotation processors: ${binaryTypesToReprocess.joinToString()}")
|
||||
}
|
||||
val parsedJavaFiles = parseJavaFiles(javaSourceFiles)
|
||||
val parsedJavaFiles = parseJavaFiles(javaSourcesToProcess)
|
||||
|
||||
val sourcesStructureListener = cacheManager?.let {
|
||||
if (processors.any { it.isUnableToRunIncrementally() }) return@let null
|
||||
@@ -231,4 +240,4 @@ private fun KaptContext.initModulesIfNeeded(files: JavacList<JCTree.JCCompilatio
|
||||
}
|
||||
|
||||
return files
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user