如何从 gradle 已经有主项目的项目中 运行 Kotlin 脚本?
How to run a Kotlin script from within a gradle project that already has a main?
我有一个名为 Application.kt
的 Ktor 项目。
布局是这样的
.
└── com
└── myProject
├── Application.kt
├── Testing.kt
├── api
│ ├── Routes.kt
│ └── routes
│ ├── NewRoutes.kt
│ ├── OpenApiRoutes.kt
│ └── OldRoutes.kt
├── data
│ ├── Mongo.kt
│ ├── model
│ │ ├── model1
│ │ │ ├── Model1.kt
│ │ └── model2
│ │ ├── Model2.kt
│ └── repository
│ ├── MongoRepository.kt
│ └── Repository.kt
但现在我有一个脚本,我想 运行 作为 Kubernetes init 容器的一部分,文件看起来像这样
import com.myProject.data.Mongo
import org.bson.BsonDocument
import org.litote.kmongo.formatJson
class Testing {
suspend fun test() {
return whatever
}
suspend fun test2() {
return whatever2
}
}
suspend fun main() {
val create = Testing()
create.test()
create.test2()
}
我试过 运行ning ./gradlew testing
我在我的 build.gradle 中这样定义:
task testing( type: JavaExec) {
main = 'com.myProject.Testing'
}
但是没有用,有没有人有什么想法?
当尝试 运行 使用上面的 gradle 命令时,我得到错误 Could not find or load main class Testing
我的build.gradle
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
buildscript {
repositories {
jcenter()
maven { url 'https://jitpack.io' }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.github.jengelman.gradle.plugins:shadow:6.1.0'
}
}
task testing( type: JavaExec) {
main = 'com.myProject.Testing'
classpath = sourceSets.main.runtimeClasspath
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
}
}
apply plugin: "java"
apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'jacoco'
group 'com.myProject'
version '0.0.1'
mainClassName = "io.ktor.server.netty.EngineMain"
shadowJar {
manifest {
attributes 'Main-Class': mainClassName
}
}
sourceSets {
main.kotlin.srcDirs = main.java.srcDirs = ['src']
test.kotlin.srcDirs = test.java.srcDirs = ['test']
main.resources.srcDirs = ['resources']
test.resources.srcDirs = ['testresources']
}
repositories {
mavenCentral()
jcenter()
maven { url 'https://jitpack.io' }
maven { url 'https://kotlin.bintray.com/ktor' }
}
您可以使用以下格式来定义任务:
task <task-name>(type: JavaExec) {
main = '[<package>.]<file-class>'
classpath = sourceSets.main.runtimeClasspath
}
其中 <task-name>
— Gradle 任务的名称,<package>
— 您的脚本所在的包 class,<file-class>
— 没有扩展名的大写文件名+ Kt
后缀。
例如,如果我调用任务 runScript
并且脚本位于 /src/main/kotlin/script.kt
(顶级包)中,那么任务定义如下:
task runScript(type: JavaExec) {
main = 'ScriptKt'
classpath = sourceSets.main.runtimeClasspath
}
您的 main
函数不属于 Testing
class。所以 com.myProject.Testing
不是有效的主要 class 名称。
您应该将 main
方法移动到 Testing
class 的 companion object
(就像 class 的静态方法),或者更改 gradle 构建文件以使用生成的 class 名称作为顶级声明,遵循约定:
package_name + .
+ capitalized_file_name + Kt
如果您的文件名为 Testing.kt
,并且您的声明包是 com.myProject
,您的完全限定主 class 名称应该是:
com.myProject.TestingKt
(注意最后的Kt
)
但是我在 Testing.kt
的顶部没有看到 package
声明。您是为了简洁而忽略了它还是真的忘记了它?
我有一个名为 Application.kt
的 Ktor 项目。
布局是这样的
.
└── com
└── myProject
├── Application.kt
├── Testing.kt
├── api
│ ├── Routes.kt
│ └── routes
│ ├── NewRoutes.kt
│ ├── OpenApiRoutes.kt
│ └── OldRoutes.kt
├── data
│ ├── Mongo.kt
│ ├── model
│ │ ├── model1
│ │ │ ├── Model1.kt
│ │ └── model2
│ │ ├── Model2.kt
│ └── repository
│ ├── MongoRepository.kt
│ └── Repository.kt
但现在我有一个脚本,我想 运行 作为 Kubernetes init 容器的一部分,文件看起来像这样
import com.myProject.data.Mongo
import org.bson.BsonDocument
import org.litote.kmongo.formatJson
class Testing {
suspend fun test() {
return whatever
}
suspend fun test2() {
return whatever2
}
}
suspend fun main() {
val create = Testing()
create.test()
create.test2()
}
我试过 运行ning ./gradlew testing
我在我的 build.gradle 中这样定义:
task testing( type: JavaExec) {
main = 'com.myProject.Testing'
}
但是没有用,有没有人有什么想法?
当尝试 运行 使用上面的 gradle 命令时,我得到错误 Could not find or load main class Testing
我的build.gradle
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
buildscript {
repositories {
jcenter()
maven { url 'https://jitpack.io' }
}
dependencies {
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.github.jengelman.gradle.plugins:shadow:6.1.0'
}
}
task testing( type: JavaExec) {
main = 'com.myProject.Testing'
classpath = sourceSets.main.runtimeClasspath
}
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
}
}
apply plugin: "java"
apply plugin: 'kotlin'
apply plugin: 'application'
apply plugin: 'com.github.johnrengelman.shadow'
apply plugin: 'jacoco'
group 'com.myProject'
version '0.0.1'
mainClassName = "io.ktor.server.netty.EngineMain"
shadowJar {
manifest {
attributes 'Main-Class': mainClassName
}
}
sourceSets {
main.kotlin.srcDirs = main.java.srcDirs = ['src']
test.kotlin.srcDirs = test.java.srcDirs = ['test']
main.resources.srcDirs = ['resources']
test.resources.srcDirs = ['testresources']
}
repositories {
mavenCentral()
jcenter()
maven { url 'https://jitpack.io' }
maven { url 'https://kotlin.bintray.com/ktor' }
}
您可以使用以下格式来定义任务:
task <task-name>(type: JavaExec) {
main = '[<package>.]<file-class>'
classpath = sourceSets.main.runtimeClasspath
}
其中 <task-name>
— Gradle 任务的名称,<package>
— 您的脚本所在的包 class,<file-class>
— 没有扩展名的大写文件名+ Kt
后缀。
例如,如果我调用任务 runScript
并且脚本位于 /src/main/kotlin/script.kt
(顶级包)中,那么任务定义如下:
task runScript(type: JavaExec) {
main = 'ScriptKt'
classpath = sourceSets.main.runtimeClasspath
}
您的 main
函数不属于 Testing
class。所以 com.myProject.Testing
不是有效的主要 class 名称。
您应该将 main
方法移动到 Testing
class 的 companion object
(就像 class 的静态方法),或者更改 gradle 构建文件以使用生成的 class 名称作为顶级声明,遵循约定:
package_name + .
+ capitalized_file_name + Kt
如果您的文件名为 Testing.kt
,并且您的声明包是 com.myProject
,您的完全限定主 class 名称应该是:
com.myProject.TestingKt
(注意最后的Kt
)
但是我在 Testing.kt
的顶部没有看到 package
声明。您是为了简洁而忽略了它还是真的忘记了它?