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

(-)java/org/apache/catalina/core/ContainerBase.java (-6 lines)
Lines 794-811 Link Here
794
794
795
            // Start child
795
            // Start child
796
            if (started && startChildren && (child instanceof Lifecycle)) {
796
            if (started && startChildren && (child instanceof Lifecycle)) {
797
                boolean success = false;
798
                try {
797
                try {
799
                    ((Lifecycle) child).start();
798
                    ((Lifecycle) child).start();
800
                    success = true;
801
                } catch (LifecycleException e) {
799
                } catch (LifecycleException e) {
802
                    log.error("ContainerBase.addChild: start: ", e);
800
                    log.error("ContainerBase.addChild: start: ", e);
803
                    throw new IllegalStateException
801
                    throw new IllegalStateException
804
                        ("ContainerBase.addChild: start: " + e);
802
                        ("ContainerBase.addChild: start: " + e);
805
                } finally {
806
                    if (!success) {
807
                        children.remove(child.getName());
808
                    }
809
                }
803
                }
810
            }
804
            }
811
805
(-)java/org/apache/catalina/startup/HostConfig.java (-134 / +222 lines)
Lines 31-36 Link Here
31
import java.util.HashSet;
31
import java.util.HashSet;
32
import java.util.LinkedHashMap;
32
import java.util.LinkedHashMap;
33
import java.util.List;
33
import java.util.List;
34
import java.util.Locale;
34
import java.util.Set;
35
import java.util.Set;
35
import java.util.jar.JarEntry;
36
import java.util.jar.JarEntry;
36
import java.util.jar.JarFile;
37
import java.util.jar.JarFile;
Lines 548-571 Link Here
548
     */
549
     */
549
    protected void deployApps(String name) {
550
    protected void deployApps(String name) {
550
551
551
        File appBase = appBase();
552
        File configBase = configBase();
553
        String baseName = getConfigFile(name);
552
        String baseName = getConfigFile(name);
554
        String docBase = getDocBase(name);
553
        String docBase = getDocBase(name);
555
        
554
556
        // Deploy XML descriptors from configBase
555
        // Deploy XML descriptor from configBase
557
        File xml = new File(configBase, baseName + ".xml");
556
        deployDescriptor(baseName + ".xml", false);
558
        if (xml.exists())
557
        // Deploy WAR
559
            deployDescriptor(name, xml, baseName + ".xml");
558
        deployWAR(docBase + ".war", false);
560
        // Deploy WARs, and loop if additional descriptors are found
559
        // Deploy expanded folder
561
        File war = new File(appBase, docBase + ".war");
560
        deployDirectory(docBase, false);
562
        if (war.exists())
563
            deployWAR(name, war, docBase + ".war");
564
        // Deploy expanded folders
565
        File dir = new File(appBase, docBase);
566
        if (dir.exists())
567
            deployDirectory(name, dir, docBase);
568
        
569
    }
561
    }
570
562
571
563
Lines 578-609 Link Here
578
            return;
570
            return;
579
        
571
        
580
        for (int i = 0; i < files.length; i++) {
572
        for (int i = 0; i < files.length; i++) {
573
            deployDescriptor(files[i], true);
574
        }
581
575
582
            if (files[i].equalsIgnoreCase("META-INF"))
576
    }
583
                continue;
584
            if (files[i].equalsIgnoreCase("WEB-INF"))
585
                continue;
586
            File contextXml = new File(configBase, files[i]);
