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
23 import org.apache.catalina.Context;
24 import org.apache.catalina.Engine;
25 import org.apache.catalina.Host;
26 import org.apache.catalina.LifecycleException;
27 import org.apache.catalina.Wrapper;
28 import org.apache.catalina.connector.Connector;
29 import org.apache.catalina.loader.WebappLoader;
30 import org.apache.catalina.realm.MemoryRealm;
31 import org.apache.catalina.servlets.DefaultServlet;
32 import org.apache.catalina.startup.Catalina;
33 import org.apache.catalina.startup.Embedded;
34 import org.apache.maven.artifact.Artifact;
35 import org.apache.maven.artifact.factory.ArtifactFactory;
36 import org.apache.maven.artifact.repository.ArtifactRepository;
37 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
38 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
39 import org.apache.maven.artifact.resolver.ArtifactResolver;
40 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
41 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
42 import org.apache.maven.artifact.versioning.VersionRange;
43 import org.apache.maven.execution.MavenSession;
44 import org.apache.maven.plugin.MojoExecutionException;
45 import org.apache.maven.plugin.MojoFailureException;
46 import org.apache.maven.plugins.annotations.Component;
47 import org.apache.maven.plugins.annotations.Parameter;
48 import org.apache.maven.project.MavenProject;
49 import org.apache.maven.shared.filtering.MavenFileFilter;
50 import org.apache.maven.shared.filtering.MavenFileFilterRequest;
51 import org.apache.maven.shared.filtering.MavenFilteringException;
52 import org.apache.tomcat.maven.common.config.AbstractWebapp;
53 import org.apache.tomcat.maven.common.run.EmbeddedRegistry;
54 import org.codehaus.plexus.archiver.ArchiverException;
55 import org.codehaus.plexus.archiver.UnArchiver;
56 import org.codehaus.plexus.archiver.manager.ArchiverManager;
57 import org.codehaus.plexus.archiver.manager.NoSuchArchiverException;
58 import org.codehaus.plexus.classworlds.ClassWorld;
59 import org.codehaus.plexus.classworlds.realm.ClassRealm;
60 import org.codehaus.plexus.classworlds.realm.DuplicateRealmException;
61 import org.codehaus.plexus.util.DirectoryScanner;
62 import org.codehaus.plexus.util.FileUtils;
63 import org.codehaus.plexus.util.StringUtils;
64 import org.w3c.dom.Document;
65 import org.w3c.dom.NamedNodeMap;
66 import org.w3c.dom.Node;
67 import org.xml.sax.SAXException;
68
69 import javax.xml.parsers.DocumentBuilder;
70 import javax.xml.parsers.DocumentBuilderFactory;
71 import javax.xml.parsers.ParserConfigurationException;
72 import java.io.File;
73 import java.io.FileNotFoundException;
74 import java.io.IOException;
75 import java.net.InetAddress;
76 import java.net.MalformedURLException;
77 import java.net.URL;
78 import java.util.ArrayList;
79 import java.util.Collection;
80 import java.util.Collections;
81 import java.util.List;
82 import java.util.Map;
83 import java.util.Set;
84
85
86
87
88
89
90
91 public abstract class AbstractRunMojo
92 extends AbstractI18NTomcat6Mojo
93 {
94
95
96
97
98
99
100
101 @Component( role = ArtifactFactory.class )
102 protected ArtifactFactory artifactFactory;
103
104
105
106
107 @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
108 private ArtifactRepository artifactRepository;
109
110
111
112
113 @Component( role = ArtifactResolver.class )
114 protected ArtifactResolver artifactResolver;
115
116
117
118
119
120
121
122
123 @Parameter( defaultValue = "${project.packaging}", required = true, readonly = true )
124 private String packaging;
125
126
127
128
129 @Parameter( defaultValue = "${project.build.directory}/tomcat" )
130 private File configurationDir;
131
132
133
134
135 @Parameter( property = "maven.tomcat.port", defaultValue = "8080" )
136 private int port;
137
138
139
140
141
142
143 @Parameter( property = "maven.tomcat.address")
144 private String address;
145
146
147
148
149
150
151
152
153 @Parameter( property = "maven.tomcat.ajp.port", defaultValue = "0" )
154 private int ajpPort;
155
156
157
158
159
160
161
162
163 @Parameter( property = "maven.tomcat.ajp.protocol", defaultValue = "ajp" )
164 private String ajpProtocol;
165
166
167
168
169
170
171
172
173 @Parameter( property = "maven.tomcat.httpsPort", defaultValue = "0" )
174 private int httpsPort;
175
176
177
178
179
180
181 @Parameter( property = "maven.tomcat.uriEncoding", defaultValue = "ISO-8859-1" )
182 private String uriEncoding;
183
184
185
186
187
188
189 @Parameter
190 private Map<String, String> systemProperties;
191
192
193
194
195
196
197 @Parameter( property = "maven.tomcat.additionalConfigFilesDir", defaultValue = "${basedir}/src/main/tomcatconf" )
198 private File additionalConfigFilesDir;
199
200
201
202
203
204
205 @Parameter( property = "maven.tomcat.serverXml" )
206 private File serverXml;
207
208
209
210
211
212
213
214 @Parameter( property = "maven.tomcat.webXml" )
215 private File tomcatWebXml;
216
217
218
219
220
221
222
223 @Parameter( property = "maven.tomcat.fork", defaultValue = "false" )
224 private boolean fork;
225
226
227
228
229
230
231
232
233
234
235
236
237
238 @Parameter( property = "maven.tomcat.addContextWarDependencies", defaultValue = "false" )
239 private boolean addContextWarDependencies;
240
241
242
243
244
245
246 @Component
247 protected MavenProject project;
248
249
250
251
252
253
254 @Component( role = ArchiverManager.class )
255 private ArchiverManager archiverManager;
256
257
258
259
260
261
262 @Parameter( property = "tomcat.useSeparateTomcatClassLoader", defaultValue = "false" )
263 protected boolean useSeparateTomcatClassLoader;
264
265
266
267
268 @Parameter( defaultValue = "${plugin.artifacts}", required = true )
269 private List<Artifact> pluginArtifacts;
270
271
272
273
274
275
276 @Parameter( property = "tomcat.ignorePackaging", defaultValue = "false" )
277 private boolean ignorePackaging;
278
279
280
281
282
283
284 @Parameter
285 private String keystoreFile;
286
287
288
289
290
291
292 @Parameter
293 private String keystorePass;
294
295
296
297
298
299
300 @Parameter( defaultValue = "JKS" )
301 private String keystoreType;
302
303
304
305
306
307
308 @Parameter
309 private String truststoreFile;
310
311
312
313
314
315
316 @Parameter
317 private String truststorePass;
318
319
320
321
322
323
324 @Parameter
325 private String truststoreType;
326
327
328
329
330
331
332 @Parameter
333 private String truststoreProvider;
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349 @Parameter( property = "maven.tomcat.useNaming", defaultValue = "true" )
350 private boolean useNaming;
351
352
353
354
355
356
357
358
359 @Parameter( property = "maven.tomcat.contextReloadable", defaultValue = "false" )
360 protected boolean contextReloadable;
361
362
363
364
365
366
367 @Parameter( property = "maven.tomcat.backgroundProcessorDelay", defaultValue = "-1" )
368 protected int backgroundProcessorDelay = -1;
369
370
371
372
373 @Parameter( defaultValue = "src/main/webapp/META-INF/context.xml" )
374 protected File contextFile;
375
376
377
378
379
380
381
382
383
384 @Parameter( property = "maven.tomcat.protocol", defaultValue = "HTTP/1.1" )
385 private String protocol;
386
387
388
389
390 @Parameter( property = "maven.tomcat.tomcatUsers.file" )
391 private File tomcatUsers;
392
393
394
395
396
397
398 @Parameter
399 private File managerWarPath;
400
401
402
403
404
405
406
407 @Parameter( property = "maven.tomcat.skip", defaultValue = "false" )
408 protected boolean skip;
409
410
411
412
413
414 @Parameter
415 private List<Webapp> webapps;
416
417
418
419
420
421
422 @Parameter( property = "maven.tomcat.hostName", defaultValue = "localhost" )
423 protected String hostName;
424
425
426
427
428
429
430
431 @Parameter
432 protected String[] aliases;
433
434
435
436
437
438
439
440
441 private ClassRealm tomcatRealm;
442
443
444
445
446
447
448 @Parameter( property = "maven.tomcat.staticContextPath", defaultValue = "/" )
449 private String staticContextPath;
450
451
452
453
454
455
456
457 @Parameter( property = "maven.tomcat.staticContextDocbase" )
458 private String staticContextDocbase;
459
460
461
462
463
464
465 @Parameter
466 protected String classLoaderClass;
467
468
469
470
471 @Parameter( property = "maven.tomcat.useBodyEncodingForURI", defaultValue = "false" )
472 protected boolean useBodyEncodingForURI;
473
474 @Parameter( defaultValue = "${session}", readonly = true, required = true )
475 protected MavenSession session;
476
477 @Component( role = MavenFileFilter.class, hint = "default" )
478 protected MavenFileFilter mavenFileFilter;
479
480
481
482
483
484
485
486
487 public void execute()
488 throws MojoExecutionException, MojoFailureException
489 {
490 if ( skip )
491 {
492 getLog().info( "skip execution" );
493 return;
494 }
495
496 if ( !isWar() && !addContextWarDependencies && getAdditionalWebapps().isEmpty() )
497 {
498 getLog().info( messagesProvider.getMessage( "AbstractRunMojo.nonWar" ) );
499 return;
500 }
501 ClassLoader originalClassLoader = null;
502 try
503 {
504
505 if ( useSeparateTomcatClassLoader )
506 {
507 originalClassLoader = Thread.currentThread().getContextClassLoader();
508 }
509 getLog().info( messagesProvider.getMessage( "AbstractRunMojo.runningWar", getWebappUrl() ) );
510
511 initConfiguration();
512 startContainer();
513 if ( !fork )
514 {
515 waitIndefinitely();
516 }
517 }
518 catch ( LifecycleException exception )
519 {
520 throw new MojoExecutionException( messagesProvider.getMessage( "AbstractRunMojo.cannotStart" ), exception );
521 }
522 catch ( IOException exception )
523 {
524 throw new MojoExecutionException(
525 messagesProvider.getMessage( "AbstractRunMojo.cannotCreateConfiguration" ), exception );
526 }
527 catch ( MavenFilteringException e )
528 {
529 throw new MojoExecutionException( "filtering issue: " + e.getMessage(), e );
530 }
531 finally
532 {
533 if ( useSeparateTomcatClassLoader )
534 {
535 Thread.currentThread().setContextClassLoader( originalClassLoader );
536 }
537 }
538 }
539
540
541
542
543
544
545
546
547
548
549 protected String getPath()
550 {
551 return path;
552 }
553
554
555
556
557
558
559
560
561
562 protected Context createContext( Embedded container )
563 throws IOException, MojoExecutionException
564 {
565 String contextPath = getPath();
566 Context context =
567 container.createContext( "/".equals( contextPath ) ? "" : contextPath, getDocBase().getAbsolutePath() );
568
569 if ( useSeparateTomcatClassLoader )
570 {
571 context.setParentClassLoader( getTomcatClassLoader() );
572 }
573
574 final WebappLoader webappLoader = createWebappLoader();
575
576 if ( classLoaderClass != null )
577 {
578 webappLoader.setLoaderClass( classLoaderClass );
579 }
580
581 context.setLoader( webappLoader );
582 File contextFile = getContextFile();
583 if ( contextFile != null )
584 {
585 context.setConfigFile( getContextFile().getAbsolutePath() );
586 }
587 return context;
588 }
589
590
591
592
593
594
595
596
597 protected WebappLoader createWebappLoader()
598 throws IOException, MojoExecutionException
599 {
600 if ( useSeparateTomcatClassLoader )
601 {
602 return ( isContextReloadable() )
603 ? new ExternalRepositoriesReloadableWebappLoader( getTomcatClassLoader(), getLog() )
604 : new WebappLoader( getTomcatClassLoader() );
605 }
606
607 return ( isContextReloadable() )
608 ? new ExternalRepositoriesReloadableWebappLoader( Thread.currentThread().getContextClassLoader(), getLog() )
609 : new WebappLoader( Thread.currentThread().getContextClassLoader() );
610 }
611
612
613
614
615
616
617 protected boolean isContextReloadable()
618 throws MojoExecutionException
619 {
620 if ( contextReloadable || backgroundProcessorDelay > 0 )
621 {
622 return true;
623 }
624
625 boolean reloadable = false;
626 try
627 {
628 if ( contextFile != null && contextFile.exists() )
629 {
630 DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
631 DocumentBuilder builder = builderFactory.newDocumentBuilder();
632 Document contextDoc = builder.parse( contextFile );
633 contextDoc.getDocumentElement().normalize();
634
635 NamedNodeMap nodeMap = contextDoc.getDocumentElement().getAttributes();
636 Node reloadableAttribute = nodeMap.getNamedItem( "reloadable" );
637
638 reloadable =
639 ( reloadableAttribute != null ) ? Boolean.valueOf( reloadableAttribute.getNodeValue() ) : false;
640 }
641 getLog().debug( "context reloadable: " + reloadable );
642 }
643 catch ( IOException ioe )
644 {
645 getLog().error( "Could not parse file: [" + contextFile.getAbsolutePath() + "]", ioe );
646 }
647 catch ( ParserConfigurationException pce )
648 {
649 getLog().error( "Could not configure XML parser", pce );
650 }
651 catch ( SAXException se )
652 {
653 getLog().error( "Could not parse file: [" + contextFile.getAbsolutePath() + "]", se );
654 }
655
656 return reloadable;
657 }
658
659
660
661
662
663
664
665 protected abstract File getDocBase();
666
667
668
669
670
671
672 protected abstract File getContextFile()
673 throws MojoExecutionException;
674
675
676
677
678
679
680
681
682
683
684 protected boolean isWar()
685 {
686 return "war".equals( packaging ) || ignorePackaging;
687 }
688
689
690
691
692
693
694
695 private URL getWebappUrl()
696 throws MalformedURLException
697 {
698 return new URL( "http", "localhost", port, getPath() );
699 }
700
701
702
703
704
705
706
707 private void initConfiguration()
708 throws IOException, MojoExecutionException, MavenFilteringException
709 {
710 if ( configurationDir.exists() )
711 {
712 getLog().info( messagesProvider.getMessage( "AbstractRunMojo.usingConfiguration", configurationDir ) );
713 }
714 else
715 {
716 getLog().info( messagesProvider.getMessage( "AbstractRunMojo.creatingConfiguration", configurationDir ) );
717
718 configurationDir.mkdirs();
719
720 File confDir = new File( configurationDir, "conf" );
721 confDir.mkdir();
722
723 copyFile( "/conf/tomcat-users.xml", new File( confDir, "tomcat-users.xml" ) );
724
725 if ( tomcatWebXml != null )
726 {
727 if ( !tomcatWebXml.exists() )
728 {
729 throw new MojoExecutionException( " tomcatWebXml " + tomcatWebXml.getPath() + " not exists" );
730 }
731
732 FileUtils.copyFile( tomcatWebXml, new File( confDir, "web.xml" ) );
733
734 MavenFileFilterRequest mavenFileFilterRequest = new MavenFileFilterRequest();
735 mavenFileFilterRequest.setFrom( tomcatWebXml );
736 mavenFileFilterRequest.setTo( new File( confDir, "web.xml" ) );
737 mavenFileFilterRequest.setMavenProject( project );
738 mavenFileFilterRequest.setMavenSession( session );
739 mavenFileFilterRequest.setFiltering( true );
740
741 mavenFileFilter.copyFile( mavenFileFilterRequest );
742 }
743 else
744 {
745 copyFile( "/conf/web.xml", new File( confDir, "web.xml" ) );
746 }
747
748 File logDir = new File( configurationDir, "logs" );
749 logDir.mkdir();
750
751 File webappsDir = new File( configurationDir, "webapps" );
752 webappsDir.mkdir();
753 if ( managerWarPath != null && managerWarPath.exists() )
754 {
755 FileUtils.copyFileToDirectory( managerWarPath, webappsDir );
756 }
757
758 if ( additionalConfigFilesDir != null && additionalConfigFilesDir.exists() )
759 {
760 DirectoryScanner scanner = new DirectoryScanner();
761 scanner.addDefaultExcludes();
762 scanner.setBasedir( additionalConfigFilesDir.getPath() );
763 scanner.scan();
764
765 String[] files = scanner.getIncludedFiles();
766
767 if ( files != null && files.length > 0 )
768 {
769 getLog().info( "Coping additional tomcat config files" );
770
771 for ( int i = 0; i < files.length; i++ )
772 {
773 File file = new File( additionalConfigFilesDir, files[i] );
774
775 getLog().info( " copy " + file.getName() );
776
777 FileUtils.copyFileToDirectory( file, confDir );
778 }
779 }
780 }
781 }
782 }
783
784
785
786
787
788
789
790
791 private void copyFile( String fromPath, File toFile )
792 throws IOException
793 {
794 URL fromURL = getClass().getResource( fromPath );
795
796 if ( fromURL == null )
797 {
798 throw new FileNotFoundException( fromPath );
799 }
800
801 FileUtils.copyURLToFile( fromURL, toFile );
802 }
803
804
805
806
807
808
809
810
811 private void startContainer()
812 throws IOException, LifecycleException, MojoExecutionException
813 {
814 String previousCatalinaBase = System.getProperty( "catalina.base" );
815
816 try
817 {
818
819
820 setupSystemProperties();
821
822 System.setProperty( "catalina.base", configurationDir.getAbsolutePath() );
823 System.setProperty( "catalina.home", configurationDir.getAbsolutePath() );
824
825 File catalinaPolicy = new File( configurationDir, "conf/catalina.policy" );
826
827 if ( catalinaPolicy.exists() )
828 {
829
830 System.setProperty( "java.security.policy", catalinaPolicy.getAbsolutePath() );
831 }
832
833 final Embedded container;
834 if ( serverXml != null )
835 {
836 if ( !serverXml.exists() )
837 {
838 throw new MojoExecutionException( serverXml.getPath() + " not exists" );
839 }
840
841 container = new Catalina();
842 container.setCatalinaHome( configurationDir.getAbsolutePath() );
843 container.setCatalinaBase( configurationDir.getAbsolutePath() );
844 ( (Catalina) container ).setConfigFile( serverXml.getPath() );
845 ( (Catalina) container ).setRedirectStreams( true );
846 ( (Catalina) container ).setUseNaming( this.useNaming );
847
848 container.start();
849 }
850 else
851 {
852
853 container = new Embedded();
854 container.setCatalinaHome( configurationDir.getAbsolutePath() );
855 MemoryRealm memoryRealm = new MemoryRealm();
856
857 if ( tomcatUsers != null )
858 {
859 if ( !tomcatUsers.exists() )
860 {
861 throw new MojoExecutionException( " tomcatUsers " + tomcatUsers.getPath() + " not exists" );
862 }
863 getLog().info( "use tomcat-users.xml from " + tomcatUsers.getAbsolutePath() );
864 memoryRealm.setPathname( tomcatUsers.getAbsolutePath() );
865
866 }
867
868 container.setRealm( memoryRealm );
869 container.setUseNaming( useNaming );
870
871
872
873
874 Context context = createContext( container );
875
876
877 String appBase = new File( configurationDir, "webapps" ).getAbsolutePath();
878 Host host = container.createHost( "localHost", appBase );
879
880 if ( hostName != null )
881 {
882 host.setName( hostName );
883 }
884 if ( aliases != null )
885 {
886 for ( String alias : aliases )
887 {
888 host.addAlias( alias );
889 }
890 }
891
892 host.addChild( context );
893 createStaticContext( container, context, host );
894 if ( addContextWarDependencies || !getAdditionalWebapps().isEmpty() )
895 {
896 Collection<Context> dependencyContexts = createDependencyContexts( container );
897 for ( Context extraContext : dependencyContexts )
898 {
899 host.addChild( extraContext );
900 }
901 }
902
903
904 Engine engine = container.createEngine();
905 engine.setName( "localEngine-" + port );
906 engine.addChild( host );
907 engine.setDefaultHost( host.getName() );
908 container.addEngine( engine );
909
910 getLog().debug( "start tomcat instance on http port:" + port + " and protocol: " + protocol );
911
912
913 Connector httpConnector = container.createConnector( (InetAddress) null, port, protocol );
914 if ( httpsPort > 0 )
915 {
916 httpConnector.setRedirectPort( httpsPort );
917 }
918 httpConnector.setURIEncoding( uriEncoding );
919 httpConnector.setUseBodyEncodingForURI( this.useBodyEncodingForURI );
920
921 if ( address != null)
922 {
923 httpConnector.setAttribute( "address", address );
924 }
925
926 container.addConnector( httpConnector );
927
928
929 if ( httpsPort > 0 )
930 {
931 Connector httpsConnector = container.createConnector( (InetAddress) null, httpsPort, true );
932 httpsConnector.setSecure( true );
933 httpsConnector.setProperty( "SSLEnabled", "true" );
934
935 httpsConnector.setProperty( "sslProtocol", "TLS" );
936 if ( keystoreFile != null )
937 {
938 httpsConnector.setAttribute( "keystoreFile", keystoreFile );
939 }
940 if ( keystorePass != null )
941 {
942 httpsConnector.setAttribute( "keystorePass", keystorePass );
943 }
944 if ( keystoreType != null )
945 {
946 httpsConnector.setAttribute( "keystoreType", keystoreType );
947 }
948
949 if ( truststoreFile != null )
950 {
951 httpsConnector.setAttribute( "truststoreFile", truststoreFile );
952 }
953
954 if ( truststorePass != null )
955 {
956 httpsConnector.setAttribute( "truststorePass", truststorePass );
957 }
958
959 if ( truststoreType != null )
960 {
961 httpsConnector.setAttribute( "truststoreType", truststoreType );
962 }
963
964 if ( truststoreProvider != null )
965 {
966 httpsConnector.setAttribute( "truststoreProvider", truststoreProvider );
967 }
968
969 httpsConnector.setUseBodyEncodingForURI( this.useBodyEncodingForURI );
970
971 if ( address != null)
972 {
973 httpsConnector.setAttribute( "address", address );
974 }
975
976 container.addConnector( httpsConnector );
977
978 }
979
980
981 if ( ajpPort > 0 )
982 {
983 Connector ajpConnector = container.createConnector( (InetAddress) null, ajpPort, ajpProtocol );
984 ajpConnector.setURIEncoding( uriEncoding );
985 ajpConnector.setUseBodyEncodingForURI( this.useBodyEncodingForURI );
986 if ( address != null)
987 {
988 ajpConnector.setAttribute( "address", address );
989 }
990 container.addConnector( ajpConnector );
991 }
992 if ( useSeparateTomcatClassLoader )
993 {
994 Thread.currentThread().setContextClassLoader( getTomcatClassLoader() );
995 engine.setParentClassLoader( getTomcatClassLoader() );
996 }
997 container.start();
998 }
999
1000 EmbeddedRegistry.getInstance().register( container );
1001 }
1002 finally
1003 {
1004 if ( previousCatalinaBase != null )
1005 {
1006 System.setProperty( "catalina.base", previousCatalinaBase );
1007 }
1008 }
1009 }
1010
1011 private List<Webapp> getAdditionalWebapps()
1012 {
1013 if ( webapps == null )
1014 {
1015 return Collections.emptyList();
1016 }
1017 return webapps;
1018 }
1019
1020 protected ClassRealm getTomcatClassLoader()
1021 throws MojoExecutionException
1022 {
1023 if ( this.tomcatRealm != null )
1024 {
1025 return tomcatRealm;
1026 }
1027 try
1028 {
1029 ClassWorld world = new ClassWorld();
1030 ClassRealm root = world.newRealm( "tomcat", Thread.currentThread().getContextClassLoader() );
1031
1032 for ( Artifact pluginArtifact : pluginArtifacts )
1033 {
1034
1035 if ( pluginArtifact.getFile() != null )
1036 {
1037 root.addURL( pluginArtifact.getFile().toURI().toURL() );
1038 }
1039
1040 }
1041 tomcatRealm = root;
1042 return root;
1043 }
1044 catch ( DuplicateRealmException e )
1045 {
1046 throw new MojoExecutionException( e.getMessage(), e );
1047 }
1048 catch ( MalformedURLException e )
1049 {
1050 throw new MojoExecutionException( e.getMessage(), e );
1051 }
1052 }
1053
1054 @SuppressWarnings( "unchecked" )
1055 public Set<Artifact> getProjectArtifacts()
1056 {
1057 return project.getArtifacts();
1058 }
1059
1060
1061
1062
1063 private void waitIndefinitely()
1064 {
1065 Object lock = new Object();
1066
1067 synchronized ( lock )
1068 {
1069 try
1070 {
1071 lock.wait();
1072 }
1073 catch ( InterruptedException exception )
1074 {
1075 getLog().warn( messagesProvider.getMessage( "AbstractRunMojo.interrupted" ), exception );
1076 }
1077 }
1078 }
1079
1080
1081
1082
1083
1084 private void setupSystemProperties()
1085 {
1086 if ( systemProperties != null && !systemProperties.isEmpty() )
1087 {
1088 getLog().info( "setting SystemProperties:" );
1089
1090 for ( String key : systemProperties.keySet() )
1091 {
1092 String value = systemProperties.get( key );
1093
1094 if ( value != null )
1095 {
1096 getLog().info( " " + key + "=" + value );
1097 System.setProperty( key, value );
1098 }
1099 else
1100 {
1101 getLog().info( "skip sysProps " + key + " with empty value" );
1102 }
1103 }
1104 }
1105 }
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115 private Collection<Context> createDependencyContexts( Embedded container )
1116 throws MojoExecutionException
1117 {
1118 getLog().info( "Deploying dependency wars" );
1119
1120 List<Context> contexts = new ArrayList<Context>();
1121
1122 ScopeArtifactFilter filter = new ScopeArtifactFilter( "tomcat" );
1123 @SuppressWarnings( "unchecked" ) Set<Artifact> artifacts = project.getArtifacts();
1124 for ( Artifact artifact : artifacts )
1125 {
1126
1127
1128 if ( "war".equals( artifact.getType() ) && !artifact.isOptional() && filter.include( artifact ) )
1129 {
1130 addContextFromArtifact( container, contexts, artifact, "/" + artifact.getArtifactId(), null );
1131 }
1132 }
1133
1134 for ( AbstractWebapp additionalWebapp : getAdditionalWebapps() )
1135 {
1136 String contextPath = additionalWebapp.getContextPath();
1137 if ( !contextPath.startsWith( "/" ) )
1138 {
1139 contextPath = "/" + contextPath;
1140 }
1141 addContextFromArtifact( container, contexts, getArtifact( additionalWebapp ), contextPath,
1142 additionalWebapp.getContextFile() );
1143 }
1144 return contexts;
1145 }
1146
1147
1148 private void addContextFromArtifact( Embedded container, List<Context> contexts, Artifact artifact,
1149 String contextPath, File contextXml )
1150 throws MojoExecutionException
1151 {
1152 getLog().info( "Deploy warfile: " + String.valueOf( artifact.getFile() ) + " to contextPath: " + contextPath );
1153 File webapps = new File( configurationDir, "webapps" );
1154 File artifactWarDir = new File( webapps, artifact.getArtifactId() );
1155 if ( !artifactWarDir.exists() )
1156 {
1157
1158 artifactWarDir.mkdir();
1159 try
1160 {
1161 UnArchiver unArchiver = archiverManager.getUnArchiver( "zip" );
1162 unArchiver.setSourceFile( artifact.getFile() );
1163 unArchiver.setDestDirectory( artifactWarDir );
1164
1165
1166 unArchiver.extract();
1167 }
1168 catch ( NoSuchArchiverException e )
1169 {
1170 getLog().error( e );
1171 return;
1172 }
1173 catch ( ArchiverException e )
1174 {
1175 getLog().error( e );
1176 return;
1177 }
1178 }
1179 WebappLoader webappLoader = new WebappLoader( Thread.currentThread().getContextClassLoader() );
1180 Context context = container.createContext( contextPath, artifactWarDir.getAbsolutePath() );
1181 context.setLoader( webappLoader );
1182
1183 File contextFile = contextXml != null ? contextXml : getContextFile();
1184 if ( contextFile != null )
1185 {
1186 context.setConfigFile( contextFile.getAbsolutePath() );
1187 }
1188 contexts.add( context );
1189 }
1190
1191
1192 private void createStaticContext( final Embedded container, Context context, Host host )
1193 {
1194 if ( staticContextDocbase != null )
1195 {
1196 Context staticContext = container.createContext( staticContextPath, staticContextDocbase );
1197 staticContext.setPrivileged( true );
1198 Wrapper servlet = context.createWrapper();
1199 servlet.setServletClass( DefaultServlet.class.getName() );
1200 servlet.setName( "staticContent" );
1201 staticContext.addChild( servlet );
1202 staticContext.addServletMapping( "/", "staticContent" );
1203 host.addChild( staticContext );
1204 }
1205 }
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216 protected Artifact getArtifact( AbstractWebapp additionalWebapp )
1217 throws MojoExecutionException
1218 {
1219
1220 Artifact artifact;
1221 VersionRange vr;
1222 try
1223 {
1224 vr = VersionRange.createFromVersionSpec( additionalWebapp.getVersion() );
1225 }
1226 catch ( InvalidVersionSpecificationException e )
1227 {
1228 getLog().warn( "fail to create versionRange from version: " + additionalWebapp.getVersion(), e );
1229 vr = VersionRange.createFromVersion( additionalWebapp.getVersion() );
1230 }
1231
1232 if ( StringUtils.isEmpty( additionalWebapp.getClassifier() ) )
1233 {
1234 artifact = artifactFactory.createDependencyArtifact( additionalWebapp.getGroupId(),
1235 additionalWebapp.getArtifactId(), vr,
1236 additionalWebapp.getType(), null,
1237 Artifact.SCOPE_COMPILE );
1238 }
1239 else
1240 {
1241 artifact = artifactFactory.createDependencyArtifact( additionalWebapp.getGroupId(),
1242 additionalWebapp.getArtifactId(), vr,
1243 additionalWebapp.getType(),
1244 additionalWebapp.getClassifier(),
1245 Artifact.SCOPE_COMPILE );
1246 }
1247
1248 try
1249 {
1250 artifactResolver.resolve( artifact, project.getRemoteArtifactRepositories(), this.artifactRepository );
1251 }
1252 catch ( ArtifactResolutionException e )
1253 {
1254 throw new MojoExecutionException( "Unable to resolve artifact.", e );
1255 }
1256 catch ( ArtifactNotFoundException e )
1257 {
1258 throw new MojoExecutionException( "Unable to find artifact.", e );
1259 }
1260
1261 return artifact;
1262 }
1263 }