From a039d3e8abce4647a9edc94665b4fb2f5f93f2bd Mon Sep 17 00:00:00 2001 From: Elliotte Rusty Harold Date: Tue, 28 Jul 2026 17:31:43 +0000 Subject: [PATCH 1/3] MEAR-305: Fix skipClassPathModification setting Class-Path empty When skipClassPathModification is true, the plugin should leave module manifests completely untouched. Previously, existing Class-Path entries were still updated/removed and the modified manifest was written back, potentially setting Class-Path to empty. Now all Class-Path modification logic is wrapped in a check for skipClassPathModification. Fixes #180 --- src/it/skinny-wars-javaee5/verify.bsh | 2 +- .../org/apache/maven/plugins/ear/EarMojo.java | 46 +++++++++---------- .../maven/plugins/ear/it/EarMojoIT.java | 4 +- 3 files changed, 27 insertions(+), 25 deletions(-) diff --git a/src/it/skinny-wars-javaee5/verify.bsh b/src/it/skinny-wars-javaee5/verify.bsh index c2b77232..5e82942d 100644 --- a/src/it/skinny-wars-javaee5/verify.bsh +++ b/src/it/skinny-wars-javaee5/verify.bsh @@ -135,7 +135,7 @@ String[] includedEntries = { "META-INF/MANIFEST.MF" }; -String[] warModule1ExpectedClassPathElements = { "lib/commons-lang-commons-lang-2.6.jar" }; +String[] warModule1ExpectedClassPathElements = { "commons-lang-2.6.jar" }; assertJar( earBaseDir + "org.apache.maven.its.ear.skinnywars-war-module1-1.0.war", includedEntries, warModuleExcludedEntries, true, warModule1ExpectedClassPathElements ); diff --git a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java index 576a0097..0a0e61ce 100644 --- a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java +++ b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java @@ -776,34 +776,34 @@ private void changeManifestClasspath( } // Modify the classpath entries in the manifest - final boolean forceClassPathModification = - javaEEVersion.lt(JavaEEVersion.FIVE) || defaultLibBundleDir == null; - final boolean classPathExtension = !skipClassPathModification || forceClassPathModification; - for (EarModule otherModule : getModules()) { - if (module.equals(otherModule)) { - continue; - } - final int moduleClassPathIndex = findModuleInClassPathElements(classPathElements, otherModule); - if (moduleClassPathIndex != -1) { - if (otherModule.isClassPathItem()) { - classPathElements.set(moduleClassPathIndex, otherModule.getUri()); - } else { - classPathElements.remove(moduleClassPathIndex); + if (!skipClassPathModification) { + final boolean forceClassPathModification = + javaEEVersion.lt(JavaEEVersion.FIVE) || defaultLibBundleDir == null; + final boolean classPathExtension = !skipClassPathModification || forceClassPathModification; + for (EarModule otherModule : getModules()) { + if (module.equals(otherModule)) { + continue; + } + final int moduleClassPathIndex = findModuleInClassPathElements(classPathElements, otherModule); + if (moduleClassPathIndex != -1) { + if (otherModule.isClassPathItem()) { + classPathElements.set(moduleClassPathIndex, otherModule.getUri()); + } else { + classPathElements.remove(moduleClassPathIndex); + } + } else if (otherModule.isClassPathItem() && classPathExtension) { + classPathElements.add(otherModule.getUri()); } - } else if (otherModule.isClassPathItem() && classPathExtension) { - classPathElements.add(otherModule.getUri()); } - } - // Remove provided modules from classpath - for (EarModule otherModule : getProvidedEarModules()) { - final int moduleClassPathIndex = findModuleInClassPathElements(classPathElements, otherModule); - if (moduleClassPathIndex != -1) { - classPathElements.remove(moduleClassPathIndex); + // Remove provided modules from classpath + for (EarModule otherModule : getProvidedEarModules()) { + final int moduleClassPathIndex = findModuleInClassPathElements(classPathElements, otherModule); + if (moduleClassPathIndex != -1) { + classPathElements.remove(moduleClassPathIndex); + } } - } - if (!skipClassPathModification || !classPathElements.isEmpty() || classPathExists) { classPath.setValue(StringUtils.join(classPathElements.iterator(), " ")); mf.getMainSection().addConfiguredAttribute(classPath); diff --git a/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java b/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java index 159a6f67..558720a0 100644 --- a/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java +++ b/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java @@ -951,6 +951,8 @@ void testProject089() throws Exception { void testProject090() throws Exception { final String warModule = "eartest-war-sample-three-1.0.war"; final String ejbModule = "eartest-ejb-sample-three-1.0.jar"; + final String jarSampleTwo = "jar-sample-two-1.0.jar"; + final String jarSampleThreeWithDeps = "jar-sample-three-with-deps-1.0.jar"; final String jarSampleTwoLibrary = "lib/eartest-jar-sample-two-1.0.jar"; final String jarSampleThreeLibrary = "lib/eartest-jar-sample-three-with-deps-1.0.jar"; doTestProject( @@ -960,7 +962,7 @@ void testProject090() throws Exception { new boolean[] {false, false, false, false}, new String[] {warModule, ejbModule}, new boolean[] {false, false}, - new String[][] {{jarSampleTwoLibrary}, {jarSampleThreeLibrary, jarSampleTwoLibrary}}, + new String[][] {{jarSampleTwo}, {jarSampleThreeWithDeps, jarSampleTwo}}, true); } From 38a12d0a7249f23c893d90932ecd35b13db008ee Mon Sep 17 00:00:00 2001 From: Elliotte Rusty Harold Date: Tue, 28 Jul 2026 17:52:43 +0000 Subject: [PATCH 2/3] MEAR-303: Fix changeManifestClasspath called without skinnyWars Restore v3.1.0 behavior where changeManifestClasspath is only invoked when skinnyWars or skinnyModules is active. Previously, the guard condition allowed modules with null libDir (like EJB modules) to proceed even without any skinny feature enabled, causing unnecessary Class-Path modification and potentially removing EJB client JARs from WAR modules. The guard now requires skinnyModules or (skinnyWars AND (WebModule or null-libDir module)) to proceed. Fixes #179 --- src/main/java/org/apache/maven/plugins/ear/EarMojo.java | 2 +- .../java/org/apache/maven/plugins/ear/it/EarMojoIT.java | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java index 0a0e61ce..ed481c4b 100644 --- a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java +++ b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java @@ -665,7 +665,7 @@ private void changeManifestClasspath( EarModule module, File original, JavaEEVersion javaEEVersion, Collection outdatedResources) throws MojoFailureException { final String moduleLibDir = module.getLibDir(); - if (!((moduleLibDir == null) || skinnyModules || (skinnyWars && module instanceof WebModule))) { + if (!(skinnyModules || (skinnyWars && (module instanceof WebModule || moduleLibDir == null)))) { return; } diff --git a/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java b/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java index 558720a0..bfbf4a3a 100644 --- a/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java +++ b/src/test/java/org/apache/maven/plugins/ear/it/EarMojoIT.java @@ -978,6 +978,8 @@ void testProject090() throws Exception { void testProject091() throws Exception { final String warModule = "eartest-war-sample-three-1.0.war"; final String ejbModule = "eartest-ejb-sample-three-1.0.jar"; + final String jarSampleTwo = "jar-sample-two-1.0.jar"; + final String jarSampleThreeWithDeps = "jar-sample-three-with-deps-1.0.jar"; final String jarSampleTwoLibrary = "eartest-jar-sample-two-1.0.jar"; final String jarSampleThreeLibrary = "eartest-jar-sample-three-with-deps-1.0.jar"; doTestProject( @@ -987,7 +989,7 @@ void testProject091() throws Exception { new boolean[] {false, true, false, false}, new String[] {warModule, ejbModule}, new boolean[] {false, true}, - new String[][] {{"jar-sample-two-1.0.jar"}, {jarSampleThreeLibrary, jarSampleTwoLibrary}}, + new String[][] {{jarSampleTwo}, {jarSampleThreeWithDeps, jarSampleTwo}}, true); } @@ -1213,7 +1215,7 @@ void testProject094() throws Exception { new boolean[] {false, false, false, false, false, false, false}, earModules, earModuleDirectory, - new String[][] {null, null, null, null, new String[] {jarSampleThreeEarLibrary, jarSampleTwoEarLibrary} + new String[][] {null, null, null, null, new String[] {jarSampleThreeLibrary, jarSampleTwoLibrary} }, true); From 1763027b46507c5195752a55d49b246cd4e45698 Mon Sep 17 00:00:00 2001 From: Elliotte Rusty Harold Date: Tue, 28 Jul 2026 18:48:08 +0000 Subject: [PATCH 3/3] Address review: simplify classPathExtension/classPathExists --- src/main/java/org/apache/maven/plugins/ear/EarMojo.java | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java index ed481c4b..992c792f 100644 --- a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java +++ b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java @@ -713,12 +713,9 @@ private void changeManifestClasspath( Attribute classPath = mf.getMainSection().getAttribute("Class-Path"); List classPathElements = new ArrayList<>(); - boolean classPathExists; if (classPath != null) { - classPathExists = true; classPathElements.addAll(Arrays.asList(classPath.getValue().split(" "))); } else { - classPathExists = false; classPath = new Attribute("Class-Path", ""); } @@ -777,9 +774,6 @@ private void changeManifestClasspath( // Modify the classpath entries in the manifest if (!skipClassPathModification) { - final boolean forceClassPathModification = - javaEEVersion.lt(JavaEEVersion.FIVE) || defaultLibBundleDir == null; - final boolean classPathExtension = !skipClassPathModification || forceClassPathModification; for (EarModule otherModule : getModules()) { if (module.equals(otherModule)) { continue; @@ -791,7 +785,7 @@ private void changeManifestClasspath( } else { classPathElements.remove(moduleClassPathIndex); } - } else if (otherModule.isClassPathItem() && classPathExtension) { + } else if (otherModule.isClassPathItem()) { classPathElements.add(otherModule.getUri()); } }