587
            if (files[i].toLowerCase().endsWith(".xml")) {
588
577
589
                // Calculate the context path and make sure it is unique
590
                String nameTmp = files[i].substring(0, files[i].length() - 4);
591
                String contextPath = "/" + nameTmp.replace('#', '/');
592
                if (nameTmp.equals("ROOT")) {
593
                    contextPath = "";
594
                }
595
578
596
                if (isServiced(contextPath))
579
    /**
597
                    continue;
580
     * 
598
                
581
     * @param file
599
                String file = files[i];
582
     *            Filename of the file in our configBase. If it is not a ".xml"
600
583
     *            file, this call is ignored.
601
                deployDescriptor(contextPath, contextXml, file);
584
     * @param checkServiced
602
                
585
     *            If <code>true</code>, deployment will not be allowed while
603
            }
586
     *            context is serviced.
604
587
     */
588
    private void deployDescriptor(String file, boolean checkServiced) {
589
        if (file.length() <= 4 || file.equalsIgnoreCase("META-INF")
590
                || file.equalsIgnoreCase("WEB-INF")) {
591
            return;
605
        }
592
        }
606
593
        String extention = file.substring(file.length() - 4).toLowerCase(
594
                Locale.ENGLISH);
595
        if (!extention.equals(".xml")) {
596
            return;
597
        }
598
        File appBase = appBase();
599
        // Calculate the context path and make sure it is unique
600
        String contextPath = getContextPathFromFileName(appBase, file, 4);
601
        if (contextPath == null) {
602
            return;
603
        }
604
        if (checkServiced && isServiced(contextPath)) {
605
            return;
606
        }
607
        File contextXml = new File(configBase(), file);
608
        if (!contextXml.isFile()) {
609
            return;
610
        }
611
        deployDescriptor(contextPath, contextXml, file);
607
    }
612
    }
608
613
609
614
Lines 618-623 Link Here
618
        }
623
        }
619
        
624
        
620
        DeployedApplication deployedApp = new DeployedApplication(contextPath);
625
        DeployedApplication deployedApp = new DeployedApplication(contextPath);
626
        boolean success = false;
621
627
622
        // Assume this is a configuration descriptor and deploy it
628
        // Assume this is a configuration descriptor and deploy it
623
        if(log.isInfoEnabled()) {
629
        if(log.isInfoEnabled()) {
Lines 725-738 Link Here
725
                        (contextXml.getAbsolutePath(), new Long(contextXml.lastModified()));
731
                        (contextXml.getAbsolutePath(), new Long(contextXml.lastModified()));
726
                }
732
                }
727
            }
733
            }
734
            if (context != null && host.findChild(context.getName()) != null) {
735
                deployed.put(contextPath, deployedApp);
736
                success = true;
737
            }
728
        } catch (Throwable t) {
738
        } catch (Throwable t) {
729
            log.error(sm.getString("hostConfig.deployDescriptor.error",
739
            log.error(sm.getString("hostConfig.deployDescriptor.error",
730
                                   file), t);
740
                                   file), t);
741
        } finally {
742
            if (!success) {
743
                deployedApp = new DeployedApplication(contextPath);
744
                deployedApp.redeployResources.put(
745
                        contextXml.getAbsolutePath(),
746
                        new Long(contextXml.lastModified()));
747
                deployed.put(contextPath, deployedApp);
748
            }
731
        }
749
        }
732
733
        if (context != null && host.findChild(context.getName()) != null) {
734
            deployed.put(contextPath, deployedApp);
735
        }
736
    }
750
    }
737
751
738
752
Lines 740-786 Link Here
740
     * Deploy WAR files.
754
     * Deploy WAR files.
741
     */
755
     */
