From e2f8a1a8ee187ef532996cd38ea3e0c9aaa5e4a7 Mon Sep 17 00:00:00 2001 From: felixncheng Date: Tue, 2 Jul 2024 16:18:27 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Plugin=E6=94=AF=E6=8C=81=E7=AC=AC?= =?UTF-8?q?=E4=B8=89=E6=96=B9jar=20#201?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../devops-plugin-core/build.gradle.kts | 1 + .../devops/plugin/core/PluginLoader.kt | 26 ++++++++++++++++--- .../plugin-printer/build.gradle.kts | 7 ++++- .../SystemIoPrintExtension.kt | 3 ++- 4 files changed, 31 insertions(+), 6 deletions(-) diff --git a/devops-boot-project/devops-boot-core/devops-plugin/devops-plugin-core/build.gradle.kts b/devops-boot-project/devops-boot-core/devops-plugin/devops-plugin-core/build.gradle.kts index f2ef859..e3ef1f8 100644 --- a/devops-boot-project/devops-boot-core/devops-plugin/devops-plugin-core/build.gradle.kts +++ b/devops-boot-project/devops-boot-core/devops-plugin/devops-plugin-core/build.gradle.kts @@ -4,5 +4,6 @@ dependencies { api(project(":devops-boot-project:devops-boot-core:devops-plugin:devops-plugin-api")) api("org.springframework.boot:spring-boot-starter") api("org.springframework:spring-webmvc") + api("org.springframework.boot:spring-boot-loader") compileOnly("org.springframework.boot:spring-boot-starter-actuator") } diff --git a/devops-boot-project/devops-boot-core/devops-plugin/devops-plugin-core/src/main/kotlin/com/tencent/devops/plugin/core/PluginLoader.kt b/devops-boot-project/devops-boot-core/devops-plugin/devops-plugin-core/src/main/kotlin/com/tencent/devops/plugin/core/PluginLoader.kt index c153a5c..6b47b95 100644 --- a/devops-boot-project/devops-boot-core/devops-plugin/devops-plugin-core/src/main/kotlin/com/tencent/devops/plugin/core/PluginLoader.kt +++ b/devops-boot-project/devops-boot-core/devops-plugin/devops-plugin-core/src/main/kotlin/com/tencent/devops/plugin/core/PluginLoader.kt @@ -4,7 +4,11 @@ import com.tencent.devops.plugin.api.EXTENSION_LOCATION import com.tencent.devops.plugin.api.ExtensionType import com.tencent.devops.plugin.api.PluginInfo import com.tencent.devops.plugin.api.PluginMetadata +import org.springframework.boot.loader.LaunchedURLClassLoader +import org.springframework.boot.loader.archive.Archive +import org.springframework.boot.loader.archive.JarFileArchive import java.io.IOException +import java.net.URL import java.nio.file.Files import java.nio.file.Path import java.security.MessageDigest @@ -16,10 +20,10 @@ import java.util.jar.JarFile * 插件加载器 */ class PluginLoader( - private val pluginPath: Path + private val pluginPath: Path, ) { - val classLoader = PluginClassLoader(pluginPath, javaClass.classLoader) + val classLoader = createClassloader(pluginPath) init { check(Files.exists(pluginPath)) { "Plugin file[$pluginPath] does not exist." } @@ -35,7 +39,7 @@ class PluginLoader( metadata = metadata, digest = digest, extensionPoints = extensions[ExtensionType.POINT].orEmpty(), - extensionControllers = extensions[ExtensionType.CONTROLLER].orEmpty() + extensionControllers = extensions[ExtensionType.CONTROLLER].orEmpty(), ) } } @@ -79,7 +83,7 @@ class PluginLoader( version = version, scope = scope, author = author, - description = description + description = description, ) } catch (ex: IOException) { throw IllegalArgumentException("Unable to load manifest from location [$MANIFEST_LOCATION]", ex) @@ -110,6 +114,16 @@ class PluginLoader( } } + private fun createClassloader(pluginPath: Path): ClassLoader { + val jarArchive = JarFileArchive(pluginPath.toFile()) + val archives = jarArchive.getNestedArchives(searchFilter, nestedFilter) + val urls = mutableListOf(jarArchive.url) + archives.forEach { + urls.add(it.url) + } + return LaunchedURLClassLoader(false, jarArchive, urls.toTypedArray(), javaClass.classLoader) + } + companion object { private const val MANIFEST_LOCATION = "META-INF/MANIFEST.MF" private const val PLUGIN_ID = "Plugin-Id" @@ -117,5 +131,9 @@ class PluginLoader( private const val PLUGIN_SCOPE = "Plugin-Scope" private const val PLUGIN_AUTHOR = "Plugin-Author" private const val PLUGIN_DESCRIPTION = "Plugin-Description" + val searchFilter = Archive.EntryFilter { entry -> entry.name.startsWith("lib/") } + val nestedFilter = Archive.EntryFilter { entry -> + !entry.isDirectory && entry.name.startsWith("lib/") + } } } diff --git a/devops-boot-sample/plugin-printer/build.gradle.kts b/devops-boot-sample/plugin-printer/build.gradle.kts index 69e8284..afb7a84 100644 --- a/devops-boot-sample/plugin-printer/build.gradle.kts +++ b/devops-boot-sample/plugin-printer/build.gradle.kts @@ -5,10 +5,10 @@ plugins { dependencies { // 引入插件扩展点定义,实际开发中通过jar包引入 implementation(project(":api-kotlin-sample")) + implementation("org.bytedeco:ffmpeg:6.0-1.5.9") kapt("com.tencent.devops:devops-plugin-processor") } - val pluginId: String? by project val pluginVersion: String? by project val pluginScope: String? by project @@ -30,4 +30,9 @@ tasks.withType { "Plugin-Description" to pluginDescription ) } + // 添加lib + from(configurations.runtimeClasspath.get().filter { it.name.endsWith(".jar") }) { + into("lib") + } + entryCompression = ZipEntryCompression.STORED } diff --git a/devops-boot-sample/plugin-printer/src/main/kotlin/com.tencent.devops.sample/SystemIoPrintExtension.kt b/devops-boot-sample/plugin-printer/src/main/kotlin/com.tencent.devops.sample/SystemIoPrintExtension.kt index c1d82bd..ca5c8f0 100644 --- a/devops-boot-sample/plugin-printer/src/main/kotlin/com.tencent.devops.sample/SystemIoPrintExtension.kt +++ b/devops-boot-sample/plugin-printer/src/main/kotlin/com.tencent.devops.sample/SystemIoPrintExtension.kt @@ -6,6 +6,7 @@ import com.tencent.devops.sample.extension.PrintExtension @Extension class SystemIoPrintExtension : PrintExtension { override fun print(content: String) { - println(content) + val loaded = javaClass.classLoader.loadClass("org.bytedeco.ffmpeg.global.avformat") != null + println("lib sdk loaded:$loaded, $content") } }