From d954e75cf595c8a0615217896c315a107d729f88 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Sun, 26 Feb 2023 17:58:21 -0800 Subject: [PATCH 1/5] Added a RunTask which includes the templates directory in the runtime classspath --- app/build.gradle.kts | 11 ++-- build-logic/build.gradle.kts | 7 +++ .../com/uwyn/rife2/gradle/Rife2Extension.java | 3 + .../com/uwyn/rife2/gradle/Rife2Plugin.java | 40 +++++++++---- .../java/com/uwyn/rife2/gradle/RunTask.java | 57 +++++++++++++++++++ war/build.gradle.kts | 5 +- 6 files changed, 102 insertions(+), 21 deletions(-) create mode 100644 build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 48c5f56..df9f28e 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -2,19 +2,15 @@ import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent plugins { - application id("com.uwyn.rife2") `maven-publish` } +version = 1.0 +group = "com.example" + base { archivesName.set("hello") - version = 1.0 - group = "com.example" -} - -application { - mainClass.set("hello.App") } java { @@ -30,6 +26,7 @@ repositories { } rife2 { + mainClass.set("hello.App") version.set("1.3.0") useAgent.set(true) } diff --git a/build-logic/build.gradle.kts b/build-logic/build.gradle.kts index b29e98f..b9ea647 100644 --- a/build-logic/build.gradle.kts +++ b/build-logic/build.gradle.kts @@ -10,6 +10,13 @@ dependencies { gradleApi() } +tasks { + withType { + options.isDeprecation = true + options.compilerArgs.add("-Xlint:unchecked") + } +} + gradlePlugin { plugins { create("rife2") { diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Extension.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Extension.java index 1fe9591..ebd97e0 100644 --- a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Extension.java +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Extension.java @@ -17,7 +17,10 @@ package com.uwyn.rife2.gradle; import org.gradle.api.provider.Property; +@SuppressWarnings("unused") public abstract class Rife2Extension { + public abstract Property getMainClass(); + public abstract Property getVersion(); public abstract Property getUseAgent(); diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java index 7572787..16a7c68 100644 --- a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java @@ -27,14 +27,10 @@ import org.gradle.api.component.AdhocComponentWithVariants; import org.gradle.api.component.ConfigurationVariantDetails; import org.gradle.api.file.DuplicatesStrategy; import org.gradle.api.plugins.BasePluginExtension; -import org.gradle.api.plugins.JavaApplication; import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPluginExtension; import org.gradle.api.plugins.PluginContainer; -import org.gradle.api.tasks.JavaExec; -import org.gradle.api.tasks.SourceSet; -import org.gradle.api.tasks.TaskContainer; -import org.gradle.api.tasks.TaskProvider; +import org.gradle.api.tasks.*; import org.gradle.api.tasks.bundling.Jar; import org.gradle.api.tasks.testing.Test; import org.gradle.process.CommandLineArgumentProvider; @@ -42,12 +38,15 @@ import org.gradle.process.CommandLineArgumentProvider; import java.util.Collections; import java.util.Locale; +@SuppressWarnings({"ALL", "unused"}) public class Rife2Plugin implements Plugin { public static final String DEFAULT_TEMPLATES_DIR = "src/main/templates"; public static final String DEFAULT_GENERATED_RIFE2_CLASSES_DIR = "generated/classes/rife2"; public static final String WEBAPP_SRCDIR = "src/main/webapp"; + public static final String RIFE2_GROUP = "rife2"; + @Override public void apply(Project project) { var plugins = project.getPlugins(); @@ -65,6 +64,7 @@ public class Rife2Plugin implements Plugin { createRife2DevelopmentOnlyConfiguration(project, configurations, dependencyHandler, precompileTemplates); exposePrecompiledTemplatesToTestTask(project, configurations, dependencyHandler, precompileTemplates); configureAgent(project, plugins, rife2Extension, rife2AgentClasspath); + registerRunTask(project, rife2Extension, rife2AgentClasspath); TaskProvider uberJarTask = registerUberJarTask(project, plugins, javaPluginExtension, rife2Extension, tasks, precompileTemplates); bundlePrecompiledTemplatesIntoJarFile(tasks, precompileTemplates); configureMavenPublishing(project, plugins, configurations, uberJarTask); @@ -81,11 +81,13 @@ public class Rife2Plugin implements Plugin { conf.attributes(attrs -> { for (Attribute attribute : runtimeAttributes.keySet()) { Object value = runtimeAttributes.getAttribute(attribute); - //noinspection unchecked - if (Bundling.class.equals(attribute.getType())) { - attrs.attribute(Bundling.BUNDLING_ATTRIBUTE, project.getObjects().named(Bundling.class, Bundling.SHADOWED)); - } else { - attrs.attribute((Attribute) attribute, value); + if (value != null) { + if (Bundling.class.equals(attribute.getType())) { + attrs.attribute(Bundling.BUNDLING_ATTRIBUTE, project.getObjects().named(Bundling.class, Bundling.SHADOWED)); + } else { + //noinspection unchecked + attrs.attribute((Attribute) attribute, value); + } } } }); @@ -156,8 +158,7 @@ public class Rife2Plugin implements Plugin { private static Rife2Extension createRife2Extension(Project project) { var rife2 = project.getExtensions().create("rife2", Rife2Extension.class); rife2.getUseAgent().convention(false); - rife2.getUberMainClass().convention(project.getExtensions().getByType(JavaApplication.class).getMainClass() - .map(mainClass -> mainClass + "Uber")); + rife2.getUberMainClass().set(rife2.getMainClass() + "Uber"); return rife2; } @@ -199,6 +200,8 @@ public class Rife2Plugin implements Plugin { private static TaskProvider registerPrecompileTemplateTask(Project project, Configuration rife2CompilerClasspath) { return project.getTasks().register("precompileTemplates", PrecompileTemplates.class, task -> { + task.setGroup(RIFE2_GROUP); + task.setDescription("Pre-compile the templates."); task.getVerbose().convention(true); task.getClasspath().from(rife2CompilerClasspath); task.getType().convention("html"); @@ -206,4 +209,17 @@ public class Rife2Plugin implements Plugin { task.getOutputDirectory().set(project.getLayout().getBuildDirectory().dir(DEFAULT_GENERATED_RIFE2_CLASSES_DIR)); }); } + + private static void registerRunTask(Project project, Rife2Extension rife2Extension, + Configuration rife2CompilerClasspath) { + project.getTasks().register("run", RunTask.class, task -> { + task.setGroup(RIFE2_GROUP); + task.setDescription("Runs this project as an application."); + task.getAgentClassPath().set(rife2CompilerClasspath.getAsPath()); + task.getClasspath().from(project.getExtensions().getByType(SourceSetContainer.class) + .getByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath()); + task.getMainClass().set(rife2Extension.getMainClass()); + task.getTemplatesDirectory().set(project.getLayout().getProjectDirectory().dir(DEFAULT_TEMPLATES_DIR)); + }); + } } diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java new file mode 100644 index 0000000..e4dcc9b --- /dev/null +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java @@ -0,0 +1,57 @@ +/* + * Copyright 2003-2021 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.uwyn.rife2.gradle; + +import org.gradle.api.DefaultTask; +import org.gradle.api.file.ConfigurableFileCollection; +import org.gradle.api.file.DirectoryProperty; +import org.gradle.api.provider.Property; +import org.gradle.api.tasks.*; +import org.gradle.process.ExecOperations; + +import javax.inject.Inject; +import java.util.ArrayList; +import java.util.List; + +@CacheableTask +public abstract class RunTask extends DefaultTask { + @Input + public abstract Property getAgentClassPath(); + + @Classpath + public abstract ConfigurableFileCollection getClasspath(); + + @Inject + protected abstract ExecOperations getExecOperations(); + + @Input + public abstract Property getMainClass(); + + @InputDirectory + @PathSensitive(PathSensitivity.RELATIVE) + public abstract DirectoryProperty getTemplatesDirectory(); + + @TaskAction + public void run() { + getExecOperations().javaexec(run -> { + run.setClasspath(getProject().getObjects().fileCollection().from(getTemplatesDirectory()).plus(getClasspath())); + run.getMainClass().set(getMainClass()); + List args = new ArrayList<>(); + args.add("-javaagent:" + getAgentClassPath().get()); + run.args(args); + }); + } +} diff --git a/war/build.gradle.kts b/war/build.gradle.kts index 206f003..477784d 100644 --- a/war/build.gradle.kts +++ b/war/build.gradle.kts @@ -2,9 +2,10 @@ plugins { war } +version = 1.0 + base { archivesName.set("hello") - version = 1.0 } repositories { @@ -20,4 +21,4 @@ tasks.war { webAppDirectory.set(file("../app/src/main/webapp")) webXml = file("src/web.xml") rootSpec.exclude("**/jetty*.jar", "**/slf4j*.jar", "**/rife2*-agent.jar") -} \ No newline at end of file +} From 269971663b0f19766a3ac1b61019075b93537ce3 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Mon, 27 Feb 2023 18:48:12 -0800 Subject: [PATCH 2/5] Minor cleanup --- .../src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java | 8 ++++---- .../src/main/java/com/uwyn/rife2/gradle/RunTask.java | 7 ++----- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java index 16a7c68..a87ed5f 100644 --- a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java @@ -43,10 +43,10 @@ public class Rife2Plugin implements Plugin { public static final String DEFAULT_TEMPLATES_DIR = "src/main/templates"; public static final String DEFAULT_GENERATED_RIFE2_CLASSES_DIR = "generated/classes/rife2"; - public static final String WEBAPP_SRCDIR = "src/main/webapp"; - public static final String RIFE2_GROUP = "rife2"; + public static final String WEBAPP_SRCDIR = "src/main/webapp"; + @Override public void apply(Project project) { var plugins = project.getPlugins(); @@ -201,7 +201,7 @@ public class Rife2Plugin implements Plugin { Configuration rife2CompilerClasspath) { return project.getTasks().register("precompileTemplates", PrecompileTemplates.class, task -> { task.setGroup(RIFE2_GROUP); - task.setDescription("Pre-compile the templates."); + task.setDescription("Pre-compiles the templates."); task.getVerbose().convention(true); task.getClasspath().from(rife2CompilerClasspath); task.getType().convention("html"); @@ -214,7 +214,7 @@ public class Rife2Plugin implements Plugin { Configuration rife2CompilerClasspath) { project.getTasks().register("run", RunTask.class, task -> { task.setGroup(RIFE2_GROUP); - task.setDescription("Runs this project as an application."); + task.setDescription("Runs this project as a web application."); task.getAgentClassPath().set(rife2CompilerClasspath.getAsPath()); task.getClasspath().from(project.getExtensions().getByType(SourceSetContainer.class) .getByName(SourceSet.MAIN_SOURCE_SET_NAME).getRuntimeClasspath()); diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java index e4dcc9b..c107544 100644 --- a/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java @@ -23,7 +23,6 @@ import org.gradle.api.tasks.*; import org.gradle.process.ExecOperations; import javax.inject.Inject; -import java.util.ArrayList; import java.util.List; @CacheableTask @@ -49,9 +48,7 @@ public abstract class RunTask extends DefaultTask { getExecOperations().javaexec(run -> { run.setClasspath(getProject().getObjects().fileCollection().from(getTemplatesDirectory()).plus(getClasspath())); run.getMainClass().set(getMainClass()); - List args = new ArrayList<>(); - args.add("-javaagent:" + getAgentClassPath().get()); - run.args(args); + run.args(List.of("-javaagent:" + getAgentClassPath().get())); }); } -} +} \ No newline at end of file From c33235a1accacffc37b00f6b5c4745b55ce040cc Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Mon, 27 Feb 2023 19:14:36 -0800 Subject: [PATCH 3/5] Added description and group for the uberJar task. --- .../src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java index a87ed5f..17bfd18 100644 --- a/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/Rife2Plugin.java @@ -40,11 +40,9 @@ import java.util.Locale; @SuppressWarnings({"ALL", "unused"}) public class Rife2Plugin implements Plugin { - public static final String DEFAULT_TEMPLATES_DIR = "src/main/templates"; public static final String DEFAULT_GENERATED_RIFE2_CLASSES_DIR = "generated/classes/rife2"; public static final String RIFE2_GROUP = "rife2"; - public static final String WEBAPP_SRCDIR = "src/main/webapp"; @Override @@ -127,6 +125,8 @@ public class Rife2Plugin implements Plugin { TaskContainer tasks, TaskProvider precompileTemplatesTask) { return tasks.register("uberJar", Jar.class, jar -> { + jar.setGroup(RIFE2_GROUP); + jar.setDescription("Assembles the web application and all dependencies into a single jar archive."); var base = project.getExtensions().getByType(BasePluginExtension.class); jar.getArchiveBaseName().convention(project.provider(() -> base.getArchivesName().get() + "-uber")); jar.setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE); From 57a604c5995de978e5f1e489bbc127d5a3bb11a7 Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Tue, 28 Feb 2023 23:46:10 -0800 Subject: [PATCH 4/5] Minor cleanup --- build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java index c107544..07be158 100644 --- a/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java @@ -47,7 +47,7 @@ public abstract class RunTask extends DefaultTask { public void run() { getExecOperations().javaexec(run -> { run.setClasspath(getProject().getObjects().fileCollection().from(getTemplatesDirectory()).plus(getClasspath())); - run.getMainClass().set(getMainClass()); + run.getMainClass().set(getMainClass().get()); run.args(List.of("-javaagent:" + getAgentClassPath().get())); }); } From f8b3078ba11682402e2074de3e682556be602d4c Mon Sep 17 00:00:00 2001 From: "Erik C. Thauvin" Date: Thu, 2 Mar 2023 05:28:18 -0800 Subject: [PATCH 5/5] Reverted cleanup, it wasn't necessary. --- build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java index 07be158..c107544 100644 --- a/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java +++ b/build-logic/src/main/java/com/uwyn/rife2/gradle/RunTask.java @@ -47,7 +47,7 @@ public abstract class RunTask extends DefaultTask { public void run() { getExecOperations().javaexec(run -> { run.setClasspath(getProject().getObjects().fileCollection().from(getTemplatesDirectory()).plus(getClasspath())); - run.getMainClass().set(getMainClass().get()); + run.getMainClass().set(getMainClass()); run.args(List.of("-javaagent:" + getAgentClassPath().get())); }); }