742
    protected void deployWARs(File appBase, String[] files) {
756
    protected void deployWARs(File appBase, String[] files) {
743
        
757
744
        if (files == null)
758
        if (files == null)
745
            return;
759
            return;
746
        
760
747
        for (int i = 0; i < files.length; i++) {
761
        for (int i = 0; i < files.length; i++) {
748
            
762
            deployWAR(files[i], true);
749
            if (files[i].equalsIgnoreCase("META-INF"))
763
        }
750
                continue;
751
            if (files[i].equalsIgnoreCase("WEB-INF"))
752
                continue;
753
            File dir = new File(appBase, files[i]);
754
            if (files[i].toLowerCase().endsWith(".war") && dir.isFile()
755
                    && !invalidWars.contains(files[i]) ) {
756
                
757
                // Calculate the context path and make sure it is unique
758
                String contextPath = "/" + files[i].replace('#','/');
759
                int period = contextPath.lastIndexOf(".");
760
                contextPath = contextPath.substring(0, period);
761
                
762
                // Check for WARs with /../ /./ or similar sequences in the name
763
                if (!validateContextPath(appBase, contextPath)) {
764
                    log.error(sm.getString(
765
                            "hostConfig.illegalWarName", files[i]));
766
                    invalidWars.add(files[i]);
767
                    continue;
768
                }
769
764
770
                if (contextPath.equals("/ROOT"))
765
    }
771
                    contextPath = "";
766
772
                
767
773
                if (isServiced(contextPath))
768
    /**
774
                    continue;
769
     * Calculates contextPath from the name of a file.
775
                
770
     * 
776
                String file = files[i];
771
     * @param fileName
777
                
772
     *            File name, without path.
778
                deployWAR(contextPath, dir, file);
773
     * @param extensionSize
779
                
774
     *            Size of filename extension. Either 0 or 4.
775
     * @return Context path, or <code>null</code> if filename is invalidþ
776
     */
777
    private String getContextPathFromFileName(File appbase, String fileName,
778
            int extensionSize) {
779
        if (extensionSize > 0) {
780
            if (fileName.length() < extensionSize) {
781
                return null;
780
            }
782
            }
781
            
783
            fileName = fileName.substring(0, fileName.length() - extensionSize);
782
        }
784
        }
783
        
785
        if (fileName.equals("ROOT")) {
786
            return "";
787
        }
788
        String warName = fileName + ".war";
789
        if (invalidWars.contains(warName)) {
790
            return null;
791
        }
792
        String contextPath = "/" + fileName.replace('#', '/');
793
        // Check for WARs with /../ /./ or similar sequences in the name
794
        if (!validateContextPath(appBase, contextPath)) {
795
            log.error(sm.getString("hostConfig.illegalWarName", fileName));
796
            invalidWars.add(warName);
797
            return null;
798
        }
799
        return contextPath;
784
    }
800
    }
785
801
786
802
Lines 821-826 Link Here
821
    }
837
    }
822
838
823
    /**
839
    /**
840
     * 
841
     * @param file
842
     *            Filename of the file in our appBase. If it is not a ".war"
843
     *            file, this call is ignored.
844
     * @param checkServiced
845
     *            If <code>true</code>, deployment will not be allowed while
846
     *            context is serviced.
847
     */
848
    private void deployWAR(String file, boolean checkServiced) {
849
        if (file.length() <= 4 || file.equalsIgnoreCase("META-INF")
850
                || file.equalsIgnoreCase("WEB-INF")) {
851
            return;
852
        }
853
        String extention = file.substring(file.length() - 4).toLowerCase(
854
                Locale.ENGLISH);
855
        if (!extention.equals(".war")) {
856
            return;
857
        }
858
        File appBase = appBase();
859
        // Calculate the context path and make sure it is unique
860
        String contextPath = getContextPathFromFileName(appBase, file, 4);
861
        if (contextPath == null) {
862
            return;
863
        }
864
        if (checkServiced && isServiced(contextPath)) {
865
            return;
866
        }
867
        File war = new File(appBase(), file);
868
        if (!war.isFile()) {
869
            return;
870
        }
871
        deployWAR(contextPath, war, file);
872
    }
