~ubuntu-branches/ubuntu/precise/tomcat7/precise-updates

« back to all changes in this revision

Viewing changes to java/org/apache/catalina/startup/ContextConfig.java

  • Committer: Bazaar Package Importer
  • Author(s): tony mancill, Miguel Landaeta, tony mancill
  • Date: 2011-06-23 20:26:29 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110623202629-w1v0jejj19swux10
Tags: 7.0.16-1
[ Miguel Landaeta ]
* New upstream release.
* Add missing deps and symlinks for commons-pool ands commons-dbcp jars.

[ tony mancill ]
* Add logrotate file for catalina.out.
* Add build-arch target to debian/rules.

Show diffs side-by-side

added added

removed removed

Lines of Context:
43
43
import java.util.Map;
44
44
import java.util.Properties;
45
45
import java.util.Set;
46
 
import java.util.jar.JarEntry;
47
 
import java.util.jar.JarInputStream;
48
46
 
49
47
import javax.servlet.ServletContainerInitializer;
50
48
import javax.servlet.ServletContext;
92
90
import org.apache.tomcat.util.digester.Digester;
93
91
import org.apache.tomcat.util.digester.RuleSet;
94
92
import org.apache.tomcat.util.res.StringManager;
 
93
import org.apache.tomcat.util.scan.Jar;
 
94
import org.apache.tomcat.util.scan.JarFactory;
95
95
import org.xml.sax.InputSource;
96
96
import org.xml.sax.SAXParseException;
97
97
 
101
101
 *
102
102
 * @author Craig R. McClanahan
103
103
 * @author Jean-Francois Arcand
104
 
 * @version $Id: ContextConfig.java 1095449 2011-04-20 16:19:59Z markt $
 
104
 * @version $Id: ContextConfig.java 1133446 2011-06-08 15:52:26Z markt $
105
105
 */
106
106
 
107
107
public class ContextConfig
1186
1186
     */
1187
1187
    protected void webConfig() {
1188
1188
        WebXml webXml = createWebXml();
 
1189
        /* Anything and everything can override the global and host defaults.
 
1190
         * This is implemented in two parts
 
1191
         * - Handle as a web fragment that gets added after everything else so
 
1192
         *   everything else takes priority
 
1193
         * - Mark Servlets as overridable so SCI configuration can replace
 
1194
         *   configuration from the defaults
 
1195
         */ 
 
1196
        WebXml webXmlDefaultFragment = createWebXml();
 
1197
        webXmlDefaultFragment.setOverridable(true);
 
1198
        // Set to distributable else every app will be prevented from being
 
1199
        // distributable when the default fragment is merged with the main
 
1200
        // web.xml
 
1201
        webXmlDefaultFragment.setDistributable(true);
 
1202
        // When merging, the default welcome files are only used if the app has
 
1203
        // not defined any welcomes files.
 
1204
        webXmlDefaultFragment.setAlwaysAddWelcomeFiles(false);
1189
1205
 
1190
1206
        // Parse global web.xml if present
1191
1207
        InputSource globalWebXml = getGlobalWebXmlSource();
1193
1209
            // This is unusual enough to log
1194
1210
            log.info(sm.getString("contextConfig.defaultMissing"));
1195
1211
        } else {
1196
 
            parseWebXml(globalWebXml, webXml, false);
 
1212
            parseWebXml(globalWebXml, webXmlDefaultFragment, false);
1197
1213
        }
1198
1214
 
1199
1215
        // Parse host level web.xml if present
1200
1216
        // Additive apart from welcome pages
1201
 
        webXml.setReplaceWelcomeFiles(true);
 
1217
        webXmlDefaultFragment.setReplaceWelcomeFiles(true);
1202
1218
        InputSource hostWebXml = getHostWebXmlSource();
1203
 
        parseWebXml(hostWebXml, webXml, false);
 
1219
        parseWebXml(hostWebXml, webXmlDefaultFragment, false);
 
1220
        
 
1221
        Set<WebXml> defaults = new HashSet<WebXml>();
 
1222
        defaults.add(webXmlDefaultFragment);
1204
1223
        
1205
1224
        // Parse context level web.xml
1206
 
        webXml.setReplaceWelcomeFiles(true);
1207
1225
        InputSource contextWebXml = getContextWebXmlSource();
1208
1226
        parseWebXml(contextWebXml, webXml, false);
1209
1227
        
1210
 
        // Assuming 0 is safe for what is required in this case
1211
 
        double webXmlVersion = 0;
1212
 
        if (webXml.getVersion() != null) {
1213
 
            webXmlVersion = Double.parseDouble(webXml.getVersion());
1214
 
        }
