diff --git a/rewrite-maven/src/main/java/org/openrewrite/maven/cleanup/ExplicitPluginGroupId.java b/rewrite-maven/src/main/java/org/openrewrite/maven/cleanup/ExplicitPluginGroupId.java
new file mode 100755
index 00000000000..e9bb432c38f
--- /dev/null
+++ b/rewrite-maven/src/main/java/org/openrewrite/maven/cleanup/ExplicitPluginGroupId.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2023 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
+ *
+ * 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 org.openrewrite.maven.cleanup;
+
+import lombok.EqualsAndHashCode;
+import lombok.Value;
+import org.openrewrite.ExecutionContext;
+import org.openrewrite.Recipe;
+import org.openrewrite.TreeVisitor;
+import org.openrewrite.maven.MavenTagInsertionComparator;
+import org.openrewrite.maven.MavenVisitor;
+import org.openrewrite.xml.AddToTagVisitor;
+import org.openrewrite.xml.tree.Xml;
+
+@Value
+@EqualsAndHashCode(callSuper = true)
+public class ExplicitPluginGroupId extends Recipe {
+ @Override
+ public String getDisplayName() {
+ return "Add explicit `groupId` to Maven plugins";
+ }
+
+ @Override
+ public String getDescription() {
+ return "Add the default `org.apache.maven.plugins` to plugins for clarity.";
+ }
+
+ @Override
+ public TreeVisitor, ExecutionContext> getVisitor() {
+ return new MavenVisitor() {
+ @Override
+ public Xml visitTag(Xml.Tag tag, ExecutionContext ctx) {
+ Xml.Tag t = (Xml.Tag) super.visitTag(tag, ctx);
+ if (isPluginTag() && !t.getChild("groupId").isPresent()) {
+ Xml.Tag groupIdTag = Xml.Tag.build("org.apache.maven.plugins");
+ t = (Xml.Tag) new AddToTagVisitor<>(t, groupIdTag, new MavenTagInsertionComparator(t.getChildren()))
+ .visitNonNull(t, ctx, getCursor().getParentOrThrow());
+ maybeUpdateModel();
+ }
+ return t;
+ }
+ };
+ }
+}
diff --git a/rewrite-maven/src/main/resources/META-INF/rewrite/maven.yml b/rewrite-maven/src/main/resources/META-INF/rewrite/maven.yml
index 1a8a106553b..351033dad40 100644
--- a/rewrite-maven/src/main/resources/META-INF/rewrite/maven.yml
+++ b/rewrite-maven/src/main/resources/META-INF/rewrite/maven.yml
@@ -19,6 +19,7 @@ name: org.openrewrite.maven.BestPractices
displayName: Apache Maven best practices
description: Applies best practices to Maven POMs.
recipeList:
+ - org.openrewrite.maven.cleanup.ExplicitPluginGroupId
- org.openrewrite.maven.cleanup.PrefixlessExpressions
---
diff --git a/rewrite-maven/src/test/java/org/openrewrite/maven/cleanup/ExplicitPluginGroupIdTest.java b/rewrite-maven/src/test/java/org/openrewrite/maven/cleanup/ExplicitPluginGroupIdTest.java
new file mode 100644
index 00000000000..a62c4b90d4d
--- /dev/null
+++ b/rewrite-maven/src/test/java/org/openrewrite/maven/cleanup/ExplicitPluginGroupIdTest.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2023 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
+ *