View | Details | Raw Unified | Return to bug 46264
Collapse All | Expand All

(-)a/java/org/apache/catalina/core/StandardHost.java (+11 lines)
Lines 176-181 public class StandardHost extends ContainerBase implements Host { Link Here
176
      */
176
      */
177
     private Pattern deployIgnore = null;
177
     private Pattern deployIgnore = null;
178
178
179
    private int parallelDeployment;
180
179
181
180
    // ------------------------------------------------------------- Properties
182
    // ------------------------------------------------------------- Properties
181
183
Lines 557-562 public class StandardHost extends ContainerBase implements Host { Link Here
557
                                   deployIgnore);
559
                                   deployIgnore);
558
    }
560
    }
559
561
562
    
563
    public void setParallelDeployment(int count) {
564
        log.info("Using " + count + " threads for deployment.");
565
        parallelDeployment = count;
566
    }
567
    
568
    public int getParallelDeployment() {
569
        return parallelDeployment;
570
    }
560
571
561
    // --------------------------------------------------------- Public Methods
572
    // --------------------------------------------------------- Public Methods
562
573
(-)a/java/org/apache/catalina/startup/HostConfig.java (-25 / +159 lines)
Lines 34-39 import java.util.LinkedHashMap; Link Here
34
import java.util.List;
34
import java.util.List;
35
import java.util.Locale;
35
import java.util.Locale;
36
import java.util.Set;
36
import java.util.Set;
37
import java.util.concurrent.CountDownLatch;
38
import java.util.concurrent.Executor;
39
import java.util.concurrent.ExecutorService;
40
import java.util.concurrent.Executors;
41
import java.util.concurrent.TimeUnit;
37
import java.util.jar.JarEntry;
42
import java.util.jar.JarEntry;
38
import java.util.jar.JarFile;
43
import java.util.jar.JarFile;
39
import java.util.regex.Matcher;
44
import java.util.regex.Matcher;
Lines 166-171 public class HostConfig Link Here
166
     */
171
     */
167
    protected Set<String> invalidWars = new HashSet<String>();
172
    protected Set<String> invalidWars = new HashSet<String>();
168
173
174
    /**
175
     * {@link Executor} to deploy contexts while startup.
176
     */
177
    private ExecutorService deployExecutor;
178
    
169
    // ------------------------------------------------------------- Properties
179
    // ------------------------------------------------------------- Properties
170
180
171
181
Lines 543-563 public class HostConfig Link Here
543
        if (files == null)
553
        if (files == null)
544
            return;
554
            return;
545
        
555
        
546
        for (int i = 0; i < files.length; i++) {
556
        final CountDownLatch deployedLatch = new CountDownLatch(files.length);
547
            File contextXml = new File(configBase, files[i]);
557
        int deployTasks = 0;
558
        
559
        for (final String file: files) {
560
            final File contextXml = new File(configBase, file);
548
561
549
            if (files[i].toLowerCase(Locale.ENGLISH).endsWith(".xml")) {
562
            if (file.toLowerCase(Locale.ENGLISH).endsWith(".xml")) {
550
                ContextName cn = new ContextName(files[i]);
563
                final ContextName cn = new ContextName(file);
551
                String name = cn.getName();
564
                String name = cn.getName();
552
565
553
                if (isServiced(name))
566
                if (isServiced(name))
554
                    continue;
567
                    continue;
555
                
556
                String file = files[i];
557
568
558
                deployDescriptor(cn, contextXml, file);
569
                deployTasks++;
570
                deployExecutor.execute(new Runnable() {
571
572
                    @Override
573
                    public void run() {
574
                        try {
575
                            deployDescriptor(cn, contextXml, file);
576
                        } finally {
577
                            deployedLatch.countDown();
578
                        }
579
                    }
580
    
581
                });
559
            }
582
            }
560
        }
583
        }
584
585
        for (int i=deployTasks; i<files.length; i++) {
586
            deployedLatch.countDown();
587
        }
