Skip to content

Commit d557b26

Browse files
ADFA-4636: Remove Kotlin/JS and Kotlin/Native backends from kt-android.jar
Adds excludeEntryPrefixes support to ExternalJarDependencyConfiguration and ExternalAssetsPlugin so that ZIP entries matching listed prefixes are stripped from a cached copy of the downloaded JAR before it is added as a dependency. Configures kotlin-analysis-api to strip all org/jetbrains/kotlin/js/ and org/jetbrains/kotlin/konan/ classes (794 entries, ~3.4 MB) since neither backend has any place in an Android IDE. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 232cec2 commit d557b26

3 files changed

Lines changed: 68 additions & 1 deletion

File tree

‎composite-builds/build-logic/plugins/src/main/java/com/itsaky/androidide/plugins/ExternalAssetsPlugin.kt‎

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,15 @@ import org.gradle.api.ExtensiblePolymorphicDomainObjectContainer
1414
import org.gradle.api.Plugin
1515
import org.gradle.api.Project
1616
import org.gradle.api.file.Directory
17+
import org.gradle.api.logging.Logger
1718
import org.gradle.api.model.ObjectFactory
1819
import org.gradle.api.provider.Provider
1920
import org.gradle.kotlin.dsl.dependencies
2021
import org.gradle.kotlin.dsl.newInstance
22+
import java.io.File
23+
import java.util.zip.ZipEntry
24+
import java.util.zip.ZipInputStream
25+
import java.util.zip.ZipOutputStream
2126
import javax.inject.Inject
2227

2328
private fun Project.externalAssetsCacheDir(): Provider<Directory> =
@@ -76,8 +81,17 @@ abstract class ExternalAssetsExtension @Inject constructor(
7681
logger = project.logger
7782
)
7883

84+
val jarFileName = if (config.excludeEntryPrefixes.isEmpty()) {
85+
config.jarName
86+
} else {
87+
val original = cacheDir.resolve(config.jarName)
88+
val stripped = cacheDir.resolve(config.jarName.replace(".jar", "-stripped.jar"))
89+
stripJar(original, stripped, config.excludeEntryPrefixes, project.logger)
90+
stripped.name
91+
}
92+
7993
val dep = project.dependencies.create(project.fileTree(cacheDir) {
80-
include(config.jarName)
94+
include(jarFileName)
8195
})
8296

8397
project.dependencies {
@@ -86,6 +100,30 @@ abstract class ExternalAssetsExtension @Inject constructor(
86100
}
87101
}
88102

103+
private fun stripJar(source: File, dest: File, excludePrefixes: List<String>, logger: Logger) {
104+
if (dest.exists() && dest.lastModified() >= source.lastModified()) {
105+
logger.lifecycle("Skipping strip of ${source.name}: stripped copy is up-to-date")
106+
return
107+
}
108+
logger.lifecycle("Stripping ${excludePrefixes.size} prefix(es) from ${source.name}…")
109+
ZipInputStream(source.inputStream().buffered()).use { zin ->
110+
ZipOutputStream(dest.outputStream().buffered()).use { zout ->
111+
var entry: ZipEntry? = zin.nextEntry
112+
while (entry != null) {
113+
if (excludePrefixes.none { entry!!.name.startsWith(it) }) {
114+
zout.putNextEntry(ZipEntry(entry.name))
115+
zin.copyTo(zout)
116+
zout.closeEntry()
117+
}
118+
zin.closeEntry()
119+
entry = zin.nextEntry
120+
}
121+
}
122+
}
123+
val savedKb = (source.length() - dest.length()) / 1024
124+
logger.lifecycle("Stripped ${source.name}: saved ${savedKb} KB (${source.length()} → ${dest.length()} bytes)")
125+
}
126+
89127
/**
90128
* Plugin used to download files from external sources and package them as assets.
91129
*

‎composite-builds/build-logic/plugins/src/main/java/com/itsaky/androidide/plugins/extension/ExternalAssetsExtension.kt‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,11 @@ abstract class ExternalJarDependencyConfiguration @Inject constructor(
123123
* The name of the JAR file to be added to the dependencies.
124124
*/
125125
var jarName: String = "${name}.jar"
126+
127+
/**
128+
* Entry name prefixes to strip from the JAR before adding it as a dependency.
129+
* Any ZIP entry whose name starts with one of these prefixes is excluded from the
130+
* stripped copy (e.g. "org/jetbrains/kotlin/js/").
131+
*/
132+
var excludeEntryPrefixes: List<String> = emptyList()
126133
}

‎subprojects/kotlin-analysis-api/build.gradle.kts‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,27 @@ externalAssets {
2323
url = uri("$ktAndroidRepo/releases/download/$ktAndroidTag/$ktAndroidJarName"),
2424
sha256Checksum = "2069ed685dafd6eed36ebe242004ed5e24e28360293117323e2c988afefa6767",
2525
)
26+
excludeEntryPrefixes = listOf(
27+
// Kotlin/JS backend — not needed in an Android IDE
28+
"org/jetbrains/kotlin/js/",
29+
"META-INF/ir.serialization.js.kotlin_module",
30+
"META-INF/checkers.js.kotlin_module",
31+
"META-INF/compiler.common.js.kotlin_module",
32+
"META-INF/js.ast.kotlin_module",
33+
"META-INF/js.config.kotlin_module",
34+
"META-INF/js.frontend.common.kotlin_module",
35+
"META-INF/js.frontend.kotlin_module",
36+
"META-INF/js.parser.kotlin_module",
37+
"META-INF/js.serializer.kotlin_module",
38+
// Kotlin/Native (konan) backend — not needed in an Android IDE
39+
"org/jetbrains/kotlin/konan/",
40+
"META-INF/checkers.native.kotlin_module",
41+
"META-INF/compiler.common.native.kotlin_module",
42+
"META-INF/decompiler-native.kotlin_module",
43+
"META-INF/fir-native.kotlin_module",
44+
"META-INF/frontend.native.kotlin_module",
45+
"META-INF/ir.serialization.native.kotlin_module",
46+
"META-INF/kotlin-native-utils.kotlin_module",
47+
)
2648
}
2749
}

0 commit comments

Comments
 (0)