You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by el...@apache.org on 2020/12/23 21:52:25 UTC

[maven-ear-plugin] branch master updated: [MEAR-294] Removal of provided artifacts from the Class-Path entry of MANIFEST.mf (#31)

This is an automated email from the ASF dual-hosted git repository.

elharo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/maven-ear-plugin.git


The following commit(s) were added to refs/heads/master by this push:
     new beb1ce7  [MEAR-294] Removal of provided artifacts from the Class-Path entry of MANIFEST.mf (#31)
beb1ce7 is described below

commit beb1ce79db242a74f3b9af9a82b5311af60ee8ee
Author: Marat Abrarov <ab...@gmail.com>
AuthorDate: Thu Dec 24 00:52:18 2020 +0300

    [MEAR-294] Removal of provided artifacts from the Class-Path entry of MANIFEST.mf (#31)
    
    * [MEAR-294] - Removal of provided artifacts from Class-Path entry of MANIFEST.mf if skinnyWars / skinnyModules options is turned on or if EAR module doesn't contain its dependencies.
    
    * [MEAR-294] - Fixed JavaDoc for the new / changed methods.
    
    * [MEAR-294] - Minor optimization of Class-Path entry modification.
---
 .../ear-module/pom.xml                             |   8 +-
 src/it/MEAR-243-skinny-wars-provided/pom.xml       |   5 +-
 src/it/MEAR-243-skinny-wars-provided/verify.bsh    | 138 ++++++++++++---------
 .../{war-module => war-module-one}/pom.xml         |   2 +-
 .../src/main/webapp/WEB-INF/web.xml                |   0
 .../{war-module => war-module-two}/pom.xml         |   9 +-
 .../src/main/webapp/WEB-INF/web.xml                |   0
 .../apache/maven/plugins/ear/AbstractEarMojo.java  |  22 +++-
 .../java/org/apache/maven/plugins/ear/EarMojo.java |  17 ++-
 .../org/apache/maven/plugins/ear/it/EarMojoIT.java |  34 +++--
 .../resources/projects/project-092/ear/pom.xml     |   5 +
 src/test/resources/projects/project-092/pom.xml    |   5 +
 .../resources/projects/project-092/war/pom.xml     |   4 +
 .../ear/expected-META-INF/application.xml          |   4 +
 .../resources/projects/project-094/ear/pom.xml     |  11 ++
 .../{project-092/war => project-094/ejb}/pom.xml   |  15 ++-
 .../ejb/src/main/java/eartest/Stub.java            |  22 ++++
 src/test/resources/projects/project-094/pom.xml    |  12 ++
 18 files changed, 229 insertions(+), 84 deletions(-)

diff --git a/src/it/MEAR-243-skinny-wars-provided/ear-module/pom.xml b/src/it/MEAR-243-skinny-wars-provided/ear-module/pom.xml
index 7709a45..cbf39cf 100644
--- a/src/it/MEAR-243-skinny-wars-provided/ear-module/pom.xml
+++ b/src/it/MEAR-243-skinny-wars-provided/ear-module/pom.xml
@@ -36,7 +36,13 @@ under the License.
     </dependency>
     <dependency>
       <groupId>org.apache.maven.its.ear.skinnywars</groupId>
-      <artifactId>war-module</artifactId>
+      <artifactId>war-module-one</artifactId>
+      <version>1.0</version>
+      <type>war</type>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.maven.its.ear.skinnywars</groupId>
+      <artifactId>war-module-two</artifactId>
       <version>1.0</version>
       <type>war</type>
     </dependency>
diff --git a/src/it/MEAR-243-skinny-wars-provided/pom.xml b/src/it/MEAR-243-skinny-wars-provided/pom.xml
index f427da9..e1dc3ba 100644
--- a/src/it/MEAR-243-skinny-wars-provided/pom.xml
+++ b/src/it/MEAR-243-skinny-wars-provided/pom.xml
@@ -31,7 +31,8 @@ under the License.
   <url>https://issues.apache.org/jira/browse/MEAR-243</url>
 
   <modules>
-      <module>ear-module</module>
-      <module>war-module</module>
+    <module>ear-module</module>
+    <module>war-module-one</module>
+    <module>war-module-two</module>
   </modules>
 </project>
diff --git a/src/it/MEAR-243-skinny-wars-provided/verify.bsh b/src/it/MEAR-243-skinny-wars-provided/verify.bsh
index 1aa05b4..6e7b874 100644
--- a/src/it/MEAR-243-skinny-wars-provided/verify.bsh
+++ b/src/it/MEAR-243-skinny-wars-provided/verify.bsh
@@ -22,92 +22,112 @@ import java.util.*;
 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 );
+    JarFile jar = new JarFile( jarFile );
 
-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 )
+    if ( includedEntries != null )
     {
-        throw new IllegalStateException( "Missing archive entry: " + included );
+        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 );
+            }
+        }
     }