588
        try {
589
            deployedLatch.await();
590
        } catch (InterruptedException e) {
591
            log.error(sm.getString("hostConfig.awaitDeployIE"), e);
592
        }
561
    }
593
    }
562
594
563
595
Lines 695-728 public class HostConfig Link Here
695
        if (files == null)
727
        if (files == null)
696
            return;
728
            return;
697
        
729
        
698
        for (int i = 0; i < files.length; i++) {
730
        final CountDownLatch deployedLatch = new CountDownLatch(files.length);
731
        int deployTasks = 0;
732
        
733
        for (final String file: files) {
699
            
734
            
700
            if (files[i].equalsIgnoreCase("META-INF"))
735
            if (file.equalsIgnoreCase("META-INF"))
701
                continue;
736
                continue;
702
            if (files[i].equalsIgnoreCase("WEB-INF"))
737
            if (file.equalsIgnoreCase("WEB-INF"))
703
                continue;
738
                continue;
704
            File dir = new File(appBase, files[i]);
705
            if (files[i].toLowerCase(Locale.ENGLISH).endsWith(".war") && dir.isFile()
706
                    && !invalidWars.contains(files[i]) ) {
707
                
739
                
708
                ContextName cn = new ContextName(files[i]);
740
            final File dir = new File(appBase, file);
741
            if (file.toLowerCase(Locale.ENGLISH).endsWith(".war") && dir.isFile()
742
                    && !invalidWars.contains(file) ) {
743
                
744
                final ContextName cn = new ContextName(file);
709
                
745
                
710
                // Check for WARs with /../ /./ or similar sequences in the name
746
                // Check for WARs with /../ /./ or similar sequences in the name
711
                if (!validateContextPath(appBase, cn.getBaseName())) {
747
                if (!validateContextPath(appBase, cn.getBaseName())) {
712
                    log.error(sm.getString(
748
                    log.error(sm.getString(
713
                            "hostConfig.illegalWarName", files[i]));
749
                            "hostConfig.illegalWarName", file));
714
                    invalidWars.add(files[i]);
750
                    invalidWars.add(file);
715
                    continue;
751
                    continue;
716
                }
752
                }
717
753
718
                if (isServiced(cn.getName()))
754
                if (isServiced(cn.getName()))
719
                    continue;
755
                    continue;
720
                
756
                
721
                String file = files[i];
757
                deployTasks++;
758
                deployExecutor.execute(new Runnable() {
759
760
                    @Override
761
                    public void run() {
762
                        try {
763
                            deployWAR(cn, dir, file);
764
                        } finally {
765
                            deployedLatch.countDown();
766
                        }
767
                    }
768
769
                });
722
                
770
                
723
                deployWAR(cn, dir, file);
724
            }
771
            }
725
        }
772
        }
773
774
        for (int i=deployTasks; i<files.length; i++) {
775
            deployedLatch.countDown();
776
        }
777
        try {
778
            deployedLatch.await();
779
        } catch (InterruptedException e) {
780
            log.error(sm.getString("hostConfig.awaitDeployIE"), e);
781
        }
726
    }
782
    }
727
783
728
784
Lines 962-983 public class HostConfig Link Here
962
        if (files == null)
1018
        if (files == null)
963
            return;
1019
            return;
964
        
1020
        
965
        for (int i = 0; i < files.length; i++) {
1021
        final CountDownLatch deployedLatch = new CountDownLatch(files.length);
966
1022
        int deployTasks = 0;
967
            if (files[i].equalsIgnoreCase("META-INF"))
1023
        
1024
        for (final String file: files) {
1025
            if (file.equalsIgnoreCase("META-INF"))
968
                continue;
1026
                continue;
969
            if (files[i].equalsIgnoreCase("WEB-INF"))
1027
            if (file.equalsIgnoreCase("WEB-INF"))
970
                continue;
1028
                continue;
971
            File dir = new File(appBase, files[i]);
1029
            final File dir = new File(appBase, file);
972
            if (dir.isDirectory()) {
1030
            if (dir.isDirectory()) {
973
                ContextName cn = new ContextName(files[i]);
1031
                final ContextName cn = new ContextName(file);
974
1032
975
                if (isServiced(cn.getName()))
1033
                if (isServiced(cn.getName()))
976
                    continue;
1034
                    continue;
1035
             
1036
                deployTasks++;
1037
                deployExecutor.execute(new Runnable() {
977
1038
978
                deployDirectory(cn, dir, files[i]);
1039
                    @Override
1040
                    public void run() {
1041
                        try {
1042
                            deployDirectory(cn, dir, file);
1043
                        } finally {
1044
                            deployedLatch.countDown();
1045
                        }
1046
                    }
1047
                    
1048
                });
979
            }
1049
            }
980
        }
1050
        }
