neu242
neu242

Reputation: 16575

How do I add dependencies to my custom Gradle plugin?

I get a NoClassDefFoundError when trying to add a dependency to my custom Gradle plugin, and I haven't found a way to solve it.

Added to the plugin's dependency block:

implementation("org.apache.logging.log4j:log4j-api:2.11.2")
implementation("org.apache.logging.log4j:log4j-core:2.11.2")

Added to the plugin's DeclarationAttributeAltererExtension implementation:

val log = LogManager.getLogger(ReallyAllOpenExtension::class.java)

Here's the full stacktrace:

no.synth.kotlin.plugins.reallyallopen.FunctionalPluginTest > should include plugin via plugins block FAILED
    org.gradle.testkit.runner.UnexpectedBuildFailure: Unexpected build execution failure in /var/folders/g4/024g2mzn7jl5s2b2cvg_ythh00016k/T/junit5022572406008108408 with arguments [build]

    Output:

    > Task :compileKotlin FAILED
    e: java.lang.NoClassDefFoundError: org/apache/logging/log4j/LogManager
        at no.synth.kotlin.plugins.reallyallopen.ReallyAllOpenExtension.<clinit>(ReallyAllOpenPlugin.kt:106)
        at no.synth.kotlin.plugins.reallyallopen.ReallyAllOpenRegistrar.registerProjectComponents(ReallyAllOpenPlugin.kt:79)
        at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment.<init>(KotlinCoreEnvironment.kt:174)
        at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment.<init>(KotlinCoreEnvironment.kt:123)
        at org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment$Companion.createForProduction(KotlinCoreEnvironment.kt:413)
        at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.createCoreEnvironment(K2JVMCompiler.kt:259)
        at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:124)
        at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:54)
        at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:84)
        at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:42)
        at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:103)
        at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:364)
        at org.jetbrains.kotlin.incremental.IncrementalJvmCompilerRunner.runCompiler(IncrementalJvmCompilerRunner.kt:105)
        at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compileIncrementally(IncrementalCompilerRunner.kt:237)
        at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.access$compileIncrementally(IncrementalCompilerRunner.kt:37)
        at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner$compile$2.invoke(IncrementalCompilerRunner.kt:79)
        at org.jetbrains.kotlin.incremental.IncrementalCompilerRunner.compile(IncrementalCompilerRunner.kt:91)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl.execIncrementalCompiler(CompileServiceImpl.kt:597)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl.access$execIncrementalCompiler(CompileServiceImpl.kt:102)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:455)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl$compile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:102)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:1023)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl$doCompile$$inlined$ifAlive$lambda$2.invoke(CompileServiceImpl.kt:102)
        at org.jetbrains.kotlin.daemon.common.DummyProfiler.withMeasure(PerfUtils.kt:137)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl.checkedCompile(CompileServiceImpl.kt:1065)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl.doCompile(CompileServiceImpl.kt:1022)
        at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:454)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:566)
        at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:359)
        at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
        at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:196)
        at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:562)
        at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:796)
        at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:677)
        at java.base/java.security.AccessController.doPrivileged(Native Method)
        at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:676)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
        at java.base/java.lang.Thread.run(Thread.java:834)
    Caused by: java.lang.ClassNotFoundException: org.apache.logging.log4j.LogManager
        at java.base/java.net.URLClassLoader.findClass(URLClassLoader.java:471)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:588)
        at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:521)
        ... 44 more

The full implementation and test case is in a separate branch at https://github.com/henrik242/kotlin-really-allopen/tree/unable-to-add-dependencies

Recreate the problem by running ./gradlew clean :kotlin-really-allopen:build :kotlin-really-allopen:publishToMavenLocal :functional-test:build

Upvotes: 1

Views: 474

Answers (1)

deduper
deduper

Reputation: 1964

I suspect your problem is because of known classloader issues with plugins exercised with Gradle's TestKit.

I will paraphrase what that link says: Your plugin and its runtime classpath are loaded with one classloader. The functional test and its classpath are loaded in yet a second different classloader. Such a situation is the classic recipe for NoClassDefFoundErrors. Therefore, when using TestKit with a custom plugin, the plugin's runtime classpath must be explicitly injected into the runtime classpath of the functional test that is exercising the plugin.

The way your project is organized — with the functional test as a subproject — is likely to compound those known classloader issues. It certainly makes things more complicated than they need to be.

The answer to your question, therefore, is: Reorganize your project.

Using the Gradle User Guide as a guide, I simplified your project. I forked and reorganized it the way Gradle advises.

The fixed code is in the able-to-add-dependencies branch of the fork.

Upvotes: 2

Related Questions