873
874
875
    /**
824
     * @param contextPath
876
     * @param contextPath
825
     * @param war
877
     * @param war
826
     * @param file
878
     * @param file
Lines 898-904 Link Here
898
        }
950
        }
899
        
951
        
900
        DeployedApplication deployedApp = new DeployedApplication(contextPath);
952
        DeployedApplication deployedApp = new DeployedApplication(contextPath);
901
        
953
        boolean success = false;
954
902
        // Deploy the application in this WAR file
955
        // Deploy the application in this WAR file
903
        if(log.isInfoEnabled()) 
956
        if(log.isInfoEnabled()) 
904
            log.info(sm.getString("hostConfig.deployJar", file));
957
            log.info(sm.getString("hostConfig.deployJar", file));
Lines 966-976 Link Here
966
            } else {
1019
            } else {
967
                addWatchedResources(deployedApp, null, context);
1020
                addWatchedResources(deployedApp, null, context);
968
            }
1021
            }
1022
            deployed.put(contextPath, deployedApp);
1023
            success = true;
969
        } catch (Throwable t) {
1024
        } catch (Throwable t) {
970
            log.error(sm.getString("hostConfig.deployJar.error", file), t);
1025
            log.error(sm.getString("hostConfig.deployJar.error", file), t);
1026
        } finally {
1027
            if (!success) {
1028
                deployedApp = new DeployedApplication(contextPath);
1029
                deployedApp.redeployResources.put(war.getAbsolutePath(), new Long(
1030
                        war.lastModified()));
1031
                deployed.put(contextPath, deployedApp);
1032
            }
971
        }
1033
        }
972
        
973
        deployed.put(contextPath, deployedApp);
974
    }
1034
    }
975
1035
976
1036
Lines 983-1010 Link Here
983
            return;
1043
            return;
984
        
1044
        
985
        for (int i = 0; i < files.length; i++) {
1045
        for (int i = 0; i < files.length; i++) {
1046
            deployDirectory(files[i], true);
1047
        }
986
1048
987
            if (files[i].equalsIgnoreCase("META-INF"))
1049
    }
988
                continue;
989
            if (files[i].equalsIgnoreCase("WEB-INF"))
990
                continue;
991
            File dir = new File(appBase, files[i]);
992
            if (dir.isDirectory()) {
993
1050
994
                // Calculate the context path and make sure it is unique
995
                String contextPath = "/" + files[i].replace('#','/');
996
                if (files[i].equals("ROOT"))
997
                    contextPath = "";
998
1051
999
                if (isServiced(contextPath))
1052
    /**
1000
                    continue;
1053
     * 
1001
1054
     * @param file
1002
                deployDirectory(contextPath, dir, files[i]);
1055
     *            Filename of the directory in our appBase.
1003
            
1056
     * @param checkServiced
1004
            }
1057
     *            If <code>true</code>, deployment will not be allowed while
1005
1058
     *            context is serviced.
1059
     */
1060
    private void deployDirectory(String file, boolean checkServiced) {
1061
        if (file.equalsIgnoreCase("META-INF") || file.equalsIgnoreCase("WEB-INF")) {
1062
            return;
1006
        }
1063
        }
1007
1064
        File appBase = appBase();
1065
        // Calculate the context path and make sure it is unique
1066
        String contextPath = getContextPathFromFileName(appBase, file, 0);
1067
        if (contextPath == null) {
1068
            return;
1069
        }
1070
        if (checkServiced && isServiced(contextPath)) {
1071
            return;
1072
        }
1073
        File dir = new File(appBase, file);
1074
        if (!dir.isDirectory()) {
1075
            return;
1076
        }
1077
        deployDirectory(contextPath, dir, file);
1008
    }
1078
    }
1009
1079
1010
    
1080
    
Lines 1014-1024 Link Here
1014
     * @param file
1084
     * @param file
1015
     */
1085
     */
