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