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.PROCESS_CLASSES )
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 @Component( role = ClassLoaderEntriesCalculator.class )
95 private ClassLoaderEntriesCalculator classLoaderEntriesCalculator;
96
97
98
99
100
101
102 @Parameter( property = "maven.tomcat.addWarDependenciesInClassloader", defaultValue = "true" )
103 private boolean addWarDependenciesInClassloader;
104
105
106
107
108
109
110 @Parameter( property = "maven.tomcat.useTestClasspath", defaultValue = "false" )
111 private boolean useTestClasspath;
112
113
114
115
116
117
118 @Parameter( alias = "additionalClassesDirs" )
119 private List<String> additionalClasspathDirs;
120
121
122
123
124
125
126
127
128
129
130 @Override
131 protected Context createContext( Embedded container )
132 throws IOException, MojoExecutionException
133 {
134 Context context = super.createContext( container );
135
136 context.setReloadable( isContextReloadable() );
137
138 return context;
139 }
140
141
142
143
144
145
146 @Override
147 protected WebappLoader createWebappLoader()
148 throws IOException, MojoExecutionException
149 {
150 WebappLoader loader = super.createWebappLoader();
151 if ( useSeparateTomcatClassLoader )
152 {
153 loader.setDelegate( delegate );
154 }
155
156 try
157 {
158 ClassLoaderEntriesCalculatorRequest request =
159 new ClassLoaderEntriesCalculatorRequest().setDependencies( dependencies ).setLog(
160 getLog() ).setMavenProject( project ).setAddWarDependenciesInClassloader(
161 addWarDependenciesInClassloader ).setUseTestClassPath( useTestClasspath );
162 ClassLoaderEntriesCalculatorResult classLoaderEntriesCalculatorResult =
163 classLoaderEntriesCalculator.calculateClassPathEntries( request );
164 List<String> classLoaderEntries = classLoaderEntriesCalculatorResult.getClassPathEntries();
165 final List<File> tmpDirectories = classLoaderEntriesCalculatorResult.getTmpDirectories();
166
167 Runtime.getRuntime().addShutdownHook( new Thread()
168 {
169 @Override
170 public void run()
171 {
172 for ( File tmpDir : tmpDirectories )
173 {
174 try
175 {
176 FileUtils.deleteDirectory( tmpDir );
177 }
178 catch ( IOException e )
179 {
180
181 }
182 }
183 }
184 } );
185
186 if ( classLoaderEntries != null )
187 {
188 for ( String classLoaderEntry : classLoaderEntries )
189 {
190 loader.addRepository( classLoaderEntry );
191 }
192 }
193 if ( additionalClasspathDirs != null && !additionalClasspathDirs.isEmpty() )
194 {
195 for ( String additionalClasspathDir : additionalClasspathDirs )
196 {
197 if ( StringUtils.isNotBlank( additionalClasspathDir ) )
198 {
199 File file = new File( additionalClasspathDir );
200 if ( file.exists() )
201 {
202 String fileUri = file.toURI().toString();
203 getLog().debug( "add file:" + fileUri + " as a additionalClasspathDir" );
204 loader.addRepository( fileUri );
205 }
206 }
207 }
208 }
209 }
210 catch ( TomcatRunException e )
211 {
212 throw new MojoExecutionException( e.getMessage(), e );
213 }
214
215 return loader;
216 }
217
218
219
220
221
222 @Override
223 protected File getDocBase()
224 {
225 return warSourceDirectory;
226 }
227
228
229
230
231 @Override
232 protected File getContextFile()
233 throws MojoExecutionException
234 {
235 File temporaryContextFile = null;
236
237
238
239
240
241
242 FileReader fr = null;
243 FileWriter fw = null;
244 StringWriter sw = new StringWriter();
245 try
246 {
247 temporaryContextFile = File.createTempFile( "tomcat-maven-plugin", "temp-ctx-file" );
248 temporaryContextFile.deleteOnExit();
249 fw = new FileWriter( temporaryContextFile );
250
251 if ( contextFile != null && contextFile.exists() )
252 {
253 fr = new FileReader( contextFile );
254 Xpp3Dom xpp3Dom = Xpp3DomBuilder.build( fr );
255 xpp3Dom.setAttribute( "backgroundProcessorDelay", Integer.toString( backgroundProcessorDelay ) );
256 xpp3Dom.setAttribute( "reloadable", Boolean.toString( isContextReloadable() ) );
257 Xpp3DomWriter.write( fw, xpp3Dom );
258 Xpp3DomWriter.write( sw, xpp3Dom );
259 getLog().debug( " generated context file " + sw.toString() );
260 }
261 else
262 {
263 if ( contextReloadable )
264 {
265
266 StringBuilder sb = new StringBuilder( "<Context " ).append( "backgroundProcessorDelay=\"" ).append(
267 Integer.toString( backgroundProcessorDelay ) ).append( "\"" ).append(
268 " reloadable=\"" + Boolean.toString( isContextReloadable() ) + "\"/>" );
269
270 getLog().debug( " generated context file " + sb.toString() );
271
272 fw.write( sb.toString() );
273 }
274 else
275 {
276
277 return null;
278 }
279 }
280 }
281 catch ( IOException e )
282 {
283 getLog().error( "error creating fake context.xml : " + e.getMessage(), e );
284 throw new MojoExecutionException( "error creating fake context.xml : " + e.getMessage(), e );
285 }
286 catch ( XmlPullParserException e )
287 {
288 getLog().error( "error creating fake context.xml : " + e.getMessage(), e );
289 throw new MojoExecutionException( "error creating fake context.xml : " + e.getMessage(), e );
290 }
291 finally
292 {
293 IOUtil.close( fw );
294 IOUtil.close( fr );
295 IOUtil.close( sw );
296 }
297
298 return temporaryContextFile;
299 }
300
301 }