-}
 
-Manifest manifest = jar.getManifest();
-String manifestClassPath = manifest.getMainAttributes().getValue("Class-Path");
-if ( manifestClassPath.contains("commons-lang-2.5.jar") )
-{
-    throw new IllegalStateException( "Surplus entry in war MANIFEST.MF: commons-lang-2.5.jar");
-}
+    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 );
+            }
+        }
+    }
 
-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 )
+    if ( assertManifest )
     {
-        throw new IllegalStateException( "Archive entry should be excluded: " + excluded );
+        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 ) );
+            }
+        }
     }
 }
 
-jar.close();
+String[] includedEntries = {
+    "WEB-INF/web.xml",
+    "META-INF/MANIFEST.MF",
+    "WEB-INF/lib/commons-lang-2.5.jar"
+};
 
+assertJar( "war-module-one/target/war-module-one-1.0.war", includedEntries, null, false, 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 );
-}
+String[] expectedClassPathElements = {
+    "commons-lang-2.5.jar"
+};
 
-JarFile jar = new JarFile( jarFile );
+assertJar( "war-module-two/target/war-module-two-1.0.war", includedEntries, null, true, expectedClassPathElements );
 
 String[] includedEntries = {
     "WEB-INF/web.xml",
-    "META-INF/MANIFEST.MF",
+    "META-INF/MANIFEST.MF"
+};
+
+String[] excludedEntries = {
     "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();
+String[] expectedClassPathElements = {};
 
-File earFile = new File( basedir, "ear-module/target/ear-module-1.0.ear" );
+assertJar( "ear-module/target/ear-module-1.0/org.apache.maven.its.ear.skinnywars-war-module-one-1.0.war",
+    includedEntries, excludedEntries, true, expectedClassPathElements );
 
-JarFile ear = new JarFile( earFile );
+assertJar( "ear-module/target/ear-module-1.0/org.apache.maven.its.ear.skinnywars-war-module-two-1.0.war",
+    includedEntries, excludedEntries, true, expectedClassPathElements );
 
 String[] excludedEntries = {
     "commons-lang-2.5.jar",
     "lib/commons-lang-2.5.jar",
 };
-for ( String excluded : excludedEntries )
-{
-    System.out.println( "Checking for excluded artifact " + excluded );
-    if ( ear.getEntry( excluded ) != null )
-    {
-        throw new IllegalStateException( "Archive entry should be excluded: " + excluded );
-    }
-}
 
-ear.close();
+assertJar( "ear-module/target/ear-module-1.0.ear", null, excludedEntries, false, null );
 
 return true;
diff --git a/src/it/MEAR-243-skinny-wars-provided/war-module/pom.xml b/src/it/MEAR-243-skinny-wars-provided/war-module-one/pom.xml
similarity index 97%
copy from src/it/MEAR-243-skinny-wars-provided/war-module/pom.xml
copy to src/it/MEAR-243-skinny-wars-provided/war-module-one/pom.xml
index 9604026..1bb48a4 100644
--- a/src/it/MEAR-243-skinny-wars-provided/war-module/pom.xml
+++ b/src/it/MEAR-243-skinny-wars-provided/war-module-one/pom.xml
@@ -23,7 +23,7 @@ under the License.
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>org.apache.maven.its.ear.skinnywars</groupId>
-  <artifactId>war-module</artifactId>
+  <artifactId>war-module-one</artifactId>
   <version>1.0</version>
   <packaging>war</packaging>
 
diff --git a/src/it/MEAR-243-skinny-wars-provided/war-module/src/main/webapp/WEB-INF/web.xml b/src/it/MEAR-243-skinny-wars-provided/war-module-one/src/main/webapp/WEB-INF/web.xml
similarity index 100%
copy from src/it/MEAR-243-skinny-wars-provided/war-module/src/main/webapp/WEB-INF/web.xml
copy to src/it/MEAR-243-skinny-wars-provided/war-module-one/src/main/webapp/WEB-INF/web.xml
diff --git a/src/it/MEAR-243-skinny-wars-provided/war-module/pom.xml b/src/it/MEAR-243-skinny-wars-provided/war-module-two/pom.xml
similarity index 85%
rename from src/it/MEAR-243-skinny-wars-provided/war-module/pom.xml
rename to src/it/MEAR-243-skinny-wars-provided/war-module-two/pom.xml
index 9604026..1c232d8 100644
--- a/src/it/MEAR-243-skinny-wars-provided/war-module/pom.xml
+++ b/src/it/MEAR-243-skinny-wars-provided/war-module-two/pom.xml
@@ -23,7 +23,7 @@ under the License.
   <modelVersion>4.0.0</modelVersion>
 
   <groupId>org.apache.maven.its.ear.skinnywars</groupId>
-  <artifactId>war-module</artifactId>
+  <artifactId>war-module-two</artifactId>
   <version>1.0</version>
   <packaging>war</packaging>
 
@@ -41,6 +41,13 @@ under the License.
         <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/MEAR-243-skinny-wars-provided/war-module/src/main/webapp/WEB-INF/web.xml b/src/it/MEAR-243-skinny-wars-provided/war-module-two/src/main/webapp/WEB-INF/web.xml
similarity index 100%
rename from src/it/MEAR-243-skinny-wars-provided/war-module/src/main/webapp/WEB-INF/web.xml
rename to src/it/MEAR-243-skinny-wars-provided/war-module-two/src/main/webapp/WEB-INF/web.xml
diff --git a/src/main/java/org/apache/maven/plugins/ear/AbstractEarMojo.java b/src/main/java/org/apache/maven/plugins/ear/AbstractEarMojo.java
index 7bd8f76..e7083f6 100644
--- a/src/main/java/org/apache/maven/plugins/ear/AbstractEarMojo.java
+++ b/src/main/java/org/apache/maven/plugins/ear/AbstractEarMojo.java
@@ -169,6 +169,8 @@ public abstract class AbstractEarMojo
 
     private List<JarModule> allJarModules;
 
+    private List<JarModule> providedJarModules;
+
     private JbossConfiguration jbossConfiguration;
 
     /** {@inheritDoc} */
@@ -271,6 +273,7 @@ public abstract class AbstractEarMojo
         // Now we have everything let's built modules which have not been excluded
         ScopeArtifactFilter filter = new ScopeArtifactFilter( Artifact.SCOPE_RUNTIME );
         allJarModules = new ArrayList<JarModule>();
+        providedJarModules = new ArrayList<JarModule>();
         earModules = new ArrayList<EarModule>();
         for ( EarModule earModule : allModules )
         {
@@ -280,7 +283,8 @@ public abstract class AbstractEarMojo
             }
             else
             {
-                if ( earModule instanceof JarModule )
+                boolean isJarModule = earModule instanceof JarModule;
+                if ( isJarModule )
                 {
                     allJarModules.add( (JarModule) earModule );
                 }
@@ -288,6 +292,10 @@ public abstract class AbstractEarMojo
                 {
                     earModules.add( earModule );
                 }
+                else if ( isJarModule )
+                {
+                    providedJarModules.add( (JarModule) earModule );
+                }
             }
         }
 
