ryandens / javaagent-gradle-plugin

A set of Gradle plugins to ease building Java applications that leverage instrumentation agents in development and/or in production
Apache License 2.0
47 stars 8 forks source link

Incompatible with the shadow plugin/shadowDist #94

Open tajobe opened 6 months ago

tajobe commented 6 months ago

The Gradle shadow plugin has the ability to create an equivalent distribution but using the shadowed dependencies: https://imperceptiblethoughts.com/shadow/application-plugin/#distributing-the-shadow-jar

This plugin seems to set the javaagent path specifically for the ApplicationPlugin's task, not any/all CreateStartScripts type tasks. It might be useful to add the same injection of the javaagent to the ShadowApplicationPlugin.SHADOW_SCRIPTS_TASK_NAME task so it can be used in conjunction with shadow.


Working around this by basically recreating what the plugin does:

distributions.named("shadow") {
    contents.from(configurations.javaagent) { into("agent-libs") }
}

tasks.named<CreateStartScripts>(ShadowApplicationPlugin.SHADOW_SCRIPTS_TASK_NAME) {
    inputs.files(configurations.javaagent)
    defaultJvmOpts = listOf("-javaagent:COM_RYANDENS_JAVAAGENTS_PLACEHOLDER.jar").plus(defaultJvmArgs)
    unixStartScriptGenerator = JavaagentAwareStartScriptGenerator(configurations.javaagent.map { it.files })
}

Edit: the workaround is a bit more complicated as the script generated using the above isn't usable...instead I'm manually mapping the javaagent files to jvm opts and working around gradle/gradle#19795 with a pattern/replace. It's a bit ugly...

tasks.named<CreateStartScripts>(ShadowApplicationPlugin.SHADOW_SCRIPTS_TASK_NAME) {
    defaultJvmOpts = configurations.javaagent.get().files.map { jar ->
        "-javaagent:\$\\{APP_HOME\\}/agent-libs/${jar.name}"
    }.plus(defaultJvmArgs)

    // FIXME - Replace env var template in `DEFAULT_JVM_OPTS`
    //  Workaround for https://github.com/gradle/gradle/issues/19795
    doLast {
        val envVarRegex = "\\\\\\$\\\\\\\\\\{(\\w+)\\\\\\\\\\}".toRegex()
        val startScript = outputs.files.single().listFiles { file -> file.name == rootProject.name }!!.single()
        val contents = startScript.readLines().joinToString("\n") { line ->
            if (line.startsWith("DEFAULT_JVM_OPTS")) line.replace(envVarRegex, "\\$$1") else line
        }
        startScript.writeText(contents)
    }
}
ryandens commented 4 months ago

Today I learned about shadowDist! I always thought the point of the shadow plugin was to just ship a shadow jar. This seems quite reasonable and within the scope of this plugin to add support for, but I don't envision myself getting to it anytime soon