View Javadoc

1   package org.apache.maven.plugin.ear;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *  http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.archiver.MavenArchiveConfiguration;
23  import org.apache.maven.archiver.MavenArchiver;
24  import org.apache.maven.execution.MavenSession;
25  import org.apache.maven.plugin.MojoExecutionException;
26  import org.apache.maven.plugin.MojoFailureException;
27  import org.apache.maven.plugin.ear.util.EarMavenArchiver;
28  import org.apache.maven.plugin.ear.util.JavaEEVersion;
29  import org.apache.maven.project.MavenProjectHelper;
30  import org.apache.maven.shared.filtering.MavenFileFilter;
31  import org.apache.maven.shared.filtering.MavenFilteringException;
32  import org.apache.maven.shared.filtering.MavenResourcesExecution;
33  import org.apache.maven.shared.filtering.MavenResourcesFiltering;
34  import org.codehaus.plexus.archiver.ArchiverException;
35  import org.codehaus.plexus.archiver.UnArchiver;
36  import org.codehaus.plexus.archiver.jar.JarArchiver;
37  import org.codehaus.plexus.archiver.jar.Manifest;
38  import org.codehaus.plexus.archiver.jar.Manifest.Attribute;
39  import org.codehaus.plexus.archiver.jar.ManifestException;
40  import org.codehaus.plexus.archiver.manager.ArchiverManager;
41  import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
42  import org.codehaus.plexus.archiver.zip.ZipArchiver;
43  import org.codehaus.plexus.archiver.zip.ZipUnArchiver;
44  import org.codehaus.plexus.util.DirectoryScanner;
45  import org.codehaus.plexus.util.FileUtils;
46  import org.codehaus.plexus.util.StringUtils;
47  
48  import java.io.File;
49  import java.io.FileReader;
50  import java.io.IOException;
51  import java.io.PrintWriter;
52  import java.util.ArrayList;
53  import java.util.Arrays;
54  import java.util.List;
55  import java.util.zip.ZipException;
56  
57  /**
58   * Builds J2EE Enterprise Archive (EAR) files.
59   *
60   * @author <a href="snicoll@apache.org">Stephane Nicoll</a>
61   * @version $Id: EarMojo.java 1228837 2012-01-08 13:19:38Z rfscholte $
62   * @goal ear
63   * @phase package
64   * @threadSafe
65   * @requiresDependencyResolution test
66   */
67  public class EarMojo
68      extends AbstractEarMojo
69  {
70      private static final String[] EMPTY_STRING_ARRAY = { };
71  
72  
73      /**
74       * Single directory for extra files to include in the EAR.
75       *
76       * @parameter default-value="${basedir}/src/main/application"
77       * @required
78       */
79      private File earSourceDirectory;
80  
81      /**
82       * The comma separated list of tokens to include in the EAR.
83       *
84       * @parameter alias="includes" default-value="**"
85       */
86      private String earSourceIncludes;
87  
88      /**
89       * The comma separated list of tokens to exclude from the EAR.
90       *
91       * @parameter alias="excludes"
92       */
93      private String earSourceExcludes;
94  
95      /**
96       * Specify that the EAR sources should be filtered.
97       *
98       * @parameter default-value="false"
99       * @since 2.3.2
100      */
101     private boolean filtering;
102 
103     /**
104      * Filters (property files) to include during the interpolation of the pom.xml.
105      *
106      * @parameter
107      * @since 2.3.2
108      */
109     private List filters;
110 
111     /**
112      * A list of file extensions that should not be filtered if
113      * filtering is enabled.
114      *
115      * @parameter
116      * @since 2.3.2
117      */
118     private List nonFilteredFileExtensions;
119 
120     /**
121      * To escape interpolated value with Windows path
122      * c:\foo\bar will be replaced with c:\\foo\\bar.
123      *
124      * @parameter expression="${maven.ear.escapedBackslashesInFilePath}" default-value="false"
125      * @since 2.3.2
126      */
127     private boolean escapedBackslashesInFilePath;
128 
129     /**
130      * Expression preceded with this String won't be interpolated
131      * \${foo} will be replaced with ${foo}.
132      *
133      * @parameter expression="${maven.ear.escapeString}"
134      * @since 2.3.2
135      */
136     protected String escapeString;
137 
138     /**
139      * The location of the manifest file to be used within the EAR file. If
140      * no value if specified, the default location in the workDirectory is
141      * taken. If the file does not exist, a manifest will be generated
142      * automatically.
143      *
144      * @parameter
145      */
146     private File manifestFile;
147 
148     /**
149      * The location of a custom application.xml file to be used
150      * within the EAR file.
151      *
152      * @parameter
153      */
154     private String applicationXml;
155 
156     /**
157      * The directory for the generated EAR.
158      *
159      * @parameter default-value="${project.build.directory}"
160      * @required
161      */
162     private String outputDirectory;
163 
164     /**
165      * The name of the EAR file to generate.
166      *
167      * @parameter alias="earName" default-value="${project.build.finalName}"
168      * @required
169      */
170     private String finalName;
171 
172     /**
173      * The comma separated list of artifact's type(s) to unpack
174      * by default.
175      *
176      * @parameter
177      */
178     private String unpackTypes;
179 
180     /**
181      * Classifier to add to the artifact generated. If given, the artifact will
182      * be an attachment instead.
183      *
184      * @parameter
185      */
186     private String classifier;
187 
188     /**
189      * A comma separated list of tokens to exclude when packaging the EAR.
190      * By default nothing is excluded. Note that you can use the Java Regular
191      * Expressions engine to include and exclude specific pattern using the
192      * expression %regex[].
193      * Hint: read the about (?!Pattern).
194      *
195      * @parameter
196      * @since 2.7
197      */
198     private String packagingExcludes;
199 
200     /**
201      * A comma separated list of tokens to include when packaging the EAR.
202      * By default everything is included. Note that you can use the Java Regular
203      * Expressions engine to include and exclude specific pattern using the
204      * expression %regex[].
205      *
206      * @parameter
207      * @since 2.7
208      */
209     private String packagingIncludes;
210 
211     /**
212      * Whether to create skinny WARs or not. A skinny WAR is a WAR that does not
213      * have all of its dependencies in WEB-INF/lib. Instead those dependencies
214      * are shared between the WARs through the EAR.
215      *
216      * @parameter expression="${maven.ear.skinnyWars}" default-value="false"
217      * @since 2.7
218      */
219     private boolean skinnyWars;
220 
221     /**
222      * The Jar archiver.
223      *
224      * @component role="org.codehaus.plexus.archiver.Archiver" role-hint="jar"
225      */
226     private JarArchiver jarArchiver;
227 
228     /**
229      * The Zip archiver.
230      *
231      * @component role="org.codehaus.plexus.archiver.Archiver" role-hint="zip"
232      */
233     private ZipArchiver zipArchiver;
234 
235     /**
236      * The Zip Un archiver.
237      *
238      * @component role="org.codehaus.plexus.archiver.UnArchiver" role-hint="zip"
239      */
240     private ZipUnArchiver zipUnArchiver;
241 
242     /**
243      * The archive configuration to use.
244      * See <a href="http://maven.apache.org/shared/maven-archiver/index.html">Maven Archiver Reference</a>.
245      *
246      * @parameter
247      */
248     private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
249 
250     /**
251      * @component
252      */
253     private MavenProjectHelper projectHelper;
254 
255     /**
256      * The archive manager.
257      *
258      * @component
259      */
260     private ArchiverManager archiverManager;
261 
262     /**
263      * @component role="org.apache.maven.shared.filtering.MavenFileFilter" role-hint="default"
264      * @required
265      */
266     private MavenFileFilter mavenFileFilter;
267 
268     /**
269      * @component role="org.apache.maven.shared.filtering.MavenResourcesFiltering" role-hint="default"
270      * @required
271      */
272     private MavenResourcesFiltering mavenResourcesFiltering;
273 
274     /**
275      * @parameter expression="${session}"
276      * @readonly
277      * @required
278      * @since 2.3.2
279      */
280     private MavenSession session;
281 
282 
283     private List filterWrappers;
284 
285 
286     public void execute()
287         throws MojoExecutionException, MojoFailureException
288     {
289         // Initializes ear modules
290         super.execute();
291 
292         final JavaEEVersion javaEEVersion = JavaEEVersion.getJavaEEVersion( version );
293 
294         // Initializes unpack types
295         List<String> unpackTypesList = new ArrayList<String>();
296         if ( unpackTypes != null )
297         {
298             unpackTypesList = Arrays.asList( unpackTypes.split( "," ) );
299             for ( String type : unpackTypesList )
300             {
301                 if ( !EarModuleFactory.standardArtifactTypes.contains( type ) )
302                 {
303                     throw new MojoExecutionException(
304                         "Invalid type [" + type + "] supported types are " + EarModuleFactory.standardArtifactTypes );
305                 }
306             }
307             getLog().debug( "Initialized unpack types " + unpackTypesList );
308         }
309 
310         // Copy modules
311         try
312         {
313             for ( EarModule module: getModules() )
314             {
315                 if ( module instanceof JavaModule )
316                 {
317                     getLog().warn( "JavaModule is deprecated (" + module + "), please use JarModule instead." );
318                 }
319                 if ( module instanceof Ejb3Module )
320                 {
321                     getLog().warn( "Ejb3Module is deprecated (" + module + "), please use EjbModule instead." );
322                 }
323                 final File sourceFile = module.getArtifact().getFile();
324                 final File destinationFile = buildDestinationFile( getWorkDirectory(), module.getUri() );
325                 if ( !sourceFile.isFile() )
326                 {
327                     throw new MojoExecutionException(
328                         "Cannot copy a directory: " + sourceFile.getAbsolutePath() + "; Did you package/install "
329                             + module.getArtifact() + "?" );
330                 }
331 
332                 if ( destinationFile.getCanonicalPath().equals( sourceFile.getCanonicalPath() ) )
333                 {
334                     getLog().info(
335                         "Skipping artifact [" + module + "], as it already exists at [" + module.getUri() + "]" );
336                     continue;
337                 }
338 
339                 // If the module is within the unpack list, make sure that no unpack wasn't forced (null or true)
340                 // If the module is not in the unpack list, it should be true
341                 if ( ( unpackTypesList.contains( module.getType() )
342                     && ( module.shouldUnpack() == null || module.shouldUnpack().booleanValue() ) )
343                     || ( module.shouldUnpack() != null && module.shouldUnpack().booleanValue() ) )
344                 {
345                     getLog().info( "Copying artifact [" + module + "] to [" + module.getUri() + "] (unpacked)" );
346                     // Make sure that the destination is a directory to avoid plexus nasty stuff :)
347                     destinationFile.mkdirs();
348                     unpack( sourceFile, destinationFile );
349 
350                     if ( skinnyWars && module.changeManifestClasspath() )
351                     {
352                         changeManifestClasspath( module, destinationFile );
353                     }
354                 }
355                 else
356                 {
357                     if ( sourceFile.lastModified() > destinationFile.lastModified() )
358                     {
359                         getLog().info( "Copying artifact [" + module + "] to [" + module.getUri() + "]" );
360                         FileUtils.copyFile( sourceFile, destinationFile );
361 
362                         if ( skinnyWars && module.changeManifestClasspath() )
363                         {
364                             changeManifestClasspath( module, destinationFile );
365                         }
366                     }
367                     else
368                     {
369                         getLog().debug(
370                             "Skipping artifact [" + module + "], as it is already up to date at [" + module.getUri()
371                                 + "]" );
372                     }
373                 }
374             }
375         }
376         catch ( IOException e )
377         {
378             throw new MojoExecutionException( "Error copying EAR modules", e );
379         }
380         catch ( ArchiverException e )
381         {
382             throw new MojoExecutionException( "Error unpacking EAR modules", e );
383         }
384         catch ( NoSuchArchiverException e )
385         {
386             throw new MojoExecutionException( "No Archiver found for EAR modules", e );
387         }
388 
389         // Copy source files
390         try
391         {
392             File earSourceDir = earSourceDirectory;
393             if ( earSourceDir.exists() )
394             {
395                 getLog().info( "Copy ear sources to " + getWorkDirectory().getAbsolutePath() );
396                 String[] fileNames = getEarFiles( earSourceDir );
397                 for ( int i = 0; i < fileNames.length; i++ )
398                 {
399                     copyFile( new File( earSourceDir, fileNames[i] ), new File( getWorkDirectory(), fileNames[i] ) );
400                 }
401             }
402 
403             if ( applicationXml != null && !"".equals( applicationXml ) )
404             {
405                 //rename to application.xml
406                 getLog().info( "Including custom application.xml[" + applicationXml + "]" );
407                 File metaInfDir = new File( getWorkDirectory(), META_INF );
408                 copyFile( new File( applicationXml ), new File( metaInfDir, "/application.xml" ) );
409             }
410 
411         }
412         catch ( IOException e )
413         {
414             throw new MojoExecutionException( "Error copying EAR sources", e );
415         }
416         catch ( MavenFilteringException e )
417         {
418             throw new MojoExecutionException( "Error filtering EAR sources", e );
419         }
420 
421         // Check if deployment descriptor is there
422         File ddFile = new File( getWorkDirectory(), APPLICATION_XML_URI );
423         if ( !ddFile.exists() && ( javaEEVersion.lt( JavaEEVersion.Five ) ) )
424         {
425             throw new MojoExecutionException(
426                 "Deployment descriptor: " + ddFile.getAbsolutePath() + " does not exist." );
427         }
428 
429         try
430         {
431             File earFile = getEarFile( outputDirectory, finalName, classifier );
432             final MavenArchiver archiver = new EarMavenArchiver( getModules() );
433             final JarArchiver jarArchiver = getJarArchiver();
434             getLog().debug( "Jar archiver implementation [" + jarArchiver.getClass().getName() + "]" );
435             archiver.setArchiver( jarArchiver );
436             archiver.setOutputFile( earFile );
437 
438             // Include custom manifest if necessary
439             includeCustomManifestFile();
440 
441             getLog().debug(
442                 "Excluding " + Arrays.asList( getPackagingExcludes() ) + " from the generated EAR." );
443             getLog().debug(
444                 "Including " + Arrays.asList( getPackagingIncludes() ) + " in the generated EAR." );
445 
446             archiver.getArchiver().addDirectory( getWorkDirectory(), getPackagingIncludes(), getPackagingExcludes() );
447             archiver.createArchive( getProject(), archive );
448 
449             if ( classifier != null )
450             {
451                 projectHelper.attachArtifact( getProject(), "ear", classifier, earFile );
452             }
453             else
454             {
455                 getProject().getArtifact().setFile( earFile );
456             }
457         }
458         catch ( Exception e )
459         {
460             throw new MojoExecutionException( "Error assembling EAR", e );
461         }
462     }
463 
464     public String getApplicationXml()
465     {
466         return applicationXml;
467     }
468 
469     public void setApplicationXml( String applicationXml )
470     {
471         this.applicationXml = applicationXml;
472     }
473 
474     /**
475      * Returns a string array of the excludes to be used
476      * when assembling/copying the ear.
477      *
478      * @return an array of tokens to exclude
479      */
480     protected String[] getExcludes()
481     {
482         @SuppressWarnings( "unchecked" )
483         List<String> excludeList = new ArrayList<String>( FileUtils.getDefaultExcludesAsList() );
484         if ( earSourceExcludes != null && !"".equals( earSourceExcludes ) )
485         {
486             excludeList.addAll( Arrays.asList( StringUtils.split( earSourceExcludes, "," ) ) );
487         }
488 
489         // if applicationXml is specified, omit the one in the source directory
490         if ( getApplicationXml() != null && !"".equals( getApplicationXml() ) )
491         {
492             excludeList.add( "**/" + META_INF + "/application.xml" );
493         }
494 
495         return (String[]) excludeList.toArray( EMPTY_STRING_ARRAY );
496     }
497 
498     /**
499      * Returns a string array of the includes to be used
500      * when assembling/copying the ear.
501      *
502      * @return an array of tokens to include
503      */
504     protected String[] getIncludes()
505     {
506         return StringUtils.split( StringUtils.defaultString( earSourceIncludes ), "," );
507     }
508 
509     public String[] getPackagingExcludes()
510     {
511         if ( StringUtils.isEmpty( packagingExcludes ) )
512         {
513             return new String[0];
514         }
515         else
516         {
517             return StringUtils.split( packagingExcludes, "," );
518         }
519     }
520 
521     public void setPackagingExcludes( String packagingExcludes )
522     {
523         this.packagingExcludes = packagingExcludes;
524     }
525 
526     public String[] getPackagingIncludes()
527     {
528         if ( StringUtils.isEmpty( packagingIncludes ) )
529         {
530             return new String[]{"**"};
531         }
532         else
533         {
534             return StringUtils.split( packagingIncludes, "," );
535         }
536     }
537 
538     public void setPackagingIncludes( String packagingIncludes )
539     {
540         this.packagingIncludes = packagingIncludes;
541     }
542 
543     private static File buildDestinationFile( File buildDir, String uri )
544     {
545         return new File( buildDir, uri );
546     }
547 
548     private void includeCustomManifestFile()
549     {
550         if ( manifestFile == null )
551         {
552             manifestFile = new File( getWorkDirectory(), "META-INF/MANIFEST.MF" );
553         }
554 
555         if ( !manifestFile.exists() )
556         {
557             getLog().info( "Could not find manifest file: " + manifestFile + " - Generating one" );
558         }
559         else
560         {
561             getLog().info( "Including custom manifest file [" + manifestFile + "]" );
562             archive.setManifestFile( manifestFile );
563         }
564     }
565 
566     /**
567      * Returns the EAR file to generate, based on an optional classifier.
568      *
569      * @param basedir    the output directory
570      * @param finalName  the name of the ear file
571      * @param classifier an optional classifier
572      * @return the EAR file to generate
573      */
574     private static File getEarFile( String basedir, String finalName, String classifier )
575     {
576         if ( classifier == null )
577         {
578             classifier = "";
579         }
580         else if ( classifier.trim().length() > 0 && !classifier.startsWith( "-" ) )
581         {
582             classifier = "-" + classifier;
583         }
584 
585         return new File( basedir, finalName + classifier + ".ear" );
586     }
587 
588     /**
589      * Returns a list of filenames that should be copied
590      * over to the destination directory.
591      *
592      * @param sourceDir the directory to be scanned
593      * @return the array of filenames, relative to the sourceDir
594      */
595     private String[] getEarFiles( File sourceDir )
596     {
597         DirectoryScanner scanner = new DirectoryScanner();
598         scanner.setBasedir( sourceDir );
599         scanner.setExcludes( getExcludes() );
600         scanner.addDefaultExcludes();
601 
602         scanner.setIncludes( getIncludes() );
603 
604         scanner.scan();
605 
606         return scanner.getIncludedFiles();
607     }
608 
609     /**
610      * Unpacks the module into the EAR structure.
611      *
612      * @param source  File to be unpacked.
613      * @param destDir Location where to put the unpacked files.
614      */
615     public void unpack( File source, File destDir )
616         throws NoSuchArchiverException, IOException, ArchiverException
617     {
618         UnArchiver unArchiver = archiverManager.getUnArchiver( "zip" );
619         unArchiver.setSourceFile( source );
620         unArchiver.setDestDirectory( destDir );
621 
622         // Extract the module
623         unArchiver.extract();
624     }
625 
626     /**
627      * Returns the {@link JarArchiver} implementation used
628      * to package the EAR file.
629      * <p/>
630      * By default the archiver is obtained from the Plexus container.
631      *
632      * @return the archiver
633      */
634     protected JarArchiver getJarArchiver()
635     {
636         return jarArchiver;
637     }
638 
639     private void copyFile( File source, File target )
640         throws MavenFilteringException, IOException, MojoExecutionException
641     {
642         if ( filtering && !isNonFilteredExtension( source.getName() ) )
643         {
644             // Silly that we have to do this ourselves
645             if ( target.getParentFile() != null && !target.getParentFile().exists() )
646             {
647                 target.getParentFile().mkdirs();
648             }
649             mavenFileFilter.copyFile( source, target, true, getFilterWrappers(), null );
650         }
651         else
652         {
653             FileUtils.copyFile( source, target );
654         }
655     }
656 
657     public boolean isNonFilteredExtension( String fileName )
658     {
659         return !mavenResourcesFiltering.filteredFileExtension( fileName, nonFilteredFileExtensions );
660     }
661 
662     private List getFilterWrappers()
663         throws MojoExecutionException
664     {
665         if ( filterWrappers == null )
666         {
667             try
668             {
669                 MavenResourcesExecution mavenResourcesExecution = new MavenResourcesExecution();
670                 mavenResourcesExecution.setEscapeString( escapeString );
671                 filterWrappers =
672                     mavenFileFilter.getDefaultFilterWrappers( project, filters, escapedBackslashesInFilePath,
673                                                               this.session, mavenResourcesExecution );
674             }
675             catch ( MavenFilteringException e )
676             {
677                 getLog().error( "Fail to build filtering wrappers " + e.getMessage() );
678                 throw new MojoExecutionException( e.getMessage(), e );
679             }
680         }
681         return filterWrappers;
682     }
683 
684     private void changeManifestClasspath( EarModule module, File original )
685             throws MojoFailureException
686     {
687         try
688         {
689             File workDirectory;
690 
691             // Handle the case that the destination might be a directory (project-038)
692             if ( original.isFile() )
693             {
694                 // Create a temporary work directory
695                 workDirectory = new File( new File(
696                         generatedDescriptorLocation, "temp" ), module.getArtifact()
697                         .getArtifactId() );
698                 workDirectory.mkdirs();
699                 getLog().debug( "Created a temporary work directory: " + workDirectory.getAbsolutePath() );
700 
701                 // Unpack the archive to a temporary work directory
702                 zipUnArchiver.setSourceFile( original );
703                 zipUnArchiver.setDestDirectory( workDirectory );
704                 zipUnArchiver.extract();
705             }
706             else
707             {
708                 workDirectory = original;
709             }
710 
711             // Create a META-INF/MANIFEST.MF file if it doesn't exist (project-038)
712             File metaInfDirectory = new File( workDirectory, "META-INF" );
713             boolean newMetaInfCreated = metaInfDirectory.mkdirs();
714             if ( newMetaInfCreated )
715             {
716                 getLog().debug(
717                         "This project did not have a META-INF directory before, so a new directory was created." );
718             }
719             File manifestFile = new File( metaInfDirectory, "MANIFEST.MF" );
720             boolean newManifestCreated = manifestFile.createNewFile();
721             if ( newManifestCreated )
722             {
723                 getLog().debug(
724                         "This project did not have a META-INF/MANIFEST.MF file before, so a new file was created." );
725             }
726 
727             // Read the manifest from disk
728             Manifest mf = new Manifest( new FileReader( manifestFile ) );
729             Attribute classPath = mf.getMainSection()
730                     .getAttribute( "Class-Path" );
731             List<String> classPathElements = new ArrayList<String>();
732 
733             if ( classPath != null )
734             {
735                 classPathElements.addAll( Arrays.asList( classPath.getValue()
736                         .split( " " ) ) );
737             }
738             else
739             {
740                 classPath = new Attribute( "Class-Path", "" );
741                 mf.getMainSection().addConfiguredAttribute( classPath );
742             }
743 
744             // Modify the classpath entries in the manifest
745             for ( EarModule o : getModules() )
746             {
747                 if ( o instanceof JarModule )
748                 {
749                     JarModule jm = ( JarModule ) o;
750 
751                     if ( module.getLibDir() != null )
752                     {
753                         File artifact = new File( new File(
754                                 workDirectory, module.getLibDir() ),
755                                 jm.getBundleFileName() );
756 
757                         if ( artifact.exists() )
758                         {
759                             if ( !artifact.delete() )
760                             {
761                                 getLog().error(
762                                         "Could not delete '" + artifact + "'" );
763                             }
764                         }
765                     }
766 
767                     if ( classPathElements.contains( jm.getBundleFileName() ) )
768                     {
769                         classPathElements.set( classPathElements.indexOf( jm
770                                 .getBundleFileName() ), jm.getUri() );
771                     }
772                     else
773                     {
774                         classPathElements.add( jm.getUri() );
775                     }
776                 }
777             }
778             classPath.setValue( StringUtils.join( classPathElements.iterator(), " " ) );
779 
780             // Write the manifest to disk
781             PrintWriter pw = new PrintWriter( manifestFile );
782             mf.write( pw );
783             pw.close();
784 
785             if ( original.isFile() )
786             {
787                 // Pack up the archive again from the work directory
788                 if ( !original.delete() )
789                 {
790                     getLog().error( "Could not delete original artifact file " + original );
791                 }
792 
793                 getLog().debug( "Zipping module" );
794                 zipArchiver.setDestFile( original );
795                 zipArchiver.addDirectory( workDirectory );
796                 zipArchiver.createArchive();
797             }
798         }
799         catch ( ManifestException e )
800         {
801             throw new MojoFailureException( e.getMessage() );
802         }
803         catch ( ZipException e )
804         {
805             throw new MojoFailureException( e.getMessage() );
806         }
807         catch ( IOException e )
808         {
809             throw new MojoFailureException( e.getMessage() );
810         }
811         catch ( ArchiverException e )
812         {
813             throw new MojoFailureException( e.getMessage() );
814         }
815     }
816 }