@@ -318,6 +326,18 @@ public abstract class AbstractEarMojo
     }
 
     /**
+     * @return the list of {@link #providedJarModules}. This corresponds to provided JAR modules.
+     */
+    protected List<JarModule> getProvidedJarModules()
+    {
+        if ( providedJarModules == null )
+        {
+            throw new IllegalStateException( "Jar modules have not been initialized" );
+        }
+        return providedJarModules;
+    }
+
+    /**
      * @return {@link MavenProject}
      */
     protected MavenProject getProject()
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 e717e26..0ffdd6f 100644
--- a/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
+++ b/src/main/java/org/apache/maven/plugins/ear/EarMojo.java
@@ -911,16 +911,23 @@ public class EarMojo
                     {
                         classPathElements.set( moduleClassPathIndex, jm.getUri() );
                     }
-                    else if ( !skipClassPathModification )
-                    {
-                        classPathElements.add( jm.getUri() );
-                    }
-                    else if ( forceClassPathModification )
+                    else if ( !skipClassPathModification || forceClassPathModification )
                     {
                         classPathElements.add( jm.getUri() );
                     }
                 }
             }
+
+            // Remove provided Jar modules from classpath
+            for ( JarModule jm : getProvidedJarModules() )
+            {
+                final int moduleClassPathIndex = findModuleInClassPathElements( classPathElements, jm );
+                if ( moduleClassPathIndex != -1 )
+                {
+                    classPathElements.remove( moduleClassPathIndex );
+                }
+            }
+
             if ( !skipClassPathModification || !classPathElements.isEmpty() || classPathExists )
             {
                 classPath.setValue( StringUtils.join( classPathElements.iterator(), " " ) );
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 678c353..3bd317c 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
@@ -1003,8 +1003,12 @@ public class EarMojoIT
      * <li>skinnyModules options is turned on</li>
      * </ul>
      * then movement of JARs and modification of manifest Class-Path entry is performed for WAR, SAR, HAR and RAR
-     * modules. Additionally this test ensures that movement of JARs is not performed for modules which
-     * libDirectory property doesn't point to the right module entry containing JAR libraries packaged into module.
+     * modules. Additionally this test ensures that
+     * <ul>
+     * <li>movement of JARs is not performed for modules whose libDirectory property doesn't point to the correct module
+     * entry containing JAR libraries packaged into the module</li>
+     * <li>JAR with provided scope is removed from modules and from Class-Path entries</li>
+     * </ul>
      */
     public void testProject092()
         throws Exception
@@ -1123,8 +1127,13 @@ public class EarMojoIT
      * <li>skinnyWars option is turned off (has default value)</li>
      * <li>skinnyModules options is turned off (has default value)</li>
      * </ul>
-     * then movement of JARs and modification of manifest Class-Path entry is not performed for WAR, SAR, HAR and
-     * RAR modules.
+     * then
+     * <ul>
+     * <li>movement of JARs and modification of the manifest Class-Path entry is not performed for WAR, SAR, HAR and
+     * RAR modules</li>
+     * <li>modification of the manifest Class-Path entry is performed for EJB module</li>
+     * <li>provided JAR is removed from the manifest Class-Path entry of EJB module</li>
+     * </ul>
      */
     public void testProject094()
         throws Exception
@@ -1134,21 +1143,27 @@ public class EarMojoIT
         final String jarSampleOneLibrary = "jar-sample-one-1.0.jar";
         final String jarSampleTwoLibrary = "jar-sample-two-1.0.jar";
         final String jarSampleThreeLibrary = "jar-sample-three-with-deps-1.0.jar";
+        final String jarSampleTwoEarLibrary = "lib/eartest-" + jarSampleTwoLibrary;
+        final String jarSampleThreeEarLibrary = "lib/eartest-" + jarSampleThreeLibrary;
         final String warModule = "eartest-war-sample-three-1.0.war";
         final String sarModule = "eartest-sar-sample-two-1.0.sar";
         final String harModule = "eartest-har-sample-two-1.0.har";
         final String rarModule = "eartest-rar-sample-one-1.0.rar";
-        final String[] earModules = { warModule, sarModule, harModule, rarModule };
-        final boolean[] earModuleDirectory = { false, false, false, false };
+        final String ejbModule = "eartest-ejb-sample-three-1.0.jar";
+        final String[] earModules = { warModule, sarModule, harModule, rarModule, ejbModule };
+        final boolean[] earModuleDirectory = { false, false, false, false, false };
         final String warModuleLibDir = "WEB-INF/lib/";
         final String sarModuleLibDir = "lib/";
         final String harModuleLibDir = "lib/";
         final String rarModuleLibDir = "";
 
         final File baseDir = doTestProject( projectName, earModuleName,
+            new String[] { warModule, sarModule, harModule, rarModule, ejbModule, jarSampleTwoEarLibrary,
+                jarSampleThreeEarLibrary },
+            new boolean[] { false, false, false, false, false, false, false },
             earModules, earModuleDirectory,
-            earModules, earModuleDirectory,
-            new String[][] { null, null, null, null },
+            new String[][] { null, null, null, null,
+                new String[] { jarSampleThreeEarLibrary, jarSampleTwoEarLibrary } },
             true );
 
         assertEarModulesContent( baseDir, projectName, earModuleName, earModules, earModuleDirectory,
@@ -1156,7 +1171,8 @@ public class EarMojoIT
                 { warModuleLibDir + jarSampleTwoLibrary, warModuleLibDir + jarSampleThreeLibrary },
                 { sarModuleLibDir + jarSampleOneLibrary, sarModuleLibDir + jarSampleTwoLibrary, sarModuleLibDir + jarSampleThreeLibrary },
                 { harModuleLibDir + jarSampleOneLibrary, harModuleLibDir + jarSampleTwoLibrary, harModuleLibDir + jarSampleThreeLibrary },
-                { rarModuleLibDir + jarSampleOneLibrary, rarModuleLibDir + jarSampleTwoLibrary, rarModuleLibDir + jarSampleThreeLibrary } } ,
+                { rarModuleLibDir + jarSampleOneLibrary, rarModuleLibDir + jarSampleTwoLibrary, rarModuleLibDir + jarSampleThreeLibrary },
+                null } ,
             null );
     }
 
