aboutsummaryrefslogtreecommitdiff
path: root/runners/gradle-plugin/src
diff options
context:
space:
mode:
authorSimon Ogorodnik <sem-oro@yandex.ru>2016-12-06 16:24:43 +0300
committerGitHub <noreply@github.com>2016-12-06 16:24:43 +0300
commit2d03ad01f650bc997dce076abaab0a61c2301a96 (patch)
tree957dbe5280cf1114cfecfca35d18b264be195255 /runners/gradle-plugin/src
parent5d030c6303270d8955b71c6738afd9c80d73662f (diff)
parent546e8edfd95c16665319bc371c6ccf63706ad1e4 (diff)
downloaddokka-2d03ad01f650bc997dce076abaab0a61c2301a96.tar.gz
dokka-2d03ad01f650bc997dce076abaab0a61c2301a96.tar.bz2
dokka-2d03ad01f650bc997dce076abaab0a61c2301a96.zip
Merge pull request #123 from Kotlin/isolated-classloader
Now dokka-fatjar complete isolated from poisonous Gradle environment
Diffstat (limited to 'runners/gradle-plugin/src')
-rw-r--r--runners/gradle-plugin/src/main/kotlin/ProxyUtils.kt46
-rw-r--r--runners/gradle-plugin/src/main/kotlin/logger.kt18
-rw-r--r--runners/gradle-plugin/src/main/kotlin/main.kt79
-rw-r--r--runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties3
4 files changed, 117 insertions, 29 deletions
diff --git a/runners/gradle-plugin/src/main/kotlin/ProxyUtils.kt b/runners/gradle-plugin/src/main/kotlin/ProxyUtils.kt
new file mode 100644
index 00000000..7bdf2f9d
--- /dev/null
+++ b/runners/gradle-plugin/src/main/kotlin/ProxyUtils.kt
@@ -0,0 +1,46 @@
+package org.jetbrains.dokka
+
+import java.lang.reflect.InvocationHandler
+import java.lang.reflect.InvocationTargetException
+import java.lang.reflect.Method
+import java.lang.reflect.Proxy
+
+
+/**
+ * Warning! Hard reflection magic used here.
+ *
+ * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm,
+ * to create access proxy for [delegate] into [targetClassLoader].
+ */
+@Suppress("UNCHECKED_CAST")
+inline fun <reified T : Any> automagicTypedProxy(targetClassLoader: ClassLoader, delegate: Any): T =
+ automagicProxy(targetClassLoader, T::class.java, delegate) as T
+
+
+/**
+ * Warning! Hard reflection magic used here.
+ *
+ * Creates [java.lang.reflect.Proxy] with pass through invocation algorithm,
+ * to create access proxy for [delegate] into [targetClassLoader].
+ *
+ */
+fun automagicProxy(targetClassLoader: ClassLoader, targetType: Class<*>, delegate: Any): Any =
+ Proxy.newProxyInstance(
+ targetClassLoader,
+ arrayOf(targetType),
+ DelegatedInvocationHandler(delegate)
+ )
+
+class DelegatedInvocationHandler(private val delegate: Any) : InvocationHandler {
+
+ @Throws(Throwable::class)
+ override fun invoke(proxy: Any, method: Method, args: Array<Any?>?): Any? {
+ val delegateMethod = delegate.javaClass.getMethod(method.name, *method.parameterTypes)
+ try {
+ delegateMethod.isAccessible = true
+ return delegateMethod.invoke(delegate, *(args ?: emptyArray()))
+ } catch (ex: InvocationTargetException) {
+ throw ex.targetException
+ }
+ }
+}
diff --git a/runners/gradle-plugin/src/main/kotlin/logger.kt b/runners/gradle-plugin/src/main/kotlin/logger.kt
deleted file mode 100644
index 715c1f04..00000000
--- a/runners/gradle-plugin/src/main/kotlin/logger.kt
+++ /dev/null
@@ -1,18 +0,0 @@
-package org.jetbrains.dokka.gradle
-
-import org.gradle.api.logging.Logger
-import org.jetbrains.dokka.DokkaLogger
-
-class DokkaGradleLogger(val logger: Logger) : DokkaLogger {
- override fun error(message: String) {
- logger.error(message)
- }
-
- override fun info(message: String) {
- logger.info(message)
- }
-
- override fun warn(message: String) {
- logger.warn(message)
- }
-} \ No newline at end of file
diff --git a/runners/gradle-plugin/src/main/kotlin/main.kt b/runners/gradle-plugin/src/main/kotlin/main.kt
index 49c3b8ba..51061415 100644
--- a/runners/gradle-plugin/src/main/kotlin/main.kt
+++ b/runners/gradle-plugin/src/main/kotlin/main.kt
@@ -8,15 +8,24 @@ import org.gradle.api.file.FileCollection
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPluginConvention
import org.gradle.api.tasks.*
-import org.jetbrains.dokka.DocumentationOptions
-import org.jetbrains.dokka.DokkaGenerator
-import org.jetbrains.dokka.SourceLinkDefinition
+import org.jetbrains.dokka.DokkaBootstrap
+import org.jetbrains.dokka.automagicTypedProxy
+import org.jetbrains.dokka.gradle.ClassloaderContainer.fatJarClassLoader
import java.io.File
import java.io.Serializable
+import java.net.URLClassLoader
import java.util.*
+import java.util.function.BiConsumer
open class DokkaPlugin : Plugin<Project> {
+
+ val properties = Properties()
+
+ init {
+ properties.load(javaClass.getResourceAsStream("/META-INF/gradle-plugins/org.jetbrains.dokka.properties"))
+ }
override fun apply(project: Project) {
+ version = properties.getProperty("dokka-version")
project.tasks.create("dokka", DokkaTask::class.java).apply {
moduleName = project.name
outputDirectory = File(project.buildDir, "dokka").absolutePath
@@ -24,6 +33,13 @@ open class DokkaPlugin : Plugin<Project> {
}
}
+var version: String? = null
+
+object ClassloaderContainer {
+ @JvmField
+ var fatJarClassLoader: ClassLoader? = null
+}
+
open class DokkaTask : DefaultTask() {
init {
group = JavaBasePlugin.DOCUMENTATION_GROUP
@@ -47,6 +63,8 @@ open class DokkaTask : DefaultTask() {
var jdkVersion: Int = 6
@Input
var sourceDirs: Iterable<File> = emptyList()
+ @Input
+ var dokkaFatJar: Any = "org.jetbrains.dokka:dokka-fatjar:$version"
protected open val sdkProvider: SdkProvider? = null
@@ -65,8 +83,27 @@ open class DokkaTask : DefaultTask() {
linkMappings.add(mapping)
}
+
+ fun loadFatJar() {
+ if (fatJarClassLoader == null) {
+ val fatjar = if (dokkaFatJar is File)
+ dokkaFatJar as File
+ else {
+ val dependency = project.buildscript.dependencies.create(dokkaFatJar)
+ val configuration = project.buildscript.configurations.detachedConfiguration(dependency)
+ configuration.description = "Dokka main jar"
+ configuration.resolve().first()
+ }
+
+ fatJarClassLoader = URLClassLoader(arrayOf(fatjar.toURI().toURL()))
+ }
+ }
+
+
@TaskAction
fun generate() {
+ loadFatJar()
+
val project = project
val sdkProvider = sdkProvider
val sourceDirectories = getSourceDirectories()
@@ -83,17 +120,39 @@ open class DokkaTask : DefaultTask() {
return
}
- DokkaGenerator(
- DokkaGradleLogger(logger),
+ val bootstrapClass = fatJarClassLoader!!.loadClass("org.jetbrains.dokka.DokkaBootstrapImpl")
+
+ val bootstrapInstance = bootstrapClass.constructors.first().newInstance()
+
+ val bootstrapProxy: DokkaBootstrap = automagicTypedProxy(javaClass.classLoader, bootstrapInstance)
+
+ bootstrapProxy.configure(
+ BiConsumer { level, message ->
+ when (level) {
+ "info" -> logger.info(message)
+ "warn" -> logger.warn(message)
+ "error" -> logger.error(message)
+ }
+ },
+ moduleName,
classpath.map { it.absolutePath },
sourceDirectories.map { it.absolutePath },
samples.filterNotNull().map { project.file(it).absolutePath },
includes.filterNotNull().map { project.file(it).absolutePath },
- moduleName,
- DocumentationOptions(outputDirectory, outputFormat,
- sourceLinks = linkMappings.map { SourceLinkDefinition(project.file(it.dir).absolutePath, it.url, it.suffix) },
- jdkVersion = jdkVersion)
- ).generate()
+ outputDirectory,
+ outputFormat,
+ false,
+ false,
+ false,
+ false,
+ 6,
+ true,
+ linkMappings.map {
+ val path = project.file(it.dir).absolutePath
+ "$path=${it.url}${it.suffix}"
+ })
+
+ bootstrapProxy.generate()
}
fun getSourceDirectories(): Collection<File> {
diff --git a/runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties b/runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties
index b42cfe9f..068bd352 100644
--- a/runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties
+++ b/runners/gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.jetbrains.dokka.properties
@@ -1 +1,2 @@
-implementation-class=org.jetbrains.dokka.gradle.DokkaPlugin \ No newline at end of file
+implementation-class=org.jetbrains.dokka.gradle.DokkaPlugin
+dokka-version=<version> \ No newline at end of file