1215
 
        
1216
 
        if (webXmlVersion >= 3) {
 
1228
        if (webXml.getMajorVersion() >= 3) {
1217
1229
            // Ordering is important here
1218
1230
 
1219
1231
            // Step 1. Identify all the JARs packaged with the application
1260
1272
                    ok = webXml.merge(orderedFragments);
1261
1273
                }
1262
1274
    
1263
 
                // Step 6.5 Convert explicitly mentioned jsps to servlets
 
1275
                // Step 7. Apply global defaults
 
1276
                // Have to merge defaults before JSP conversion since defaults
 
1277
                // provide JSP servlet definition.
 
1278
                webXml.merge(defaults);
 
1279
 
 
1280
                // Step 8. Convert explicitly mentioned jsps to servlets
1264
1281
                if (!false) {
1265
1282
                    convertJsps(webXml);
1266
1283
                }
1267
 
    
1268
 
                // Step 7. Apply merged web.xml to Context
 
1284
                
 
1285
                // Step 9. Apply merged web.xml to Context
1269
1286
                if (ok) {
1270
1287
                    webXml.configureContext(context);
1271
1288
    
1272
 
                    // Step 7a. Make the merged web.xml available to other
 
1289
                    // Step 9a. Make the merged web.xml available to other
1273
1290
                    // components, specifically Jasper, to save those components
1274
1291
                    // from having to re-generate it.
1275
1292
                    // TODO Use a ServletContainerInitializer for Jasper
1282
1299
                    }
1283
1300
                }
1284
1301
            } else {
 
1302
                webXml.merge(defaults);
1285
1303
                webXml.configureContext(context);
1286
1304
            }
1287
1305
            
1288
1306
            // Always need to look for static resources
1289
 
            // Step 8. Look for static resources packaged in JARs
 
1307
            // Step 10. Look for static resources packaged in JARs