diff --git a/src/test/resources/projects/project-092/ear/pom.xml b/src/test/resources/projects/project-092/ear/pom.xml
index fc35448..20ec9d9 100644
--- a/src/test/resources/projects/project-092/ear/pom.xml
+++ b/src/test/resources/projects/project-092/ear/pom.xml
@@ -30,6 +30,11 @@ under the License.
   <packaging>ear</packaging>
   <dependencies>
     <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
       <groupId>eartest</groupId>
       <artifactId>jar-sample-one</artifactId>
     </dependency>
diff --git a/src/test/resources/projects/project-092/pom.xml b/src/test/resources/projects/project-092/pom.xml
index b807f4c..e95ca18 100644
--- a/src/test/resources/projects/project-092/pom.xml
+++ b/src/test/resources/projects/project-092/pom.xml
@@ -41,6 +41,11 @@ under the License.
   <dependencyManagement>
     <dependencies>
       <dependency>
+        <groupId>commons-lang</groupId>
+        <artifactId>commons-lang</artifactId>
+        <version>2.5</version>
+      </dependency>
+      <dependency>
         <groupId>eartest</groupId>
         <artifactId>jar-sample-one</artifactId>
         <version>1.0</version>
diff --git a/src/test/resources/projects/project-092/war/pom.xml b/src/test/resources/projects/project-092/war/pom.xml
index 84a517b..563f74f 100644
--- a/src/test/resources/projects/project-092/war/pom.xml
+++ b/src/test/resources/projects/project-092/war/pom.xml
@@ -32,6 +32,10 @@ under the License.
   <packaging>war</packaging>
   <dependencies>
     <dependency>
