From 88d68c9c4045290aeb195abcf5a27796efb1663e Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Tue, 31 Oct 2023 22:23:32 -0700 Subject: [PATCH 01/15] :white_check_mark: add windows to CI --- .github/workflows/gradle.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index b233935..18fe5d9 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -15,7 +15,10 @@ jobs: - uses: gradle/actions/wrapper-validation@v5 build: name: "Javaagent Gradle Plugin Validation" - runs-on: ubuntu-latest + strategy: + matrix: + platform: [ubuntu-latest, windows-latest] + runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v6.0.1 - uses: actions/setup-java@v5.1.0 From f654c49ab1207c15a8cc2536f827f13b3860cd03 Mon Sep 17 00:00:00 2001 From: Punya Biswal Date: Tue, 18 Jul 2023 23:55:12 -0400 Subject: [PATCH 02/15] Use Unix line endings for all files See https://github.com/diffplug/spotless/issues/39 for details --- .gitattributes | 1 + 1 file changed, 1 insertion(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..fcadb2c --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text eol=lf From 77fa62fc4577cdc85eb5f114939323fd19a61cdf Mon Sep 17 00:00:00 2001 From: Punya Biswal Date: Tue, 18 Jul 2023 22:39:57 -0400 Subject: [PATCH 03/15] Add support for Windows --- gradlew.bat | 186 +++++++++--------- .../JavaagentApplicationDistributionPlugin.kt | 12 +- .../JavaagentAwareStartScriptGenerator.kt | 17 +- .../kotlin/com/ryandens/javaagent/Platform.kt | 16 ++ 4 files changed, 122 insertions(+), 109 deletions(-) create mode 100644 plugin/src/main/kotlin/com/ryandens/javaagent/Platform.kt diff --git a/gradlew.bat b/gradlew.bat index e509b2d..c4bdd3a 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,93 +1,93 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentApplicationDistributionPlugin.kt b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentApplicationDistributionPlugin.kt index 3645e5f..3caf7c1 100644 --- a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentApplicationDistributionPlugin.kt +++ b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentApplicationDistributionPlugin.kt @@ -6,7 +6,6 @@ import org.gradle.api.Project import org.gradle.api.artifacts.Configuration import org.gradle.api.distribution.DistributionContainer import org.gradle.api.distribution.plugins.DistributionPlugin -import org.gradle.api.internal.plugins.WindowsStartScriptGenerator import org.gradle.api.plugins.ApplicationPlugin import org.gradle.api.tasks.application.CreateStartScripts @@ -52,14 +51,9 @@ class JavaagentApplicationDistributionPlugin : .plus(it.defaultJvmOpts ?: listOf()) it.inputs.files(javaagentConfiguration) // custom start script generator that replaces the placeholder - it.unixStartScriptGenerator = - JavaagentAwareStartScriptGenerator( - javaagentConfiguration.map { configuration -> - configuration.files - }, - ) - // TODO build support for windows - it.windowsStartScriptGenerator = WindowsStartScriptGenerator() + val agentFiles = javaagentConfiguration.map { configuration -> configuration.files } + it.unixStartScriptGenerator = JavaagentAwareStartScriptGenerator(agentFiles, Platform.UNIX) + it.windowsStartScriptGenerator = JavaagentAwareStartScriptGenerator(agentFiles, Platform.WINDOWS) } } } diff --git a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentAwareStartScriptGenerator.kt b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentAwareStartScriptGenerator.kt index 247a0fa..1225a83 100644 --- a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentAwareStartScriptGenerator.kt +++ b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentAwareStartScriptGenerator.kt @@ -3,7 +3,6 @@ package com.ryandens.javaagent import org.gradle.api.Transformer import org.gradle.api.internal.plugins.DefaultTemplateBasedStartScriptGenerator import org.gradle.api.internal.plugins.StartScriptTemplateBindingFactory -import org.gradle.api.internal.plugins.UnixStartScriptGenerator import org.gradle.api.provider.Provider import org.gradle.jvm.application.scripts.JavaAppStartScriptGenerationDetails import org.gradle.jvm.application.scripts.ScriptGenerator @@ -12,18 +11,19 @@ import java.io.Writer class JavaagentAwareStartScriptGenerator( private val javaagentConfiguration: Provider>, + private val platform: Platform, private val inner: ScriptGenerator = DefaultTemplateBasedStartScriptGenerator( - "\n", - FakeTransformer(StartScriptTemplateBindingFactory.unix()), - UnixStartScriptGenerator().template, + platform.lineSeparator, + FakeTransformer(platform.templateBindingFactory), + platform.template, ), ) : ScriptGenerator { override fun generateScript( details: JavaAppStartScriptGenerationDetails, destination: Writer, ) { - inner.generateScript(details, Fake(destination, javaagentConfiguration)) + inner.generateScript(details, Fake(destination, javaagentConfiguration, platform.pathSeparator)) } private class FakeTransformer( @@ -46,7 +46,8 @@ class JavaagentAwareStartScriptGenerator( private class Fake( private val inner: Writer, private val javaagentFiles: Provider>, - ) : Writer() { + private val pathSeparator: String, + ) : Writer() { override fun close() { inner.close() } @@ -76,7 +77,9 @@ class JavaagentAwareStartScriptGenerator( } else { str.replace( "-javaagent:COM_RYANDENS_JAVAAGENTS_PLACEHOLDER.jar", - javaagentFiles.get().joinToString(" ") { jar -> "-javaagent:\$APP_HOME/agent-libs/${jar.name}" }, + javaagentFiles.get().joinToString( + " ", + ) { jar -> "-javaagent:\$APP_HOME${pathSeparator}agent-libs${pathSeparator}${jar.name}" }, ) } super.write(replace) diff --git a/plugin/src/main/kotlin/com/ryandens/javaagent/Platform.kt b/plugin/src/main/kotlin/com/ryandens/javaagent/Platform.kt new file mode 100644 index 0000000..3bd7983 --- /dev/null +++ b/plugin/src/main/kotlin/com/ryandens/javaagent/Platform.kt @@ -0,0 +1,16 @@ +package com.ryandens.javaagent + +import org.gradle.api.internal.plugins.StartScriptTemplateBindingFactory +import org.gradle.api.internal.plugins.UnixStartScriptGenerator +import org.gradle.api.internal.plugins.WindowsStartScriptGenerator +import org.gradle.api.resources.TextResource + +enum class Platform( + val lineSeparator: String, + val pathSeparator: String, + val templateBindingFactory: StartScriptTemplateBindingFactory, + val template: TextResource, +) { + UNIX("\n", "/", StartScriptTemplateBindingFactory.unix(), UnixStartScriptGenerator().template), + WINDOWS("\r\n", "\\", StartScriptTemplateBindingFactory.windows(), WindowsStartScriptGenerator().template), +} From 62aa5c9ada133294511d3c4c3889c09b0d2cd5a3 Mon Sep 17 00:00:00 2001 From: Punya Biswal Date: Wed, 19 Jul 2023 00:39:33 -0400 Subject: [PATCH 04/15] Use portable path separators --- .../com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt index 45dcb45..38288c2 100644 --- a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt +++ b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt @@ -5,6 +5,7 @@ import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner import org.gradle.testkit.runner.TaskOutcome import java.io.File +import java.nio.file.Paths import kotlin.test.AfterTest import kotlin.test.BeforeTest import kotlin.test.Test @@ -191,10 +192,11 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" } private fun createJavaagentProject(dependencies: String) { - File("src/functionalTest/resources/hello-world-project/").copyRecursively(helloWorldDir) + val helloWorldDir = File(functionalTestDir, "hello-world") + Paths.get("src", "functionalTest", "resources", "hello-world-project").toFile().copyRecursively(helloWorldDir) val simpleAgentTestDir = File(functionalTestDir, "simple-agent") val simpleAgentBuildScript = simpleAgentTestDir.resolve("build.gradle.kts") - File("../simple-agent/").copyRecursively(simpleAgentTestDir) + Paths.get("..", "simple-agent").toFile().copyRecursively(simpleAgentTestDir) simpleAgentBuildScript.writeText( simpleAgentBuildScript.readText().replace( "id(\"com.ryandens.java-conventions\")\n", From 801056d199414130c5016c7fc60a9772aa45ebe2 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Tue, 31 Oct 2023 22:51:50 -0700 Subject: [PATCH 05/15] :bug: dont use canonical path --- .../com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt index 38288c2..c6f5db8 100644 --- a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt +++ b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt @@ -234,10 +234,10 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" } task execStartScript(type: Exec) { - inputs.files(fileTree('${helloWorldDir.canonicalPath}/build/install/') { + inputs.files(fileTree('${helloWorldDir.path}/build/install/') { builtBy tasks.named('installDist') }) - workingDir '${helloWorldDir.canonicalPath}/build/install/hello-world/bin/' + workingDir '${helloWorldDir.path}/build/install/hello-world/bin/' commandLine './hello-world' environment JAVA_HOME: "${Jvm.current().getJavaHome()}" } From 47d85b10efc6c5c12a8e0a9168979ffb2bb8a68e Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Tue, 31 Oct 2023 22:56:50 -0700 Subject: [PATCH 06/15] Revert ":bug: dont use canonical path" This revrts commit ee3e96106b2dc62d0aa9eaca7a8712975592b74e. --- .../com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt index c6f5db8..38288c2 100644 --- a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt +++ b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt @@ -234,10 +234,10 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" } task execStartScript(type: Exec) { - inputs.files(fileTree('${helloWorldDir.path}/build/install/') { + inputs.files(fileTree('${helloWorldDir.canonicalPath}/build/install/') { builtBy tasks.named('installDist') }) - workingDir '${helloWorldDir.path}/build/install/hello-world/bin/' + workingDir '${helloWorldDir.canonicalPath}/build/install/hello-world/bin/' commandLine './hello-world' environment JAVA_HOME: "${Jvm.current().getJavaHome()}" } From 55270a7c3acfcbf1e3d8a9a4027241b82926599f Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Tue, 31 Oct 2023 23:03:16 -0700 Subject: [PATCH 07/15] :bug: get rid of hardcoded file separators in tests --- .../javaagent/JavaagentPluginFunctionalTest.kt | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt index 38288c2..b184aea 100644 --- a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt +++ b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt @@ -26,7 +26,7 @@ class JavaagentPluginFunctionalTest { @BeforeTest fun beforeEach() { - functionalTestDir = File("build/functionalTest") + functionalTestDir = File("build", "functionalTest") functionalTestDir.mkdirs() helloWorldDir = File(functionalTestDir, "hello-world") } @@ -234,11 +234,10 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" } task execStartScript(type: Exec) { - inputs.files(fileTree('${helloWorldDir.canonicalPath}/build/install/') { - builtBy tasks.named('installDist') - }) - workingDir '${helloWorldDir.canonicalPath}/build/install/hello-world/bin/' - commandLine './hello-world' + dependsOn('installDist') + inputs.files(layout.buildDirectory.dir('install')) + workingDir '${helloWorldDir.canonicalPath + File.separator}build${File.separator}install${File.separator}hello-world${File.separator}bin${File.separator}' + commandLine '.${File.separator}hello-world' environment JAVA_HOME: "${Jvm.current().getJavaHome()}" } From 55ed4ca11912f1e490fc376dbfe98b890498a1bf Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Tue, 31 Oct 2023 23:06:25 -0700 Subject: [PATCH 08/15] :bug: more path separator cleanup --- .../javaagent/JavaagentPluginFunctionalTest.kt | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt index b184aea..d7ca138 100644 --- a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt +++ b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt @@ -121,14 +121,14 @@ class JavaagentPluginFunctionalTest { val result = runBuild(listOf("--configuration-cache", "build", "installDist", "execStartScript")) // verify the distribution was created properly - val applicationDistribution = File(functionalTestDir, "hello-world/build/distributions/hello-world.tar") + val applicationDistribution = File(functionalTestDir, "hello-world${File.separator}build${File.separator}distributions${File.separator}hello-world.tar") assertTrue(applicationDistribution.exists()) // verify the expected text was injected into the start script val expectedDefaultJavaOpts = """ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/agent-libs/simple-agent.jar -Xmx256m" """ - val applicationDistributionScript = File(functionalTestDir, "hello-world/build/scripts/hello-world") + val applicationDistributionScript = File(functionalTestDir, "hello-world${File.separator}build${File.separator}scripts${File.separator}hello-world") assertTrue(applicationDistributionScript.readText().contains(expectedDefaultJavaOpts)) /* @@ -141,7 +141,7 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" */ // verify the agent was added to the /lib/ dir of the distribution - assertTrue(File(functionalTestDir, "hello-world/build/install/hello-world/agent-libs/simple-agent.jar").exists()) + assertTrue(File(functionalTestDir, "hello-world${File.separator}build${File.separator}install${File.separator}hello-world${File.separator}agent-libs${File.separator}simple-agent.jar").exists()) // Verify the result assertTrue(result.output.contains("Hello World!")) @@ -181,13 +181,13 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" val result = runBuild(listOf("build", "installDist", "execStartScript")) // verify the distribution was created properly - val applicationDistribution = File(functionalTestDir, "hello-world/build/distributions/hello-world.tar") + val applicationDistribution = File(functionalTestDir, "hello-world${File.separator}build${File.separator}distributions${File.separator}hello-world.tar") assertTrue(applicationDistribution.exists()) - val applicationDistributionScript = File(functionalTestDir, "hello-world/build/scripts/hello-world") + val applicationDistributionScript = File(functionalTestDir, "hello-world${File.separator}build${File.separator}scripts${File.separator}hello-world") assertTrue(applicationDistributionScript.readText().contains("""DEFAULT_JVM_OPTS="-Xmx256m""")) - assertFalse(File(functionalTestDir, "hello-world/build/install/hello-world/agent-libs/").exists()) + assertFalse(File(functionalTestDir, "hello-world${File.separator}build${File.separator}install${File.separator}hello-world${File.separator}agent-libs/").exists()) assertTrue(result.output.contains("Hello World!")) } From 6cec91612c849e522b29ec8e9a0f988b91957655 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Tue, 31 Oct 2023 23:13:20 -0700 Subject: [PATCH 09/15] :art: --- .../JavaagentPluginFunctionalTest.kt | 26 ++++++++++++++----- 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt index d7ca138..06f4ea7 100644 --- a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt +++ b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt @@ -121,14 +121,16 @@ class JavaagentPluginFunctionalTest { val result = runBuild(listOf("--configuration-cache", "build", "installDist", "execStartScript")) // verify the distribution was created properly - val applicationDistribution = File(functionalTestDir, "hello-world${File.separator}build${File.separator}distributions${File.separator}hello-world.tar") + val applicationDistribution = + File(functionalTestDir, "hello-world${File.separator}build${File.separator}distributions${File.separator}hello-world.tar") assertTrue(applicationDistribution.exists()) // verify the expected text was injected into the start script val expectedDefaultJavaOpts = """ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/agent-libs/simple-agent.jar -Xmx256m" """ - val applicationDistributionScript = File(functionalTestDir, "hello-world${File.separator}build${File.separator}scripts${File.separator}hello-world") + val applicationDistributionScript = + File(functionalTestDir, "hello-world${File.separator}build${File.separator}scripts${File.separator}hello-world") assertTrue(applicationDistributionScript.readText().contains(expectedDefaultJavaOpts)) /* @@ -141,7 +143,12 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" */ // verify the agent was added to the /lib/ dir of the distribution - assertTrue(File(functionalTestDir, "hello-world${File.separator}build${File.separator}install${File.separator}hello-world${File.separator}agent-libs${File.separator}simple-agent.jar").exists()) + assertTrue( + File( + functionalTestDir, + "hello-world/build/install/hello-world/agent-libs/simple-agent.jar".replace("/", File.separator), + ).exists(), + ) // Verify the result assertTrue(result.output.contains("Hello World!")) @@ -181,13 +188,20 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" val result = runBuild(listOf("build", "installDist", "execStartScript")) // verify the distribution was created properly - val applicationDistribution = File(functionalTestDir, "hello-world${File.separator}build${File.separator}distributions${File.separator}hello-world.tar") + val applicationDistribution = + File(functionalTestDir, "hello-world${File.separator}build${File.separator}distributions${File.separator}hello-world.tar") assertTrue(applicationDistribution.exists()) - val applicationDistributionScript = File(functionalTestDir, "hello-world${File.separator}build${File.separator}scripts${File.separator}hello-world") + val applicationDistributionScript = + File(functionalTestDir, "hello-world${File.separator}build${File.separator}scripts${File.separator}hello-world") assertTrue(applicationDistributionScript.readText().contains("""DEFAULT_JVM_OPTS="-Xmx256m""")) - assertFalse(File(functionalTestDir, "hello-world${File.separator}build${File.separator}install${File.separator}hello-world${File.separator}agent-libs/").exists()) + assertFalse( + File( + functionalTestDir, + "hello-world${File.separator}build${File.separator}install${File.separator}hello-world${File.separator}agent-libs/", + ).exists(), + ) assertTrue(result.output.contains("Hello World!")) } From 4d45ccdd96099f71e79aec3c82c9e6089d883ce2 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Tue, 31 Oct 2023 23:22:47 -0700 Subject: [PATCH 10/15] :bug: use layout for specifying dir where possible --- .../com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt index 06f4ea7..f78be5f 100644 --- a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt +++ b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt @@ -250,7 +250,7 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" task execStartScript(type: Exec) { dependsOn('installDist') inputs.files(layout.buildDirectory.dir('install')) - workingDir '${helloWorldDir.canonicalPath + File.separator}build${File.separator}install${File.separator}hello-world${File.separator}bin${File.separator}' + workingDir(layout.buildDirectory.dir('install').map { it.dir('hello-world').dir('bin') }) commandLine '.${File.separator}hello-world' environment JAVA_HOME: "${Jvm.current().getJavaHome()}" } From dd241055d13d55aed6b7833957fe06eb64c6aa08 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Wed, 17 Dec 2025 19:36:12 -0800 Subject: [PATCH 11/15] :fire: remove gitattributes --- .gitattributes | 1 - gradlew.bat | 186 ++++++++++++++++++++++++------------------------- 2 files changed, 93 insertions(+), 94 deletions(-) delete mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes deleted file mode 100644 index fcadb2c..0000000 --- a/.gitattributes +++ /dev/null @@ -1 +0,0 @@ -* text eol=lf diff --git a/gradlew.bat b/gradlew.bat index c4bdd3a..e509b2d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,93 +1,93 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem -@rem SPDX-License-Identifier: Apache-2.0 -@rem - -@if "%DEBUG%"=="" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%"=="" set DIRNAME=. -@rem This is normally unused -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Resolve any "." and ".." in APP_HOME to make it shorter. -for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if %ERRORLEVEL% equ 0 goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto execute - -echo. 1>&2 -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 -echo. 1>&2 -echo Please set the JAVA_HOME variable in your environment to match the 1>&2 -echo location of your Java installation. 1>&2 - -goto fail - -:execute -@rem Setup the command line - - - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* - -:end -@rem End local scope for the variables with windows NT shell -if %ERRORLEVEL% equ 0 goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -set EXIT_CODE=%ERRORLEVEL% -if %EXIT_CODE% equ 0 set EXIT_CODE=1 -if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% -exit /b %EXIT_CODE% - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem +@rem SPDX-License-Identifier: Apache-2.0 +@rem + +@if "%DEBUG%"=="" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%"=="" set DIRNAME=. +@rem This is normally unused +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if %ERRORLEVEL% equ 0 goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto execute + +echo. 1>&2 +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 1>&2 +echo. 1>&2 +echo Please set the JAVA_HOME variable in your environment to match the 1>&2 +echo location of your Java installation. 1>&2 + +goto fail + +:execute +@rem Setup the command line + + + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* + +:end +@rem End local scope for the variables with windows NT shell +if %ERRORLEVEL% equ 0 goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega From 1a731c6127efaaec3b41bd1d5c46028a029f7836 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Wed, 17 Dec 2025 19:42:13 -0800 Subject: [PATCH 12/15] :art: --- .../ryandens/javaagent/JavaagentAwareStartScriptGenerator.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentAwareStartScriptGenerator.kt b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentAwareStartScriptGenerator.kt index 1225a83..5658eae 100644 --- a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentAwareStartScriptGenerator.kt +++ b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentAwareStartScriptGenerator.kt @@ -47,7 +47,7 @@ class JavaagentAwareStartScriptGenerator( private val inner: Writer, private val javaagentFiles: Provider>, private val pathSeparator: String, - ) : Writer() { + ) : Writer() { override fun close() { inner.close() } From 72170d5fc07ecc7c5981b7de9ee8b8c11c7f6863 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Wed, 17 Dec 2025 19:51:54 -0800 Subject: [PATCH 13/15] :rotating_light: --- .../javaagent/JavaagentApplicationDistributionPlugin.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentApplicationDistributionPlugin.kt b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentApplicationDistributionPlugin.kt index 3caf7c1..f7174a3 100644 --- a/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentApplicationDistributionPlugin.kt +++ b/plugin/src/main/kotlin/com/ryandens/javaagent/JavaagentApplicationDistributionPlugin.kt @@ -7,7 +7,9 @@ import org.gradle.api.artifacts.Configuration import org.gradle.api.distribution.DistributionContainer import org.gradle.api.distribution.plugins.DistributionPlugin import org.gradle.api.plugins.ApplicationPlugin +import org.gradle.api.provider.Provider import org.gradle.api.tasks.application.CreateStartScripts +import java.io.File /** * Gradle plugin for configuration of the [DistributionPlugin.MAIN_DISTRIBUTION_NAME] after it has been configured by @@ -51,7 +53,7 @@ class JavaagentApplicationDistributionPlugin : .plus(it.defaultJvmOpts ?: listOf()) it.inputs.files(javaagentConfiguration) // custom start script generator that replaces the placeholder - val agentFiles = javaagentConfiguration.map { configuration -> configuration.files } + val agentFiles: Provider> = javaagentConfiguration.map { configuration -> configuration.files } it.unixStartScriptGenerator = JavaagentAwareStartScriptGenerator(agentFiles, Platform.UNIX) it.windowsStartScriptGenerator = JavaagentAwareStartScriptGenerator(agentFiles, Platform.WINDOWS) } From cf7c82963c5a5bac3a0ebe84a777406e13d9248a Mon Sep 17 00:00:00 2001 From: "John Y. Pazekha" <35344069+neboskreb@users.noreply.github.com> Date: Mon, 22 Dec 2025 17:53:22 +0100 Subject: [PATCH 14/15] Small fixes to the Windows branch (#298) Just a couple of minor fixes to add to the branch before its PR can proceed further --- plugin/build.gradle.kts | 1 + .../ryandens/javaagent/JavaagentPluginFunctionalTest.kt | 9 ++++++--- .../ryandens/javaagent/JavaForkOptionsConfigurer.java | 8 +++++++- 3 files changed, 14 insertions(+), 4 deletions(-) diff --git a/plugin/build.gradle.kts b/plugin/build.gradle.kts index f163834..116d12b 100644 --- a/plugin/build.gradle.kts +++ b/plugin/build.gradle.kts @@ -29,6 +29,7 @@ dependencies { testImplementation("org.jetbrains.kotlin:kotlin-test") testImplementation("org.jetbrains.kotlin:kotlin-test-junit") testImplementation("org.apache.commons:commons-compress:1.28.0") + testImplementation("org.apache.commons:commons-text:1.15.0") } gradlePlugin { diff --git a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt index f78be5f..f8b9825 100644 --- a/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt +++ b/plugin/src/functionalTest/kotlin/com/ryandens/javaagent/JavaagentPluginFunctionalTest.kt @@ -1,5 +1,6 @@ package com.ryandens.javaagent +import org.apache.commons.text.StringEscapeUtils import org.gradle.internal.jvm.Jvm import org.gradle.testkit.runner.BuildResult import org.gradle.testkit.runner.GradleRunner @@ -213,7 +214,7 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" Paths.get("..", "simple-agent").toFile().copyRecursively(simpleAgentTestDir) simpleAgentBuildScript.writeText( simpleAgentBuildScript.readText().replace( - "id(\"com.ryandens.java-conventions\")\n", + "id(\"com.ryandens.java-conventions\")", "", ), ) @@ -226,6 +227,8 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" """, ) + val commandLine = StringEscapeUtils.escapeJava(""".${File.separator}hello-world""") + val javaHome = StringEscapeUtils.escapeJava(Jvm.current().getJavaHome().toString()) helloWorldDir.resolve("build.gradle").writeText( """ plugins { @@ -251,8 +254,8 @@ DEFAULT_JVM_OPTS="-javaagent:${"$"}APP_HOME/lib/simple-agent.jar -Xmx256m" dependsOn('installDist') inputs.files(layout.buildDirectory.dir('install')) workingDir(layout.buildDirectory.dir('install').map { it.dir('hello-world').dir('bin') }) - commandLine '.${File.separator}hello-world' - environment JAVA_HOME: "${Jvm.current().getJavaHome()}" + commandLine '$commandLine' + environment JAVA_HOME: "$javaHome" } test { diff --git a/plugin/src/main/java/com/ryandens/javaagent/JavaForkOptionsConfigurer.java b/plugin/src/main/java/com/ryandens/javaagent/JavaForkOptionsConfigurer.java index 5912925..d197971 100644 --- a/plugin/src/main/java/com/ryandens/javaagent/JavaForkOptionsConfigurer.java +++ b/plugin/src/main/java/com/ryandens/javaagent/JavaForkOptionsConfigurer.java @@ -8,6 +8,7 @@ import java.util.Set; import java.util.stream.Collectors; import org.gradle.api.provider.Provider; +import org.gradle.internal.os.OperatingSystem; import org.gradle.process.CommandLineArgumentProvider; import org.gradle.process.JavaForkOptions; @@ -42,7 +43,12 @@ public Iterable asArguments() { .map( file -> { try { - return "-javaagent:" + file.getCanonicalPath(); + String path = file.getCanonicalPath(); + if (OperatingSystem.current().isWindows()) { + // Don't let the spaces in the Windows path break the command line + path = '"' + path + '"'; + } + return "-javaagent:" + path; } catch (IOException e) { throw new UncheckedIOException(e); } From 38951ecc64ac40824b8435d9a4c55a045d1af8d7 Mon Sep 17 00:00:00 2001 From: Ryan Dens Date: Mon, 22 Dec 2025 08:54:30 -0800 Subject: [PATCH 15/15] :art: fix formatting violations --- .../javaagent/JavaForkOptionsConfigurer.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/plugin/src/main/java/com/ryandens/javaagent/JavaForkOptionsConfigurer.java b/plugin/src/main/java/com/ryandens/javaagent/JavaForkOptionsConfigurer.java index d197971..fcc5386 100644 --- a/plugin/src/main/java/com/ryandens/javaagent/JavaForkOptionsConfigurer.java +++ b/plugin/src/main/java/com/ryandens/javaagent/JavaForkOptionsConfigurer.java @@ -43,12 +43,12 @@ public Iterable asArguments() { .map( file -> { try { - String path = file.getCanonicalPath(); - if (OperatingSystem.current().isWindows()) { - // Don't let the spaces in the Windows path break the command line - path = '"' + path + '"'; - } - return "-javaagent:" + path; + String path = file.getCanonicalPath(); + if (OperatingSystem.current().isWindows()) { + // Don't let the spaces in the Windows path break the command line + path = '"' + path + '"'; + } + return "-javaagent:" + path; } catch (IOException e) { throw new UncheckedIOException(e); }