[MEAR-292] skipClassPathModification in case of undefined Class-Path entry of MANIFEST.mf (#29)

* [MEAR-292] - Don't add MANFIEST.mf Class-Path entry for EAR module if skipClassPathModification is true and original MANFIEST.mf of EAR module artifact doesn't contain Class-Path entry.

* [MEAR-292] - skinnyWar integration test supporting Java 7.
diff --git a/src/it/skinny-wars-javaee5/ear-module/pom.xml b/src/it/skinny-wars-javaee5/ear-module/pom.xml
index 20bfc63..dc3371b 100644
--- a/src/it/skinny-wars-javaee5/ear-module/pom.xml
+++ b/src/it/skinny-wars-javaee5/ear-module/pom.xml
@@ -31,11 +31,28 @@
     <dependency>
       <groupId>commons-lang</groupId>
       <artifactId>commons-lang</artifactId>
-      <version>2.5</version>
+      <version>2.6</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-collections4</artifactId>
+      <version>4.2</version>
     </dependency>
     <dependency>
       <groupId>org.apache.maven.its.ear.skinnywars</groupId>
-      <artifactId>war-module</artifactId>
+      <artifactId>war-module1</artifactId>
+      <version>1.0</version>
+      <type>war</type>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.its.ear.skinnywars</groupId>
+      <artifactId>war-module2</artifactId>
+      <version>1.0</version>
+      <type>war</type>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.its.ear.skinnywars</groupId>
+      <artifactId>war-module3</artifactId>
       <version>1.0</version>
       <type>war</type>
     </dependency>
diff --git a/src/it/skinny-wars-javaee5/pom.xml b/src/it/skinny-wars-javaee5/pom.xml
index ce56bae..0afee72 100644
--- a/src/it/skinny-wars-javaee5/pom.xml
+++ b/src/it/skinny-wars-javaee5/pom.xml
@@ -30,7 +30,26 @@
   <description>Test Skinny WAR generation</description>
 
   <modules>
-      <module>ear-module</module>
-      <module>war-module</module>
+    <module>ear-module</module>
+    <module>war-module1</module>
+    <module>war-module2</module>
+    <module>war-module3</module>
   </modules>
+
+  <build>
+    <pluginManagement>
+      <plugins>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-war-plugin</artifactId>
+          <version>@mavenWarPluginVersion@</version>
+        </plugin>
+        <plugin>
+          <groupId>org.apache.maven.plugins</groupId>
+          <artifactId>maven-ear-plugin</artifactId>
+          <version>@project.version@</version>
+        </plugin>
+      </plugins>
+    </pluginManagement>
+  </build>
 </project>
diff --git a/src/it/skinny-wars-javaee5/verify.bsh b/src/it/skinny-wars-javaee5/verify.bsh
index ad6abb9..45c2419 100644
--- a/src/it/skinny-wars-javaee5/verify.bsh
+++ b/src/it/skinny-wars-javaee5/verify.bsh
@@ -22,73 +22,128 @@
 import java.util.jar.*;
 import java.util.regex.*;
 
-File jarFile = new File( basedir, "ear-module/target/ear-module-1.0/org.apache.maven.its.ear.skinnywars-war-module-1.0.war" );
-System.out.println( "Checking for existence of " + jarFile );
-if ( !jarFile.isFile() )
+assertJar( String fileName, String[] includedEntries, String[] excludedEntries, boolean assertManifest,
+    String[] expectedClassPathElements )
 {
-    throw new IllegalStateException( "Missing file: " + jarFile );
+    File jarFile = new File( basedir, fileName );
+    System.out.println( "Checking for existence of " + jarFile );
+    if ( !jarFile.isFile() )
+    {
+        throw new IllegalStateException( "Missing file: " + jarFile );
+    }
+
+    JarFile jar = new JarFile( jarFile );
+
+    if ( includedEntries != null )
+    {
+        for ( String included : includedEntries )
+        {
+            System.out.println( "Checking for included archive entry " + included );
+            if ( jar.getEntry( included ) == null )
+            {
+                throw new IllegalStateException( "Missing archive entry: " + included + ". Artifact: " + fileName );
+            }
+        }
+    }
+
+    if ( excludedEntries != null )
+    {
+        for ( String excluded : excludedEntries )
+        {
+            System.out.println( "Checking for excluded artifact " + excluded );
+            if ( jar.getEntry( excluded ) != null )
+            {
+                throw new IllegalStateException( "Archive entry should be excluded: " + excluded
+                    + ". Artifact: " + fileName );
+            }
+        }
+    }
+
+    if ( assertManifest )
+    {
+        Manifest manifest = jar.getManifest();
+        String manifestClassPath = manifest.getMainAttributes().getValue("Class-Path");
+        if ( expectedClassPathElements == null)
+        {
+            if ( manifestClassPath != null )
+            {
+                throw new IllegalStateException( "Superfluous Class-Path entry in MANIFEST.MF of artifact: "
+                    + fileName );
+            }
+        }
+        else
+        {
+            if ( manifestClassPath == null )
+            {
+                throw new IllegalStateException( "Missing Class-Path entry in MANIFEST.MF of artifact: "
+                    + fileName );
+            }
+            manifestClassPath = manifestClassPath.trim();
+            String[] actualClassPathElements = manifestClassPath.length() == 0 ?
+                new String[0] : manifestClassPath.split( " " );
+            if ( !Arrays.equals( expectedClassPathElements, actualClassPathElements ) )
+            {
+                throw new IllegalStateException( "Invalid Class-Path entry in MANIFEST.MF of artifact: "
+                    + fileName
+                    + ". Expected: " + Arrays.toString( expectedClassPathElements )
+                    + ". Actual: " + Arrays.toString( actualClassPathElements ) );
+            }
+        }
+    }
 }
 
-JarFile jar = new JarFile( jarFile );
+String[] includedEntries = {
+    "WEB-INF/web.xml",
+    "META-INF/MANIFEST.MF",
+    "WEB-INF/lib/commons-lang-2.6.jar"
+};
+
+String[] excludedEntries = {};
+
+String[] expectedClassPathElements = { "commons-lang-2.6.jar" };
+
+assertJar( "war-module1/target/war-module1-1.0.war", includedEntries, excludedEntries, true,
+    expectedClassPathElements );
+
+assertJar( "war-module2/target/war-module2-1.0.war", includedEntries, excludedEntries, true, null );
+
+String[] warModule3IncludedEntries = {
+    "WEB-INF/web.xml",
+    "META-INF/MANIFEST.MF",
+    "WEB-INF/lib/commons-io-2.6.jar"
+};
+
+String[] warModuleExcludedEntries = {
+    "WEB-INF/lib/commons-lang-2.6.jar",
+    "WEB-INF/lib/commons-collections4-4.2.jar"
+};
+
+String[] warModule3ExpectedClassPathElements = { "commons-io-2.6.jar" };
+
+assertJar( "war-module3/target/war-module3-1.0.war", warModule3IncludedEntries, warModuleExcludedEntries, true,
+    warModule3ExpectedClassPathElements );
+
+String earBaseDir = "ear-module/target/ear-module-1.0/";
+String earLibDir = earBaseDir + "lib/";
+
+assertJar( earLibDir + "commons-lang-commons-lang-2.6.jar", null, null, false, null );
+
+assertJar( earLibDir + "org.apache.commons-commons-collections4-4.2.jar", null, null, false, null );
 
 String[] includedEntries = {
     "WEB-INF/web.xml",
     "META-INF/MANIFEST.MF"
 };
-for ( String included : includedEntries )
-{
-    System.out.println( "Checking for included archive entry " + included );
-    if ( jar.getEntry( included ) == null )
-    {
-        throw new IllegalStateException( "Missing archive entry: " + included );
-    }
-}
 
-Manifest manifest = jar.getManifest();
-String manifestClassPath = manifest.getMainAttributes().getValue("Class-Path");
-if ( manifestClassPath != null && manifestClassPath.equals("lib/commons-lang-commons-lang-2.5.jar") )
-{
-    throw new IllegalStateException( "Superfluous entry in war MANIFEST.MF: commons-lang-commons-lang-2.5.jar");
-}
+String[] warModule1ExpectedClassPathElements = { "lib/commons-lang-commons-lang-2.6.jar" };
 
-String[] excludedEntries = {
-    "WEB-INF/lib/commons-lang-2.5.jar"
-};
-for ( String excluded : excludedEntries )
-{
-    System.out.println( "Checking for excluded artifact " + excluded );
-    if ( jar.getEntry( excluded ) != null )
-    {
-        throw new IllegalStateException( "Archive entry should be excluded: " + excluded );
-    }
-}
+assertJar( earBaseDir + "org.apache.maven.its.ear.skinnywars-war-module1-1.0.war", includedEntries,
+    warModuleExcludedEntries, true, warModule1ExpectedClassPathElements );
 
-jar.close();
+assertJar( earBaseDir + "org.apache.maven.its.ear.skinnywars-war-module2-1.0.war", includedEntries,
+    warModuleExcludedEntries, true, null );
 
-
-File jarFile = new File( basedir, "war-module/target/war-module-1.0.war" );
-System.out.println( "Checking for existence of " + jarFile );
-if ( !jarFile.isFile() )
-{
-    throw new IllegalStateException( "Missing file: " + jarFile );
-}
-
-JarFile jar = new JarFile( jarFile );
-
-String[] includedEntries = {
-    "WEB-INF/web.xml",
-    "META-INF/MANIFEST.MF",
-    "WEB-INF/lib/commons-lang-2.5.jar"
-};
-for ( String included : includedEntries )
-{
-    System.out.println( "Checking for included archive entry " + included );
-    if ( jar.getEntry( included ) == null )
-    {
-        throw new IllegalStateException( "Missing archive entry: " + included );
-    }
-}
-
-jar.close();
+assertJar( earBaseDir + "org.apache.maven.its.ear.skinnywars-war-module3-1.0.war",
+    warModule3IncludedEntries, warModuleExcludedEntries, true, warModule3ExpectedClassPathElements );
 
 return true;
diff --git a/src/it/skinny-wars-javaee5/war-module/pom.xml b/src/it/skinny-wars-javaee5/war-module1/pom.xml
similarity index 83%
rename from src/it/skinny-wars-javaee5/war-module/pom.xml
rename to src/it/skinny-wars-javaee5/war-module1/pom.xml
index 9604026..c093103 100644
--- a/src/it/skinny-wars-javaee5/war-module/pom.xml
+++ b/src/it/skinny-wars-javaee5/war-module1/pom.xml
@@ -23,7 +23,7 @@
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>org.apache.maven.its.ear.skinnywars</groupId>
-  <artifactId>war-module</artifactId>
+  <artifactId>war-module1</artifactId>
   <version>1.0</version>
   <packaging>war</packaging>
 
@@ -31,7 +31,7 @@
     <dependency>
       <groupId>commons-lang</groupId>
       <artifactId>commons-lang</artifactId>
-      <version>2.5</version>
+      <version>2.6</version>
     </dependency>
   </dependencies>
 
@@ -40,7 +40,13 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-war-plugin</artifactId>
-        <version>@mavenWarPluginVersion@</version>
+        <configuration>
+          <archive>
+            <manifest>
+              <addClasspath>true</addClasspath>
+            </manifest>
+          </archive>
+        </configuration>
       </plugin>
     </plugins>
   </build>
diff --git a/src/it/skinny-wars-javaee5/war-module/src/main/webapp/WEB-INF/web.xml b/src/it/skinny-wars-javaee5/war-module1/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from src/it/skinny-wars-javaee5/war-module/src/main/webapp/WEB-INF/web.xml
rename to src/it/skinny-wars-javaee5/war-module1/src/main/webapp/WEB-INF/web.xml
diff --git a/src/it/skinny-wars-javaee5/war-module/pom.xml b/src/it/skinny-wars-javaee5/war-module2/pom.xml
similarity index 78%
copy from src/it/skinny-wars-javaee5/war-module/pom.xml
copy to src/it/skinny-wars-javaee5/war-module2/pom.xml
index 9604026..5d2fd3c 100644
--- a/src/it/skinny-wars-javaee5/war-module/pom.xml
+++ b/src/it/skinny-wars-javaee5/war-module2/pom.xml
@@ -23,7 +23,7 @@
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>org.apache.maven.its.ear.skinnywars</groupId>
-  <artifactId>war-module</artifactId>
+  <artifactId>war-module2</artifactId>
   <version>1.0</version>
   <packaging>war</packaging>
 
@@ -31,17 +31,7 @@
     <dependency>
       <groupId>commons-lang</groupId>
       <artifactId>commons-lang</artifactId>
-      <version>2.5</version>
+      <version>2.6</version>
     </dependency>
   </dependencies>
-
-  <build>
-    <plugins>
-      <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-war-plugin</artifactId>
-        <version>@mavenWarPluginVersion@</version>
-      </plugin>
-    </plugins>
-  </build>
 </project>
diff --git a/src/it/skinny-wars-javaee5/war-module/src/main/webapp/WEB-INF/web.xml b/src/it/skinny-wars-javaee5/war-module2/src/main/webapp/WEB-INF/web.xml
similarity index 100%
copy from src/it/skinny-wars-javaee5/war-module/src/main/webapp/WEB-INF/web.xml
copy to src/it/skinny-wars-javaee5/war-module2/src/main/webapp/WEB-INF/web.xml
diff --git a/src/it/skinny-wars-javaee5/war-module/pom.xml b/src/it/skinny-wars-javaee5/war-module3/pom.xml
similarity index 78%
copy from src/it/skinny-wars-javaee5/war-module/pom.xml
copy to src/it/skinny-wars-javaee5/war-module3/pom.xml
index 9604026..8041f63 100644
--- a/src/it/skinny-wars-javaee5/war-module/pom.xml
+++ b/src/it/skinny-wars-javaee5/war-module3/pom.xml
@@ -23,15 +23,15 @@
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>org.apache.maven.its.ear.skinnywars</groupId>
-  <artifactId>war-module</artifactId>
+  <artifactId>war-module3</artifactId>
   <version>1.0</version>
   <packaging>war</packaging>
 
   <dependencies>
     <dependency>
-      <groupId>commons-lang</groupId>
-      <artifactId>commons-lang</artifactId>
-      <version>2.5</version>
+      <groupId>commons-io</groupId>
+      <artifactId>commons-io</artifactId>
+      <version>2.6</version>
     </dependency>
   </dependencies>
 
@@ -40,7 +40,13 @@
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-war-plugin</artifactId>
-        <version>@mavenWarPluginVersion@</version>
+        <configuration>
+          <archive>
+            <manifest>
+              <addClasspath>true</addClasspath>
+            </manifest>
+          </archive>
+        </configuration>
       </plugin>
     </plugins>
   </build>
diff --git a/src/it/skinny-wars-javaee5/war-module/src/main/webapp/WEB-INF/web.xml b/src/it/skinny-wars-javaee5/war-module3/src/main/webapp/WEB-INF/web.xml
similarity index 100%
copy from src/it/skinny-wars-javaee5/war-module/src/main/webapp/WEB-INF/web.xml
copy to src/it/skinny-wars-javaee5/war-module3/src/main/webapp/WEB-INF/web.xml
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 e0dc675..e717e26 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
@@ -825,12 +825,15 @@
             Attribute classPath = mf.getMainSection().getAttribute( "Class-Path" );

             List<String> classPathElements = new ArrayList<String>();

 

+            boolean classPathExists;

             if ( classPath != null )

             {

+                classPathExists = true;

                 classPathElements.addAll( Arrays.asList( classPath.getValue().split( " " ) ) );

             }

             else

             {

+                classPathExists = false;

                 classPath = new Attribute( "Class-Path", "" );

             }

 

@@ -897,6 +900,7 @@
             }

 

             // Modify the classpath entries in the manifest