1051
1052
        for (int i=deployTasks; i<files.length; i++) {
1053
            deployedLatch.countDown();
1054
        }
1055
        try {
1056
            deployedLatch.await();
1057
        } catch (InterruptedException e) {
1058
            log.error(sm.getString("hostConfig.awaitDeployIE"), e);
1059
        }
981
    }
1060
    }
982
1061
983
    
1062
    
Lines 1318-1323 public class HostConfig Link Here
1318
            }
1397
            }
1319
        }
1398
        }
1320
1399
1400
        initDeployExecutor();
1401
        
1321
        if (host.getDeployOnStartup())
1402
        if (host.getDeployOnStartup())
1322
            deployApps();
1403
            deployApps();
1323
        
1404
        
Lines 1325-1330 public class HostConfig Link Here
1325
1406
1326
1407
1327
    /**
1408
    /**
1409
     * Initialize executor for deployment.
1410
     */
1411
    private void initDeployExecutor() {
1412
        if (deployExecutor == null) {
1413
            int parallelCount = 0;
1414
            if (host instanceof StandardHost) {
1415
                StandardHost standardHost = (StandardHost) host;
1416
                if (standardHost.getParallelDeployment() > 0) {
1417
                    log.info(sm.getString("hostConfig.parallelDeploymentCount",
1418
                            standardHost.getParallelDeployment()));
1419
                    parallelCount = standardHost.getParallelDeployment();
1420
                }
1421
            }
1422
            if (parallelCount == 0 && System.getProperty("hostConfig.parallelDeployment") != null) {
1423
                int parallelCountProperty = Integer.parseInt(System
1424
                        .getProperty("hostConfig.parallelDeployment"));
1425
                if (parallelCountProperty > 0) {
1426
                    log.info(sm.getString(
1427
                            "hostConfig.parallelDeploymentCount",
1428
                            parallelCountProperty));
1429
                    parallelCount = parallelCountProperty;
1430
                } else {
1431
                    log.info(sm
1432
                            .getString(
1433
                                    "hostConfig.invalidParallelDeploymentCount",
1434
                                    System.getProperty("hostConfig.parallelDeployment")));
1435
                }
1436
            }
1437
            if (parallelCount == 0) {
1438
                parallelCount = Runtime.getRuntime().availableProcessors();
1439
                log.info(sm.getString(
1440
                        "hostConfig.parallelDeploymentCountFromRuntime",
1441
                        parallelCount));
1442
            }
1443
            deployExecutor = Executors.newFixedThreadPool(parallelCount);
1444
        }
1445
    }
1446
1447
    /**
1328
     * Process a "stop" event for this Host.
1448
     * Process a "stop" event for this Host.
1329
     */
1449
     */
1330
    public void stop() {
1450
    public void stop() {
Lines 1342-1347 public class HostConfig Link Here
1342
        oname = null;
1462
        oname = null;
1343
        appBase = null;
1463
        appBase = null;
1344
        configBase = null;
1464
        configBase = null;
1465
        
1466
        if (deployExecutor != null) {
1467
            deployExecutor.shutdown();
1468
            try {
1469
                if (!deployExecutor.awaitTermination(1, TimeUnit.MINUTES)) 
1470
                    log.warn(sm.getString("hostConfig.awaitDeployExecutorShutdownFailed"));
1471
            } catch (InterruptedException e) {
1472
                log.error(
1473
                        sm.getString("hostConfig.awaitDeployExecutorShutdownIE"),
1474
                        e);
1475
            }
1476
        }
1345
1477
1346
    }
1478
    }
