View Javadoc

1   package org.apache.tomcat.maven.plugin.tomcat7.run;
2   /*
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *   http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing,
14   * software distributed under the License is distributed on an
15   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16   * KIND, either express or implied.  See the License for the
17   * specific language governing permissions and limitations
18   * under the License.
19   */
20  
21  import java.io.File;
22  import java.io.FileInputStream;
23  import java.io.FileOutputStream;
24  import java.io.IOException;
25  import java.io.PrintWriter;
26  import java.util.Properties;
27  import java.util.jar.JarFile;
28  
29  import org.apache.commons.compress.archivers.ArchiveException;
30  import org.apache.commons.compress.archivers.ArchiveOutputStream;
31  import org.apache.commons.compress.archivers.ArchiveStreamFactory;
32  import org.apache.commons.compress.archivers.jar.JarArchiveEntry;
33  import org.apache.commons.io.IOUtils;
34  import org.apache.commons.lang.StringUtils;
35  import org.apache.maven.artifact.Artifact;
36  import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
37  import org.apache.maven.artifact.resolver.ArtifactResolutionException;
38  import org.apache.maven.model.Dependency;
39  import org.apache.maven.plugin.MojoExecutionException;
40  import org.apache.maven.plugin.MojoFailureException;
41  import org.apache.maven.plugins.annotations.Parameter;
42  import org.apache.tomcat.maven.runner.Tomcat7Runner;
43  import org.apache.tomcat.maven.runner.Tomcat7RunnerCli;
44  import org.codehaus.plexus.archiver.jar.Manifest;
45  import org.codehaus.plexus.archiver.jar.ManifestException;
46  import org.codehaus.plexus.util.DirectoryScanner;
47  
48  /**
49   * Abstract Mojo for building deployable and executable war files
50   *
51   * @since 2.1
52   */
53  public abstract class AbstractStandaloneWarMojo
54      extends AbstractExecWarMojo
55  {
56  
57      /**
58       * Name of the generated WAR.
59       */
60      @Parameter(property = "tomcat.jar.finalName",
61                 defaultValue = "${project.artifactId}-${project.version}-standalone.war", required = true)
62      protected String finalName;
63  
64      /**
65       * the classifier to use for the attached/generated artifact
66       */
67      @Parameter(property = "maven.tomcat.exec.war.attachArtifactClassifier", defaultValue = "standalone",
68                 required = true)
69      protected String attachArtifactClassifier;
70  
71      public void execute()
72          throws MojoExecutionException, MojoFailureException
73      {
74          if ( !"war".equals( project.getPackaging() ) )
75          {
76              throw new MojoFailureException( "Pacakaging must be of type war for standalone-war goal." );
77          }
78  
79          File warExecFile = new File( buildDirectory, finalName );
80          if ( warExecFile.exists() )
81          {
82              warExecFile.delete();
83          }
84  
85          File execWarJar = new File( buildDirectory, finalName );
86  
87          FileOutputStream execWarJarOutputStream = null;
88          ArchiveOutputStream os = null;
89          File tmpPropertiesFile = null;
90          File tmpManifestFile = null;
91          FileOutputStream tmpPropertiesFileOutputStream = null;
92          PrintWriter tmpManifestWriter = null;
93  
94          try
95          {
96              tmpPropertiesFile = new File( buildDirectory, "war-exec.properties" );
97              if ( tmpPropertiesFile.exists() )
98              {
99                  tmpPropertiesFile.delete();
100             }
101             tmpPropertiesFile.getParentFile().mkdirs();
102 
103             tmpManifestFile = new File( buildDirectory, "war-exec.manifest" );
104             if ( tmpManifestFile.exists() )
105             {
106                 tmpManifestFile.delete();
107             }
108             tmpPropertiesFileOutputStream = new FileOutputStream( tmpPropertiesFile );
109             execWarJar.getParentFile().mkdirs();
110             execWarJar.createNewFile();
111             execWarJarOutputStream = new FileOutputStream( execWarJar );
112 
113             tmpManifestWriter = new PrintWriter( tmpManifestFile );
114 
115             // store :
116             //* wars in the root: foo.war
117             //* tomcat jars
118             //* file tomcat.standalone.properties with possible values :
119             //   * useServerXml=true/false to use directly the one provided
120             //   * enableNaming=true/false
121             //   * wars=foo.war|contextpath;bar.war  ( |contextpath is optionnal if empty use the war name )
122             //   * accessLogValveFormat=
123             //   * connectorhttpProtocol: HTTP/1.1 or org.apache.coyote.http11.Http11NioProtocol
124             //   * codeSourceContextPath=path parameter, default is project.artifactId
125             //* optionnal: conf/ with usual tomcat configuration files
126             //* MANIFEST with Main-Class
127 
128             Properties properties = new Properties();
129 
130             properties.put( Tomcat7Runner.ARCHIVE_GENERATION_TIMESTAMP_KEY,
131                             Long.toString( System.currentTimeMillis() ) );
132             properties.put( Tomcat7Runner.ENABLE_NAMING_KEY, Boolean.toString( enableNaming ) );
133             properties.put( Tomcat7Runner.ACCESS_LOG_VALVE_FORMAT_KEY, accessLogValveFormat );
134             properties.put( Tomcat7Runner.HTTP_PROTOCOL_KEY, connectorHttpProtocol );
135             properties.put( Tomcat7Runner.CODE_SOURCE_CONTEXT_PATH, path );
136 
137             os = new ArchiveStreamFactory().createArchiveOutputStream( ArchiveStreamFactory.JAR,
138                                                                        execWarJarOutputStream );
139 
140             extractJarToArchive( new JarFile( projectArtifact.getFile() ), os );
141 
142             if ( serverXml != null && serverXml.exists() )
143             {
144                 os.putArchiveEntry( new JarArchiveEntry( "conf/server.xml" ) );
145                 IOUtils.copy( new FileInputStream( serverXml ), os );
146                 os.closeArchiveEntry();
147                 properties.put( Tomcat7Runner.USE_SERVER_XML_KEY, Boolean.TRUE.toString() );
148             }
149             else
150             {
151                 properties.put( Tomcat7Runner.USE_SERVER_XML_KEY, Boolean.FALSE.toString() );
152             }
153 
154             os.putArchiveEntry( new JarArchiveEntry( "conf/web.xml" ) );
155             IOUtils.copy( getClass().getResourceAsStream( "/conf/web.xml" ), os );
156             os.closeArchiveEntry();
157 
158             properties.store( tmpPropertiesFileOutputStream, "created by Apache Tomcat Maven plugin" );
159 
160             tmpPropertiesFileOutputStream.flush();
161             tmpPropertiesFileOutputStream.close();
162 
163             os.putArchiveEntry( new JarArchiveEntry( Tomcat7RunnerCli.STAND_ALONE_PROPERTIES_FILENAME ) );
164             IOUtils.copy( new FileInputStream( tmpPropertiesFile ), os );
165             os.closeArchiveEntry();
166 
167             // add tomcat classes
168             for ( Artifact pluginArtifact : pluginArtifacts )
169             {
170                 if ( StringUtils.equals( "org.apache.tomcat", pluginArtifact.getGroupId() ) || StringUtils.equals(
171                     "org.apache.tomcat.embed", pluginArtifact.getGroupId() ) || StringUtils.equals(
172                     "org.eclipse.jdt.core.compiler", pluginArtifact.getGroupId() ) || StringUtils.equals( "commons-cli",
173                                                                                                           pluginArtifact.getArtifactId() )
174                     || StringUtils.equals( "tomcat7-war-runner", pluginArtifact.getArtifactId() ) )
175                 {
176                     JarFile jarFile = new JarFile( pluginArtifact.getFile() );
177                     extractJarToArchive( jarFile, os );
178                 }
179             }
180 
181             // add extra dependencies
182             if ( extraDependencies != null && !extraDependencies.isEmpty() )
183             {
184                 for ( Dependency dependency : extraDependencies )
185                 {
186                     // String groupId, String artifactId, String version, String scope, String type
187                     Artifact artifact =
188                         artifactFactory.createArtifact( dependency.getGroupId(), dependency.getArtifactId(),
189                                                         dependency.getVersion(), dependency.getScope(),
190                                                         dependency.getType() );
191 
192                     artifactResolver.resolve( artifact, this.remoteRepos, this.local );
193                     JarFile jarFile = new JarFile( artifact.getFile() );
194                     extractJarToArchive( jarFile, os );
195                 }
196             }
197 
198             Manifest manifest = new Manifest();
199 
200             Manifest.Attribute mainClassAtt = new Manifest.Attribute();
201             mainClassAtt.setName( "Main-Class" );
202             mainClassAtt.setValue( mainClass );
203             manifest.addConfiguredAttribute( mainClassAtt );
204 
205             manifest.write( tmpManifestWriter );
206             tmpManifestWriter.flush();
207             tmpManifestWriter.close();
208 
209             os.putArchiveEntry( new JarArchiveEntry( "META-INF/MANIFEST.MF" ) );
210             IOUtils.copy( new FileInputStream( tmpManifestFile ), os );
211             os.closeArchiveEntry();
212 
213             if ( attachArtifact )
214             {
215                 //MavenProject project, String artifactType, String artifactClassifier, File artifactFile
216                 projectHelper.attachArtifact( project, attachArtifactClassifierType, attachArtifactClassifier,
217                                               execWarJar );
218             }
219 
220             if ( extraResources != null )
221             {
222                 for ( ExtraResource extraResource : extraResources )
223                 {
224 
225                     DirectoryScanner directoryScanner = new DirectoryScanner();
226                     directoryScanner.setBasedir( extraResource.getDirectory() );
227                     directoryScanner.addDefaultExcludes();
228                     directoryScanner.setExcludes( toStringArray( extraResource.getExcludes() ) );
229                     directoryScanner.setIncludes( toStringArray( extraResource.getIncludes() ) );
230                     directoryScanner.scan();
231                     for ( String includeFile : directoryScanner.getIncludedFiles() )
232                     {
233                         getLog().debug( "include file:" + includeFile );
234                         os.putArchiveEntry( new JarArchiveEntry( includeFile ) );
235                         IOUtils.copy( new FileInputStream( new File( extraResource.getDirectory(), includeFile ) ),
236                                       os );
237                         os.closeArchiveEntry();
238                     }
239                 }
240             }
241 
242             if ( tomcatConfigurationFilesDirectory != null && tomcatConfigurationFilesDirectory.exists() )
243             {
244                 // Because its the tomcat default dir for configs
245                 String aConfigOutputDir = "conf/";
246                 copyDirectoryContentIntoArchive( tomcatConfigurationFilesDirectory, aConfigOutputDir, os );
247             }
248         }
249         catch ( ManifestException e )
250         {
251             throw new MojoExecutionException( e.getMessage(), e );
252         }
253         catch ( IOException e )
254         {
255             throw new MojoExecutionException( e.getMessage(), e );
256         }
257         catch ( ArchiveException e )
258         {
259             throw new MojoExecutionException( e.getMessage(), e );
260         }
261         catch ( ArtifactNotFoundException e )
262         {
263             throw new MojoExecutionException( e.getMessage(), e );
264         }
265         catch ( ArtifactResolutionException e )
266         {
267             throw new MojoExecutionException( e.getMessage(), e );
268         }
269         finally
270         {
271             IOUtils.closeQuietly( os );
272             IOUtils.closeQuietly( tmpManifestWriter );
273             IOUtils.closeQuietly( execWarJarOutputStream );
274             IOUtils.closeQuietly( tmpPropertiesFileOutputStream );
275         }
276 
277     }
278 }