1 package org.apache.tomcat.maven.plugin.tomcat7.run;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 import org.apache.catalina.loader.WebappLoader;
22 import org.apache.commons.io.FileUtils;
23 import org.apache.commons.lang.StringUtils;
24 import org.apache.maven.artifact.Artifact;
25 import org.apache.maven.plugin.MojoExecutionException;
26 import org.apache.maven.plugins.annotations.Component;
27 import org.apache.maven.plugins.annotations.Execute;
28 import org.apache.maven.plugins.annotations.LifecyclePhase;
29 import org.apache.maven.plugins.annotations.Mojo;
30 import org.apache.maven.plugins.annotations.Parameter;
31 import org.apache.maven.plugins.annotations.ResolutionScope;
32 import org.apache.maven.shared.filtering.MavenFileFilterRequest;
33 import org.apache.maven.shared.filtering.MavenFilteringException;
34 import org.apache.tomcat.maven.common.run.ClassLoaderEntriesCalculator;
35 import org.apache.tomcat.maven.common.run.ClassLoaderEntriesCalculatorRequest;
36 import org.apache.tomcat.maven.common.run.ClassLoaderEntriesCalculatorResult;
37 import org.apache.tomcat.maven.common.run.TomcatRunException;
38 import org.codehaus.plexus.util.IOUtil;
39 import org.codehaus.plexus.util.xml.Xpp3Dom;
40 import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
41 import org.codehaus.plexus.util.xml.Xpp3DomWriter;
42 import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
43
44 import java.io.File;
45 import java.io.FileReader;
46 import java.io.FileWriter;
47 import java.io.IOException;
48 import java.io.StringWriter;
49 import java.util.List;
50 import java.util.Set;
51
52
53
54
55
56
57
58 @Mojo( name = "run", requiresDependencyResolution = ResolutionScope.TEST, threadSafe = true )
59 @Execute( phase = LifecyclePhase.PROCESS_CLASSES )
60 public class RunMojo
61 extends AbstractRunMojo
62 {
63
64
65
66
67
68
69
70
71 @Parameter( defaultValue = "${project.artifacts}", required = true, readonly = true )
72 private Set<Artifact> dependencies;
73
74
75
76
77 @Parameter( defaultValue = "${basedir}/src/main/webapp", property = "tomcat.warSourceDirectory" )
78 private File warSourceDirectory;
79
80
81
82
83
84
85
86
87 @Parameter( property = "tomcat.delegate", defaultValue = "true" )
88 private boolean delegate = true;
89
90
91
92
93 @Component
94 private ClassLoaderEntriesCalculator classLoaderEntriesCalculator;
95
96
97
98
99
100
101 @Parameter( property = "maven.tomcat.addWarDependenciesInClassloader", defaultValue = "true" )
102 private boolean addWarDependenciesInClassloader;
103
104
105
106
107
108
109 @Parameter( property = "maven.tomcat.useTestClasspath", defaultValue = "false" )
110 private boolean useTestClasspath;
111
112
113
114
115
116
117 @Parameter( alias = "additionalClassesDirs" )
118 private List<String> additionalClasspathDirs;
119
120
121
122
123 @Override
124 protected File getDocBase()
125 throws IOException
126 {
127
128
129 if ( !warSourceDirectory.exists() )
130 {
131
132 final File tempDocBase = createTempDirectory( new File( project.getBuild().getDirectory() ) );
133 Runtime.getRuntime().addShutdownHook( new Thread()
134 {
135 @Override
136 public void run()
137 {
138 try
139 {
140 FileUtils.deleteDirectory( tempDocBase );
141 }
142 catch ( Exception e )
143 {
144
145 }
146 }
147 } );
148 return tempDocBase;
149 }
150 return warSourceDirectory;
151 }
152
153 private static File createTempDirectory( File baseTmpDirectory )
154 throws IOException
155 {
156 final File temp = File.createTempFile( "temp", Long.toString( System.nanoTime() ), baseTmpDirectory );
157
158 if ( !( temp.delete() ) )
159 {
160 throw new IOException( "Could not delete temp file: " + temp.getAbsolutePath() );
161 }
162
163 if ( !( temp.mkdir() ) )
164 {
165 throw new IOException( "Could not create temp directory: " + temp.getAbsolutePath() );
166 }
167
168 return temp;
169 }
170
171
172
173
174 @Override
175 protected File getContextFile()
176 throws MojoExecutionException
177 {
178 File temporaryContextFile = null;
179
180
181
182
183
184
185 FileReader fr = null;
186 FileWriter fw = null;
187 StringWriter sw = new StringWriter();
188 try
189 {
190 temporaryContextFile = File.createTempFile( "tomcat-maven-plugin", "temp-ctx-file" );
191 temporaryContextFile.deleteOnExit();
192
193
194 if ( contextFile != null && contextFile.exists() )
195 {
196 MavenFileFilterRequest mavenFileFilterRequest = new MavenFileFilterRequest();
197 mavenFileFilterRequest.setFrom( contextFile );
198 mavenFileFilterRequest.setTo( temporaryContextFile );
199 mavenFileFilterRequest.setMavenProject( project );
200 mavenFileFilterRequest.setMavenSession( session );
201 mavenFileFilterRequest.setFiltering( true );
202
203 mavenFileFilter.copyFile( mavenFileFilterRequest );
204
205 fr = new FileReader( temporaryContextFile );
206 Xpp3Dom xpp3Dom = Xpp3DomBuilder.build( fr );
207 xpp3Dom.setAttribute( "backgroundProcessorDelay", Integer.toString( backgroundProcessorDelay ) );
208 xpp3Dom.setAttribute( "reloadable", Boolean.toString( isContextReloadable() ) );
209 fw = new FileWriter( temporaryContextFile );
210 Xpp3DomWriter.write( fw, xpp3Dom );
211 Xpp3DomWriter.write( sw, xpp3Dom );
212 getLog().debug( " generated context file " + sw.toString() );
213 }
214 else
215 {
216 if ( contextReloadable )
217 {
218
219 StringBuilder sb = new StringBuilder( "<Context " ).append( "backgroundProcessorDelay=\"" ).append(
220 Integer.toString( backgroundProcessorDelay ) ).append( "\"" ).append(
221 " reloadable=\"" + Boolean.toString( isContextReloadable() ) + "\"/>" );
222
223 getLog().debug( " generated context file " + sb.toString() );
224 fw = new FileWriter( temporaryContextFile );
225 fw.write( sb.toString() );
226 }
227 else
228 {
229
230 return null;
231 }
232 }
233 }
234 catch ( IOException e )
235 {
236 getLog().error( "error creating fake context.xml : " + e.getMessage(), e );
237 throw new MojoExecutionException( "error creating fake context.xml : " + e.getMessage(), e );
238 }
239 catch ( XmlPullParserException e )
240 {
241 getLog().error( "error creating fake context.xml : " + e.getMessage(), e );
242 throw new MojoExecutionException( "error creating fake context.xml : " + e.getMessage(), e );
243 }
244 catch ( MavenFilteringException e )
245 {
246 getLog().error( "error filtering context.xml : " + e.getMessage(), e );
247 throw new MojoExecutionException( "error filtering context.xml : " + e.getMessage(), e );
248 }
249 finally
250 {
251 IOUtil.close( fw );
252 IOUtil.close( fr );
253 IOUtil.close( sw );
254 }
255
256 return temporaryContextFile;
257 }
258
259
260
261
262
263
264 @Override
265 protected WebappLoader createWebappLoader()
266 throws IOException, MojoExecutionException
267 {
268 WebappLoader loader = super.createWebappLoader();
269
270 if ( useSeparateTomcatClassLoader )
271 {
272 loader.setDelegate( delegate );
273 }
274
275 try
276 {
277 ClassLoaderEntriesCalculatorRequest request =
278 new ClassLoaderEntriesCalculatorRequest().setDependencies( dependencies ).setLog(
279 getLog() ).setMavenProject( project ).setAddWarDependenciesInClassloader(
280 addWarDependenciesInClassloader ).setUseTestClassPath( useTestClasspath );
281 ClassLoaderEntriesCalculatorResult classLoaderEntriesCalculatorResult =
282 classLoaderEntriesCalculator.calculateClassPathEntries( request );
283 List<String> classLoaderEntries = classLoaderEntriesCalculatorResult.getClassPathEntries();
284 final List<File> tmpDirectories = classLoaderEntriesCalculatorResult.getTmpDirectories();
285
286 Runtime.getRuntime().addShutdownHook( new Thread()
287 {
288 @Override
289 public void run()
290 {
291 for ( File tmpDir : tmpDirectories )
292 {
293 try
294 {
295 FileUtils.deleteDirectory( tmpDir );
296 }
297 catch ( IOException e )
298 {
299
300 }
301 }
302 }
303 } );
304
305 if ( classLoaderEntries != null )
306 {
307 for ( String classLoaderEntry : classLoaderEntries )
308 {
309 loader.addRepository( classLoaderEntry );
310 }
311 }
312
313 if ( additionalClasspathDirs != null && !additionalClasspathDirs.isEmpty() )
314 {
315 for ( String additionalClasspathDir : additionalClasspathDirs )
316 {
317 if ( StringUtils.isNotBlank( additionalClasspathDir ) )
318 {
319 File file = new File( additionalClasspathDir );
320 if ( file.exists() )
321 {
322 String fileUri = file.toURI().toString();
323 getLog().debug( "add file:" + fileUri + " as a additionalClasspathDir" );
324 loader.addRepository( fileUri );
325 }
326 }
327 }
328 }
329 }
330 catch ( TomcatRunException e )
331 {
332 throw new MojoExecutionException( e.getMessage(), e );
333 }
334
335 return loader;
336 }
337 }