1016
    protected void deployDirectory(String contextPath, File dir, String file) {
1086
    protected void deployDirectory(String contextPath, File dir, String file) {
1017
        DeployedApplication deployedApp = new DeployedApplication(contextPath);
1018
        
1019
        if (deploymentExists(contextPath))
1087
        if (deploymentExists(contextPath))
1020
            return;
1088
            return;
1021
1089
1090
        DeployedApplication deployedApp = new DeployedApplication(contextPath);
1091
        boolean success = false;
1092
1022
        // Deploy the application in this directory
1093
        // Deploy the application in this directory
1023
        if( log.isInfoEnabled() ) 
1094
        if( log.isInfoEnabled() ) 
1024
            log.info(sm.getString("hostConfig.deployDir", file));
1095
            log.info(sm.getString("hostConfig.deployDir", file));
Lines 1084-1094 Link Here
1084
                (xmlCopy.getAbsolutePath(), new Long(xmlCopy.lastModified()));
1155
                (xmlCopy.getAbsolutePath(), new Long(xmlCopy.lastModified()));
1085
            }
1156
            }
1086
            addWatchedResources(deployedApp, dir.getAbsolutePath(), context);
1157
            addWatchedResources(deployedApp, dir.getAbsolutePath(), context);
1158
            deployed.put(contextPath, deployedApp);
1159
            success = true;
1087
        } catch (Throwable t) {
1160
        } catch (Throwable t) {
1088
            log.error(sm.getString("hostConfig.deployDir.error", file), t);
1161
            log.error(sm.getString("hostConfig.deployDir.error", file), t);
1162
        } finally {
1163
            if (!success) {
1164
                deployedApp = new DeployedApplication(contextPath);
1165
                deployedApp.redeployResources.put(dir.getAbsolutePath(), new Long(
1166
                        dir.lastModified()));
1167
                deployed.put(contextPath, deployedApp);
1168
            }
1089
        }
1169
        }
1090
1091
        deployed.put(contextPath, deployedApp);
1092
    }
1170
    }
1093
1171
1094
    
1172
    
Lines 1155-1172 Link Here
1155
                    if (log.isInfoEnabled())
1233
                    if (log.isInfoEnabled())
1156
                        log.info(sm.getString("hostConfig.undeploy", app.name));
1234
                        log.info(sm.getString("hostConfig.undeploy", app.name));
1157
                    ContainerBase context = (ContainerBase) host.findChild(app.name);
1235
                    ContainerBase context = (ContainerBase) host.findChild(app.name);
1158
                    try {
1236
                    if (context != null) {
1159
                        host.removeChild(context);
1237
                        try {
1160
                    } catch (Throwable t) {
1238
                            host.removeChild(context);
1161
                        log.warn(sm.getString
1239
                        } catch (Throwable t) {
1162
                                 ("hostConfig.context.remove", app.name), t);
1240
                            log.warn(sm.getString
1241
                                     ("hostConfig.context.remove", app.name), t);
1242
                        }
1243
                        try {
1244
                            context.destroy();
1245
                        } catch (Throwable t) {
1246
                            log.warn(sm.getString
1247
                                     ("hostConfig.context.destroy", app.name), t);
1248
                        }
1163
                    }
1249
                    }
1164
                    try {
1165
                        context.destroy();
1166
                    } catch (Throwable t) {
1167
                        log.warn(sm.getString
1168
                                 ("hostConfig.context.destroy", app.name), t);
1169
                    }
1170
                    // Delete other redeploy resources
1250
                    // Delete other redeploy resources