+            boolean forceClassPathModification = javaEEVersion.lt( JavaEEVersion.FIVE ) || defaultLibBundleDir == null;

             for ( EarModule o : getModules() )

             {

                 if ( o instanceof JarModule )

@@ -907,30 +911,27 @@
                     {

                         classPathElements.set( moduleClassPathIndex, jm.getUri() );

                     }

-                    else

+                    else if ( !skipClassPathModification )

                     {

-                        if ( !skipClassPathModification )

-                        {

-                            classPathElements.add( jm.getUri() );

-                        }

-                        else

-                        {

-                            if ( javaEEVersion.lt( JavaEEVersion.FIVE ) || defaultLibBundleDir == null )

-                            {

-                                classPathElements.add( jm.getUri() );

-                            }

-                        }

+                        classPathElements.add( jm.getUri() );

+                    }

+                    else if ( forceClassPathModification )

+                    {

+                        classPathElements.add( jm.getUri() );

                     }

                 }

             }

-            classPath.setValue( StringUtils.join( classPathElements.iterator(), " " ) );

-            mf.getMainSection().addConfiguredAttribute( classPath );

-

-            // Write the manifest to disk

-            try ( FileOutputStream out = new FileOutputStream( manifestFile );

-                  OutputStreamWriter writer = new OutputStreamWriter( out, StandardCharsets.UTF_8 ) )

+            if ( !skipClassPathModification || !classPathElements.isEmpty() || classPathExists )

             {

-                mf.write( writer );

+                classPath.setValue( StringUtils.join( classPathElements.iterator(), " " ) );

+                mf.getMainSection().addConfiguredAttribute( classPath );

+

+                // Write the manifest to disk

+                try ( FileOutputStream out = new FileOutputStream( manifestFile );

+                      OutputStreamWriter writer = new OutputStreamWriter( out, StandardCharsets.UTF_8 ) )

+                {

+                    mf.write( writer );

+                }

             }

 

             if ( original.isFile() )