Skip to content

Commit

Permalink
feat: Plugin支持第三方jar #201
Browse files Browse the repository at this point in the history
  • Loading branch information
felixncheng committed Jul 2, 2024
1 parent 90a344d commit e2f8a1a
Show file tree
Hide file tree
Showing 4 changed files with 31 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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." }
Expand All @@ -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(),
)
}
}
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -110,12 +114,26 @@ class PluginLoader(
}
}

private fun createClassloader(pluginPath: Path): ClassLoader {
val jarArchive = JarFileArchive(pluginPath.toFile())
val archives = jarArchive.getNestedArchives(searchFilter, nestedFilter)
val urls = mutableListOf<URL>(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"
private const val PLUGIN_VERSION = "Plugin-Version"
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/")
}
}
}
7 changes: 6 additions & 1 deletion devops-boot-sample/plugin-printer/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -30,4 +30,9 @@ tasks.withType<Jar> {
"Plugin-Description" to pluginDescription
)
}
// 添加lib
from(configurations.runtimeClasspath.get().filter { it.name.endsWith(".jar") }) {
into("lib")
}
entryCompression = ZipEntryCompression.STORED
}
Original file line number Diff line number Diff line change
Expand Up @@ -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")
}
}

0 comments on commit e2f8a1a

Please sign in to comment.