1347
1479
Lines 1359-1364 public class HostConfig Link Here
1359
                if (!isServiced(apps[i].name))
1491
                if (!isServiced(apps[i].name))
1360
                    checkResources(apps[i]);
1492
                    checkResources(apps[i]);
1361
            }
1493
            }
1494
            
1495
            initDeployExecutor();
1362
            // Hotdeploy applications
1496
            // Hotdeploy applications
1363
            deployApps();
1497
            deployApps();
1364
        }
1498
        }
(-)a/java/org/apache/catalina/startup/LocalStrings.properties (+6 lines)
Lines 73-78 expandWar.copy=Error copying {0} to {1} Link Here
73
expandWar.deleteFailed=[{0}] could not be completely deleted. The presence of the remaining files may cause problems
73
expandWar.deleteFailed=[{0}] could not be completely deleted. The presence of the remaining files may cause problems
74
expandWar.illegalPath=The archive [{0}] is malformed and will be ignored: an entry contains an illegal path [{1}] which was not expanded to [{2}] since that is outside of the defined docBase [{3}]
74
expandWar.illegalPath=The archive [{0}] is malformed and will be ignored: an entry contains an illegal path [{1}] which was not expanded to [{2}] since that is outside of the defined docBase [{3}]
75
hostConfig.appBase=Application base directory {0} does not exist
75
hostConfig.appBase=Application base directory {0} does not exist
76
hostConfig.awaitDeployIE=Interrupted while waiting for contexts to be deployed
77
hostConfig.awaitDeployExecutorShutdownFailed=Error while waiting for deployment executor to shutdown
78
hostConfig.awaitDeployExecutorShutdownIE=Interrupted while waiting for deployment executor to shutdown
76
hostConfig.canonicalizing=Error delete redeploy resources from context [{0}]
79
hostConfig.canonicalizing=Error delete redeploy resources from context [{0}]
77
hostConfig.cce=Lifecycle event data object {0} is not a Host
80
hostConfig.cce=Lifecycle event data object {0} is not a Host
78
hostConfig.context.remove=Error while removing context [{0}]
81
hostConfig.context.remove=Error while removing context [{0}]
Lines 93-100 hostConfig.expand.error=Exception while expanding web application archive {0} Link Here
93
hostConfig.expanding=Expanding discovered web application archives
96
hostConfig.expanding=Expanding discovered web application archives
94
hostConfig.ignorePath=Ignoring path [{0}] in appBase for automatic deployment
97
hostConfig.ignorePath=Ignoring path [{0}] in appBase for automatic deployment
95
hostConfig.illegalWarName=The war name [{0}] is invalid. The archive will be ignored.
98
hostConfig.illegalWarName=The war name [{0}] is invalid. The archive will be ignored.
99
hostConfig.invalidParallelDeploymentCount=Invalid number of threads: [{0}]
96
hostConfig.jmx.register=Register context [{0}] failed
100
hostConfig.jmx.register=Register context [{0}] failed
97
hostConfig.jmx.unregister=Unregister context [{0}] failed
101
hostConfig.jmx.unregister=Unregister context [{0}] failed
102
hostConfig.parallelDeploymentCount=Start fixed executor for deployment with [{0}] parallel threads
103
hostConfig.parallelDeploymentCountFromRuntime=Start fixed executor for deployment with [{0}] parallel threads as given by Runtime
98
hostConfig.reload=Reloading context [{0}]
104
hostConfig.reload=Reloading context [{0}]
99
hostConfig.removeXML=Context [{0}] is undeployed
105
hostConfig.removeXML=Context [{0}] is undeployed
100
hostConfig.removeDIR=Directory {0} is undeployed
106
hostConfig.removeDIR=Directory {0} is undeployed

Return to bug 46264