1171
                    for (int j = i + 1; j < resources.length; j++) {
1251
                    for (int j = i + 1; j < resources.length; j++) {
1172
                        try {
1252
                        try {
Lines 1208-1221 Link Here
1208
                if (log.isInfoEnabled())
1288
                if (log.isInfoEnabled())
1209
                    log.info(sm.getString("hostConfig.undeploy", app.name));
1289
                    log.info(sm.getString("hostConfig.undeploy", app.name));
1210
                ContainerBase context = (ContainerBase) host.findChild(app.name);
1290
                ContainerBase context = (ContainerBase) host.findChild(app.name);
1211
                try {
1212
                    host.removeChild(context);
1213
                } catch (Throwable t) {
1214
                    log.warn(sm.getString
1215
                             ("hostConfig.context.remove", app.name), t);
1216
                }
1217
                if (context != null) {
1291
                if (context != null) {
1218
                    try {
1292
                    try {
1293
                        host.removeChild(context);
1294
                    } catch (Throwable t) {
1295
                        log.warn(sm.getString
1296
                                 ("hostConfig.context.remove", app.name), t);
1297
                    }
1298
                    try {
1219
                        context.destroy();
1299
                        context.destroy();
1220
                    } catch (Throwable t) {
1300
                    } catch (Throwable t) {
1221
                        log.warn(sm.getString
1301
                        log.warn(sm.getString
Lines 1272-1291 Link Here
1272
                if(log.isInfoEnabled())
1352
                if(log.isInfoEnabled())
1273
                    log.info(sm.getString("hostConfig.reload", app.name));
1353
                    log.info(sm.getString("hostConfig.reload", app.name));
1274
                Container context = host.findChild(app.name);
1354
                Container context = host.findChild(app.name);
1275
                try {
1355
                if (context != null) {
1276
                    ((Lifecycle) context).stop();
1356
                    try {
1277
                } catch (Exception e) {
1357
                        ((Lifecycle) context).stop();
1278
                    log.warn(sm.getString
1358
                    } catch (Exception e) {
1279
                             ("hostConfig.context.restart", app.name), e);
1359
                        log.warn(sm.getString
1360
                                 ("hostConfig.context.restart", app.name), e);
1361
                    }
1362
                    // If the context was not started (for example an error 
1363
                    // in web.xml) we'll still get to try to start
1364
                    try {
1365
                        ((Lifecycle) context).start();
1366
                    } catch (Exception e) {
1367
                        log.warn(sm.getString
1368
                                 ("hostConfig.context.restart", app.name), e);
1369
                    }
1280
                }
1370
                }
1281
                // If the context was not started (for example an error 
1282
                // in web.xml) we'll still get to try to start
1283
                try {
1284
                    ((Lifecycle) context).start();
1285
                } catch (Exception e) {
1286
                    log.warn(sm.getString
1287
                             ("hostConfig.context.restart", app.name), e);
1288
                }
1289
                // Update times
1371
                // Update times
1290
                app.reloadResources.put(resources[i], new Long(resource.lastModified()));
1372
                app.reloadResources.put(resources[i], new Long(resource.lastModified()));
1291
                app.timestamp = System.currentTimeMillis();
1373
                app.timestamp = System.currentTimeMillis();
Lines 1356-1362 Link Here
1356
            (DeployedApplication[]) deployed.values().toArray(new DeployedApplication[0]);
1438
            (DeployedApplication[]) deployed.values().toArray(new DeployedApplication[0]);
1357
        for (int i = 0; i < apps.length; i++) {
1439
        for (int i = 0; i < apps.length; i++) {
1358
            try {
1440
            try {
1359
                host.removeChild(host.findChild(apps[i].name));
1441
                Container context = host.findChild(apps[i].name);
1442
                if (context != null) {
1443
                    host.removeChild(context);
1444
                }
1360
            } catch (Throwable t) {
1445
            } catch (Throwable t) {
1361
                log.warn(sm.getString
1446
                log.warn(sm.getString
1362
                        ("hostConfig.context.remove", apps[i].name), t);
1447
                        ("hostConfig.context.remove", apps[i].name), t);
Lines 1461-1467 Link Here
1461
    public void unmanageApp(String contextPath) {
1546
    public void unmanageApp(String contextPath) {
1462
        if(isServiced(contextPath)) {
1547
        if(isServiced(contextPath)) {
1463
            deployed.remove(contextPath);
1548
            deployed.remove(contextPath);
1464
            host.removeChild(host.findChild(contextPath));
1549
            Container context = host.findChild(contextPath);
1550
            if (context != null) {
1551
                host.removeChild(host.findChild(contextPath));
1552
            }
1465
        }
1553
        }
1466
    }
1554
    }
1467
1555

Return to bug 54007