+      <groupId>commons-lang</groupId>
+      <artifactId>commons-lang</artifactId>
+    </dependency>
+    <dependency>
       <groupId>eartest</groupId>
       <artifactId>jar-sample-two</artifactId>
     </dependency>
diff --git a/src/test/resources/projects/project-094/ear/expected-META-INF/application.xml b/src/test/resources/projects/project-094/ear/expected-META-INF/application.xml
index 6ef9a7c..0d15248 100644
--- a/src/test/resources/projects/project-094/ear/expected-META-INF/application.xml
+++ b/src/test/resources/projects/project-094/ear/expected-META-INF/application.xml
@@ -28,4 +28,8 @@ under the License.
   <module>
     <connector>eartest-rar-sample-one-1.0.rar</connector>
   </module>
+  <module>
+    <ejb>eartest-ejb-sample-three-1.0.jar</ejb>
+  </module>
+  <library-directory>lib</library-directory>
 </application>
diff --git a/src/test/resources/projects/project-094/ear/pom.xml b/src/test/resources/projects/project-094/ear/pom.xml
index 73bb61d..2c00c84 100644
--- a/src/test/resources/projects/project-094/ear/pom.xml
+++ b/src/test/resources/projects/project-094/ear/pom.xml
@@ -30,6 +30,11 @@ under the License.
   <packaging>ear</packaging>
   <dependencies>
     <dependency>
+      <groupId>org.jboss.spec.javax.ejb</groupId>
+      <artifactId>jboss-ejb-api_3.1_spec</artifactId>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
       <groupId>eartest</groupId>
       <artifactId>war-sample-three</artifactId>
       <type>war</type>
