求可自动将Java模型转为Kotlin的Gradle插件或脚本化工具
Java模型转Compose Multiplatform Kotlin类的自动化方案
问题背景
现有Angular项目曾使用cz.habarta.typescript-generator Gradle插件,将服务端Java模型转换为TypeScript供前端使用。迁移至Compose Multiplatform后,发现直接调用Java库会导致iOS和WebASM运行失败。仅需同步特定模型类,寻求可处理指定.java或.class文件生成Kotlin类的工具,要求如下:
- 禁止手动粘贴类、网站或IDE工具
- 服务端保持Java技术栈(基于TomEE,使用大量Java ORM与安全库)
- 支持构建时自动同步,实现长期可维护(如Java类新增字段后自动同步到客户端)
- 可接受精度损失(如强制字段nullable),也可接受Java→TypeScript→Kotlin的转换方案
- 仅保留数据结构,忽略Java类中的逻辑,避免手动跨层同步业务模型
可行工具与实现方案
1. JavaToKotlin Gradle插件
直接基于IntelliJ的Java转Kotlin引擎,可将指定Java源文件转换为Kotlin类,支持集成到构建流程自动执行。
配置示例:
plugins { id 'org.jetbrains.kotlin.jvm' version '1.9.20' id 'io.github.microutils.java-to-kotlin' version '1.5.0' } javaToKotlin { // 指定服务端模型源文件目录 sourceDirs = files('../server/src/main/java/com/example/models') // 筛选需要转换的类 include 'com/example/dto/**/*.java' // 排除包含业务逻辑的类 exclude 'com/example/models/**/*Service.java' // 输出到Compose Multiplatform的common模块 outputDir = file('src/commonMain/kotlin') // 强制所有字段为可空类型,接受精度损失 conversionOptions = [ makePropertiesNullable: 'true', convertNullAssertions: 'true' ] } // 将转换任务绑定到编译流程,确保构建时自动同步 tasks.compileKotlin.dependsOn tasks.convertJavaToKotlin
该插件会自动剥离Java类中的方法逻辑,仅保留字段结构,适配Kotlin数据类的格式,无需额外手动调整。
2. 自定义Gradle任务结合JavaParser
如果需要更精细的控制(比如自定义类型映射、过滤特定注解),可以用JavaParser解析Java源文件,手动生成Kotlin数据类。
核心实现示例:
import com.github.javaparser.JavaParser import com.github.javaparser.ast.body.FieldDeclaration task generateKotlinModels { doLast { def sourceDir = file('../server/src/main/java/com/example/models') def outputDir = file('src/commonMain/kotlin') outputDir.mkdirs() sourceDir.eachFileRecurse(groovy.io.FileType.FILES) { file -> if (file.name.endsWith('.java')) { def compilationUnit = JavaParser.parse(file) def className = compilationUnit.types[0].nameAsString def packageName = compilationUnit.packageDeclaration?.nameAsString ?: '' def fields = compilationUnit.types[0].fields.findAll { it.variables.size() == 1 } // 生成Kotlin数据类代码,强制所有字段可空 def kotlinFields = fields.collect { FieldDeclaration field -> def fieldName = field.variables[0].nameAsString def fieldType = mapJavaTypeToKotlin(field.type.toString()) "var $fieldName: $fieldType? = null" }.join(',\n ') def kotlinCode = """package $packageName data class $className( $kotlinFields )""" def outputFilePath = "${packageName.replace('.', '/')}/${className}.kt" def outputFile = new File(outputDir, outputFilePath) outputFile.parentFile.mkdirs() outputFile.text = kotlinCode } } } } // 自定义Java到Kotlin的类型映射 def mapJavaTypeToKotlin(javaType) { return switch(javaType) { case 'int', 'Integer' -> 'Int' case 'long', 'Long' -> 'Long' case 'boolean', 'Boolean' -> 'Boolean' case 'String' -> 'String' case 'List' -> 'List<*>' default -> javaType // 复杂类型直接保留类名,需确保客户端有对应依赖 } } tasks.compileKotlin.dependsOn generateKotlinModels
这种方案完全可控,可根据需求调整字段生成规则,比如保留ORM字段注解、过滤静态字段等。
3. 复用TypeScript生成链路(Java→TypeScript→Kotlin)
如果已熟悉cz.habarta.typescript-generator的配置,可以先生成TypeScript接口,再通过ts2kt工具转换为Kotlin类。
配置示例:
// 第一步:生成TypeScript模型 task generateTypeScriptModels { doLast { // 调用cz.habarta.typescript-generator生成TS文件 exec { commandLine 'java', '-jar', 'libs/typescript-generator-cli.jar', '--input-classes', 'com.example.dto.User,com.example.dto.Order', '--output-file', 'build/tmp/models/models.ts', '--json-library', 'jackson2' } } } // 第二步:将TS转换为Kotlin task convertTsToKotlin { dependsOn generateTypeScriptModels doLast { // 使用ts2kt工具转换,需提前通过npm安装:npm install -g ts2kt exec { commandLine 'npx', 'ts2kt', '-d', 'src/commonMain/kotlin', 'build/tmp/models/models.ts' } } } // 绑定到编译流程 tasks.compileKotlin.dependsOn convertTsToKotlin
这种方案复用原有配置,适合过渡阶段,但需注意TypeScript到Kotlin的类型映射可能需要额外调整,确保生成的Kotlin类符合Compose Multiplatform的要求。
内容的提问来源于stack exchange,提问作者Gus
相关产品推荐
相关产品推荐