1290
1308
            if (ok) {
1291
1309
                // Spec does not define an order.
1292
1310
                // Use ordered JARs followed by remaining JARs
1309
1327
            // Only look for ServletContainerInitializer if metadata is not
1310
1328
            // complete
1311
1329
            if (!webXml.isMetadataComplete()) {
1312
 
                // Step 9. Apply the ServletContainerInitializer config to the
 
1330
                // Step 11. Apply the ServletContainerInitializer config to the
1313
1331
                // context
1314
1332
                if (ok) {
1315
1333
                    for (Map.Entry<ServletContainerInitializer,
1327
1345
            }
1328
1346
        } else {
1329
1347
            // Apply unmerged web.xml to Context
 
1348
            webXml.merge(defaults);
1330
1349
            convertJsps(webXml);
1331
1350
            webXml.configureContext(context);
1332
1351
        }
1375
1394
        
1376
1395
        for (WebXml fragment : fragments) {
1377
1396
            URL url = fragment.getURL();
1378
 
            JarInputStream jarInputStream = null;
 
1397
            Jar jar = null;
1379
1398
            InputStream is = null;
1380
1399
            ServletContainerInitializer sci = null;
1381
1400
            try {
1382
1401
                if ("jar".equals(url.getProtocol())) {
1383
 
                    JarURLConnection jarConn =
1384
 
                        (JarURLConnection) url.openConnection();
1385
 
                    URL resourceURL = jarConn.getJarFileURL();
1386
 
                    URLConnection resourceConn = resourceURL.openConnection();
1387
 
                    resourceConn.setUseCaches(false);
1388
 
                    
1389
 
                    jarInputStream =
1390
 
                        new JarInputStream(resourceConn.getInputStream());
1391
 
                    JarEntry entry = jarInputStream.getNextJarEntry();
1392
 
                    while (entry != null) {
1393
 
                        if (SCI_LOCATION.equals(entry.getName())) {
1394
 
                            break;
1395
 
                        }
1396
 
                        entry = jarInputStream.getNextJarEntry();
1397
 
                    }
1398
 
                    if (entry != null) {
1399
 
                        is = jarInputStream;
1400
 
                    }
 
1402
                    jar = JarFactory.newInstance(url);
 
1403
                    is = jar.getInputStream(SCI_LOCATION);
1401
1404
                } else if ("file".equals(url.getProtocol())) {
1402
1405
                    String path = url.getPath();
1403
1406
                    File file = new File(path, SCI_LOCATION);
1422
1425
                        // Ignore
1423
1426
                    }
1424
1427
                }
1425
 
                if (jarInputStream != null) {
1426
 
                    try {
1427
 
                        jarInputStream.close();
1428
 
                    } catch (IOException e) {
1429
 
                        // Ignore
1430
 
                    }
 
1428
                if (jar != null) {
 
1429
                    jar.close();
1431
1430
                }
1432
1431
            }
1433
1432
            
1514
1513
    protected void processResourceJARs(Set<WebXml> fragments) {
1515
1514
        for (WebXml fragment : fragments) {
1516
1515
            URL url = fragment.getURL();
1517
 
            JarInputStream jarInputStream = null;
 
1516
            Jar jar = null;
1518
1517
            try {
1519
1518
                // Note: Ignore file URLs for now since only jar URLs will be accepted
1520
1519
                if ("jar".equals(url.getProtocol())) {
1521
 
                    JarURLConnection jarConn =
1522
 
                        (JarURLConnection) url.openConnection();
1523
 
                    URL resourceURL = jarConn.getJarFileURL();
1524
 
                    URLConnection resourceConn = resourceURL.openConnection();
1525
 
                    resourceConn.setUseCaches(false);
1526
 
                    jarInputStream =
1527
 
                        new JarInputStream(resourceConn.getInputStream());
1528
 
                    JarEntry entry = jarInputStream.getNextJarEntry();
1529
 
                    while (entry != null) {
1530
 
                        if ("META-INF/resources/".equals(entry.getName())) {
1531
 
                            break;
1532
 
                        }
1533
 
                        entry = jarInputStream.getNextJarEntry();
1534
 
                    }
1535
 
                    if (entry != null) {
 
1520
                    jar = JarFactory.newInstance(url);
 
1521
                    if (jar.entryExists("META-INF/resources/")) {
1536
1522
                        context.addResourceJarUrl(url);
1537
1523
                    }
1538
1524
                }
1540
1526
                log.error(sm.getString("contextConfig.resourceJarFail", url,
1541
1527
                        context.getName()));
1542
1528
            } finally {
1543
 
                if (jarInputStream != null) {
1544
 
                    try {
1545
 
                        jarInputStream.close();
1546
 
                    } catch (IOException e) {
1547
 
                        // Ignore
1548
 
                    }
 
1529
                if (jar != null) {
 
1530
                    jar.close();
1549
1531
                }
1550
1532
            }
1551
1533
        }
1694
1676
        // thread safe. Whilst there should only be one thread at a time
1695
1677
        // processing a config, play safe and sync.
1696
1678
        Digester digester;
 
1679
        WebRuleSet ruleSet;
1697
1680
        if (fragment) {
1698
1681
            digester = webFragmentDigester;
 
1682
            ruleSet = webFragmentRuleSet;
1699
1683
        } else {
1700
1684
            digester = webDigester;
 
1685
            ruleSet = webRuleSet;
1701
1686
        }
1702
1687
        
1703
 
        synchronized(digester) {
 
1688
        // Sync on the ruleSet since the same ruleSet is shared across all four
 
1689
        // digesters
 
1690
        synchronized(ruleSet) {
1704
1691
            
1705
1692
            digester.push(dest);
1706
1693
            digester.setErrorHandler(handler);
1731
1718
                ok = false;
1732
1719
            } finally {
1733
1720
                digester.reset();
1734
 
                if (fragment) {
1735
 
                    webFragmentRuleSet.recycle();
1736
 
                } else {
1737
 
                    webRuleSet.recycle();
1738
 
                }
 
1721
                ruleSet.recycle();
1739
1722
            }
1740
1723
        }
1741
1724
    }
1800
1783
 
1801
1784
 
1802
1785
    protected void processAnnotationsJar(URL url, WebXml fragment) {
1803
 
        JarInputStream jarInputStream = null;
 
1786
 
 
1787
        Jar jar = null;
 
1788
        InputStream is;
1804
1789
        
1805
1790
        try {
1806
 
            URLConnection urlConn = url.openConnection();
1807
 
            JarURLConnection jarConn;
1808
 
            if (!(urlConn instanceof JarURLConnection)) {
1809
 
                // This should never happen
1810
 
                sm.getString("contextConfig.jarUrl", url);
1811
 
                return;
1812
 
            }
 
1791
            jar = JarFactory.newInstance(url);
1813
1792
            
1814
 
            jarConn = (JarURLConnection) urlConn;
1815
 
            jarConn.setUseCaches(false);
1816
 
            URL resourceURL = jarConn.getJarFileURL();
1817
 
            URLConnection resourceConn = resourceURL.openConnection();
1818
 
 
1819
 
            jarInputStream = new JarInputStream(resourceConn.getInputStream());
1820
 
 
1821
 
            JarEntry entry = jarInputStream.getNextJarEntry();
1822
 
            while (entry != null) {
1823
 
                String entryName = entry.getName();
 
1793
            jar.nextEntry();
 
1794
            String entryName = jar.getEntryName();
 
1795
            while (entryName != null) {
1824
1796
                if (entryName.endsWith(".class")) {
 
1797
                    is = null;
1825
1798
                    try {
1826
 
                        processAnnotationsStream(jarInputStream, fragment);
 
1799
                        is = jar.getEntryInputStream();
 
1800
                        processAnnotationsStream(is, fragment);
1827
1801
                    } catch (IOException e) {
1828
1802
                        log.error(sm.getString("contextConfig.inputStreamJar",
1829
1803
                                entryName, url),e);
 
1804
                    } finally {
 
1805
                        if (is != null) {
 
1806
                            try {
 
1807
                                is.close();
 
1808
                            } catch (IOException ioe) {
 
1809
                                // Ignore
 
1810
                            }
 
1811
                        }
1830
1812
                    }
1831
1813
                }
1832
 
                entry = jarInputStream.getNextJarEntry();
 
1814
                jar.nextEntry();
 
1815
                entryName = jar.getEntryName();
1833
1816
            }
1834
1817
        } catch (IOException e) {
1835
1818
            log.error(sm.getString("contextConfig.jarFile", url), e);
1836
1819
        } finally {
1837
 
            if (jarInputStream != null) {
1838
 
                try {
1839
 
                    jarInputStream.close();
1840
 
                } catch (Throwable t) {
1841
 
                    ExceptionUtils.handleThrowable(t);
1842
 
                }
 
1820
            if (jar != null) {
 
1821
                jar.close();
1843
1822
            }
1844
1823
        }
1845
1824
    }
2317
2296
        @Override
2318
2297
        public void scan(JarURLConnection jarConn) throws IOException {
2319
2298
            
2320
 
            // JarURLConnection#getJarFile() creates temporary copies of the JAR
2321
 
            // if the underlying resource is not a file URL. That can be slow so
2322
 
            // the InputStream for the resource is used
 
2299
            URL url = jarConn.getURL();
2323
2300
            URL resourceURL = jarConn.getJarFileURL();
2324
 
 
2325
 
            JarInputStream jarInputStream = null;
 
2301
            Jar jar = null;
 
2302
            InputStream is = null;
2326
2303
            WebXml fragment = new WebXml();
2327
2304
 
2328
2305
            try {
2329
 
                URLConnection resourceConn = resourceURL.openConnection();
2330
 
                resourceConn.setUseCaches(false);
2331
 
                jarInputStream =
2332
 
                    new JarInputStream(resourceConn.getInputStream());
2333
 
                JarEntry entry = jarInputStream.getNextJarEntry();
2334
 
                while (entry != null) {
2335
 
                    if (FRAGMENT_LOCATION.equals(entry.getName())) {
2336
 
                        break;
2337
 
                    }
2338
 
                    entry = jarInputStream.getNextJarEntry();
2339
 
                }
 
2306
                jar = JarFactory.newInstance(url);
 
2307
                is = jar.getInputStream(FRAGMENT_LOCATION);
2340
2308
 
2341
 
                if (entry == null) {
 
2309
                if (is == null) {
2342
2310
                    // If there is no web.xml, normal JAR no impact on
2343
2311
                    // distributable
2344
2312
                    fragment.setDistributable(true);
2345
2313
                } else {
2346
2314
                    InputSource source = new InputSource(
2347
2315
                            resourceURL.toString() + "!/" + FRAGMENT_LOCATION);
2348
 
                    source.setByteStream(jarInputStream);
 
2316
                    source.setByteStream(is);
2349
2317
                    parseWebXml(source, fragment, true);
2350
2318
                }
2351
2319
            } finally {
2352
 
                if (jarInputStream != null) {
 
2320
                if (is != null) {
2353
2321
                    try {
2354
 
                        jarInputStream.close();
2355
 
                    } catch (Throwable t) {
2356
 
                        ExceptionUtils.handleThrowable(t);
 
2322
                        is.close();
 
2323
                    } catch (IOException ioe) {
 
2324
                        // Ignore
2357
2325
                    }
2358
2326
                }
2359
 
                fragment.setURL(jarConn.getURL());
 
2327
                if (jar != null) {
 
2328
                    jar.close();
 
2329
                }
 
2330
                fragment.setURL(url);
2360
2331
                if (fragment.getName() == null) {
2361
2332
                    fragment.setName(fragment.getURL().toString());
2362
2333
                }