@@ -63,6 +68,11 @@ under the License.
       <artifactId>rar-sample-one</artifactId>
       <type>rar</type>
     </dependency>
+    <dependency>
+      <groupId>eartest</groupId>
+      <artifactId>ejb-sample-three</artifactId>
+      <type>ejb</type>
+    </dependency>
   </dependencies>
   <build>
     <plugins>
@@ -79,6 +89,7 @@ under the License.
           <jboss>
             <version>5</version>
           </jboss>
+          <defaultLibBundleDir>lib</defaultLibBundleDir>
         </configuration>
       </plugin>
     </plugins>
diff --git a/src/test/resources/projects/project-092/war/pom.xml b/src/test/resources/projects/project-094/ejb/pom.xml
similarity index 79%
copy from src/test/resources/projects/project-092/war/pom.xml
copy to src/test/resources/projects/project-094/ejb/pom.xml
index 84a517b..f0abce2 100644
--- a/src/test/resources/projects/project-092/war/pom.xml
+++ b/src/test/resources/projects/project-094/ejb/pom.xml
@@ -23,25 +23,30 @@ under the License.
   <modelVersion>4.0.0</modelVersion>
   <parent>
     <groupId>ear</groupId>
-    <artifactId>maven-ear-plugin-test-project-092-parent</artifactId>
+    <artifactId>maven-ear-plugin-test-project-094-parent</artifactId>
     <version>99.0</version>
   </parent>
   <groupId>eartest</groupId>
-  <artifactId>war-sample-three</artifactId>
+  <artifactId>ejb-sample-three</artifactId>
   <version>1.0</version>
-  <packaging>war</packaging>
+  <packaging>ejb</packaging>
   <dependencies>
     <dependency>
+      <groupId>org.jboss.spec.javax.ejb</groupId>
+      <artifactId>jboss-ejb-api_3.1_spec</artifactId>
+    </dependency>
+    <dependency>
       <groupId>eartest</groupId>
-      <artifactId>jar-sample-two</artifactId>
+      <artifactId>jar-sample-three-with-deps</artifactId>
     </dependency>
   </dependencies>
   <build>
     <plugins>
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
-        <artifactId>maven-war-plugin</artifactId>
+        <artifactId>maven-ejb-plugin</artifactId>
         <configuration>
+          <ejbVersion>3.1</ejbVersion>
           <archive>
             <manifest>
               <addClasspath>true</addClasspath>
diff --git a/src/test/resources/projects/project-094/ejb/src/main/java/eartest/Stub.java b/src/test/resources/projects/project-094/ejb/src/main/java/eartest/Stub.java
new file mode 100644
index 0000000..b8b0059
--- /dev/null
+++ b/src/test/resources/projects/project-094/ejb/src/main/java/eartest/Stub.java
@@ -0,0 +1,22 @@
+package eartest;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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
+ *
+ *  http://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.
+ */
+
+public class Stub {}
diff --git a/src/test/resources/projects/project-094/pom.xml b/src/test/resources/projects/project-094/pom.xml
index d6fad7f..a9640a1 100644
--- a/src/test/resources/projects/project-094/pom.xml
+++ b/src/test/resources/projects/project-094/pom.xml
@@ -31,6 +31,7 @@ under the License.
     <module>har</module>
     <module>rar</module>
     <module>ear</module>
+    <module>ejb</module>
   </modules>
   <properties>
     <maven.compiler.source>1.7</maven.compiler.source>
@@ -39,6 +40,11 @@ under the License.
   <dependencyManagement>
     <dependencies>
       <dependency>
+        <groupId>org.jboss.spec.javax.ejb</groupId>
+        <artifactId>jboss-ejb-api_3.1_spec</artifactId>
+        <version>1.0.2.Final</version>
+      </dependency>
+      <dependency>
         <groupId>eartest</groupId>
         <artifactId>jar-sample-one</artifactId>
         <version>1.0</version>
@@ -77,6 +83,12 @@ under the License.
         <version>1.0</version>
         <type>rar</type>
       </dependency>
+      <dependency>
+        <groupId>eartest</groupId>
+        <artifactId>ejb-sample-three</artifactId>
+        <version>1.0</version>
+        <type>ejb</type>
+      </dependency>
     </dependencies>
   </dependencyManagement>
   <build>