Author: markt
Date: Thu Jul 20 14:13:48 2017
New Revision: 1802490
URL: http://svn.apache.org/viewvc?rev=1802490&view=rev
Log:
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=60963
Add a new WebResourceRoot implementation that extracts JARs to the work
directory for improved performance when deploying packed WAR files.
Added:
tomcat/trunk/java/org/apache/catalina/webresources/ExtractingRoot.java
(with props)
Modified:
tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties
tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java
tomcat/trunk/webapps/docs/changelog.xml
tomcat/trunk/webapps/docs/config/host.xml
tomcat/trunk/webapps/docs/config/resources.xml
Modified: tomcat/trunk/java/org/apache/catalina/core/StandardContext.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/core/StandardContext.java?rev=1802490&r1=1802489&r2=1802490&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/core/StandardContext.java (original)
+++ tomcat/trunk/java/org/apache/catalina/core/StandardContext.java Thu Jul 20
14:13:48 2017
@@ -4864,6 +4864,9 @@ public class StandardContext extends Con
namingResources.start();
}
+ // Post work directory
+ postWorkDirectory();
+
// Add missing components as necessary
if (getResources() == null) { // (1) Required by Loader
if (log.isDebugEnabled())
@@ -4894,9 +4897,6 @@ public class StandardContext extends Con
// Initialize character set mapper
getCharsetMapper();
- // Post work directory
- postWorkDirectory();
-
// Validate required extensions
boolean dependencyCheck = true;
try {
Added: tomcat/trunk/java/org/apache/catalina/webresources/ExtractingRoot.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/ExtractingRoot.java?rev=1802490&view=auto
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/ExtractingRoot.java
(added)
+++ tomcat/trunk/java/org/apache/catalina/webresources/ExtractingRoot.java Thu
Jul 20 14:13:48 2017
@@ -0,0 +1,106 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.catalina.webresources;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.servlet.ServletContext;
+
+import org.apache.catalina.LifecycleException;
+import org.apache.catalina.WebResource;
+import org.apache.catalina.startup.ExpandWar;
+import org.apache.catalina.util.IOTools;
+import org.apache.tomcat.util.res.StringManager;
+
+/**
+ * If the main resources are packaged as a WAR file then any JARs will be
+ * extracted to the work directory and used from there.
+ */
+public class ExtractingRoot extends StandardRoot {
+
+ private static final StringManager sm =
StringManager.getManager(ExtractingRoot.class);
+
+ private static final String APPLICATION_JARS_DIR = "application-jars";
+
+ @Override
+ protected void processWebInfLib() throws LifecycleException {
+
+ // Don't extract JAR files unless the application is deployed as a
+ // packed WAR file.
+ if (!super.isPackedWarFile()) {
+ super.processWebInfLib();
+ return;
+ }
+
+ File expansionTarget = getExpansionTarget();
+ if (!expansionTarget.isDirectory()) {
+ if (!expansionTarget.mkdirs()) {
+ throw new LifecycleException(
+ sm.getString("extractingRoot.targetFailed",
expansionTarget));
+ }
+ }
+
+ WebResource[] possibleJars = listResources("/WEB-INF/lib", false);
+
+ for (WebResource possibleJar : possibleJars) {
+ if (possibleJar.isFile() &&
possibleJar.getName().endsWith(".jar")) {
+ try {
+ File dest = new File(expansionTarget,
possibleJar.getName());
+ dest = dest.getCanonicalFile();
+ try (InputStream sourceStream =
possibleJar.getInputStream();
+ OutputStream destStream= new
FileOutputStream(dest)) {
+ IOTools.flow(sourceStream, destStream);
+ }
+
+ createWebResourceSet(ResourceSetType.CLASSES_JAR,
+ "/WEB-INF/classes", dest.toURI().toURL(), "/");
+ } catch (IOException ioe) {
+ throw new LifecycleException(
+ sm.getString("extractingRoot.jarFailed",
possibleJar.getName()), ioe);
+ }
+ }
+ }
+ }
+
+ private File getExpansionTarget() {
+ File tmpDir = (File)
getContext().getServletContext().getAttribute(ServletContext.TEMPDIR);
+ File expansionTarget = new File(tmpDir, APPLICATION_JARS_DIR);
+ return expansionTarget;
+ }
+
+
+ @Override
+ protected boolean isPackedWarFile() {
+ return false;
+ }
+
+
+ @Override
+ protected void stopInternal() throws LifecycleException {
+ super.stopInternal();
+
+ if (super.isPackedWarFile()) {
+ // Remove the extracted JARs from the work directory
+ File expansionTarget = getExpansionTarget();
+ ExpandWar.delete(expansionTarget);
+ }
+ }
+}
Propchange:
tomcat/trunk/java/org/apache/catalina/webresources/ExtractingRoot.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified:
tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties?rev=1802490&r1=1802489&r2=1802490&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties
(original)
+++ tomcat/trunk/java/org/apache/catalina/webresources/LocalStrings.properties
Thu Jul 20 14:13:48 2017
@@ -32,6 +32,9 @@ dirResourceSet.notDirectory=The director
dirResourceSet.writeExists=The target of the write already exists
dirResourceSet.writeNpe=The input stream may not be null
+extractingRoot.targetFailed=Failed to create the directory [{0}] for extracted
JAR files
+extractingRoot.jarFailed=Failed to extract the JAR file [{0}]
+
fileResource.getCanonicalPathFail=Unable to determine the canonical path for
the resource [{0}]
fileResource.getCreationFail=Unable to determine the creation time for the
resource [{0}]
fileResource.getUrlFail=Unable to determine a URL for the resource [{0}]
Modified: tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java
URL:
http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java?rev=1802490&r1=1802489&r2=1802490&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java
(original)
+++ tomcat/trunk/java/org/apache/catalina/webresources/StandardRoot.java Thu
Jul 20 14:13:48 2017
@@ -344,7 +344,7 @@ public class StandardRoot extends Lifecy
return listResources(path, true);
}
- private WebResource[] listResources(String path, boolean validate) {
+ protected WebResource[] listResources(String path, boolean validate) {
if (validate) {
path = validate(path);
}
@@ -574,8 +574,11 @@ public class StandardRoot extends Lifecy
* the methods that are explicitly defined to return class loader
resources.
* This prevents calls to getResource("/WEB-INF/classes") returning from
one
* or more of the JAR files.
+ *
+ * @throws LifecycleException If an error occurs that should stop the web
+ * application from starting
*/
- private void processWebInfLib() {
+ protected void processWebInfLib() throws LifecycleException {
WebResource[] possibleJars = listResources("/WEB-INF/lib", false);
for (WebResource possibleJar : possibleJars) {
Modified: tomcat/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1802490&r1=1802489&r2=1802490&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/trunk/webapps/docs/changelog.xml Thu Jul 20 14:13:48 2017
@@ -52,6 +52,12 @@
other class loader resources) when the web application is deployed in a
packed WAR file. (markt)
</fix>
+ <fix>
+ <bug>60963</bug>: Add <code>ExtractingRoot</code>, a new
+ <code>WebResourceRoot</code> implementation that extracts JARs to the
+ work directory for improved performance when deploying packed WAR
files.
+ (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Web applications">
Modified: tomcat/trunk/webapps/docs/config/host.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/host.xml?rev=1802490&r1=1802489&r2=1802490&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/host.xml (original)
+++ tomcat/trunk/webapps/docs/config/host.xml Thu Jul 20 14:13:48 2017
@@ -298,7 +298,9 @@
<p>Note: Running with this option set to <code>false</code> will incur
a performance penalty. To avoid a significant performance penalty, the
web application should be configured such that class scanning for
- Servlet 3.0+ pluggability features is not required.</p>
+ Servlet 3.0+ pluggability features is not required. Users may also wish
+ to consider the <strong>ExtractingRoot</strong>
+ <a href="resources.html">Resources</a> implementation.</p>
</attribute>
<attribute name="workDir" required="false">
Modified: tomcat/trunk/webapps/docs/config/resources.xml
URL:
http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/config/resources.xml?rev=1802490&r1=1802489&r2=1802490&view=diff
==============================================================================
--- tomcat/trunk/webapps/docs/config/resources.xml (original)
+++ tomcat/trunk/webapps/docs/config/resources.xml Thu Jul 20 14:13:48 2017
@@ -149,10 +149,28 @@
<subsection name="Standard Implementation">
+ <h3>Standard Root Implementation</h3>
+
<p>The standard implementation of <strong>Resources</strong> is
<strong>org.apache.catalina.webresources.StandardRoot</strong>. It does not
support any additional attributes.</p>
+ <h3>Extracting Root Implementation</h3>
+
+ <p>The extracting implementation of <strong>Resources</strong> is
+ <strong>org.apache.catalina.webresources.ExtractingRoot</strong>. It does
not
+ support any additional attributes.</p>
+
+ <p>When deploying web applications as packed WAR files, the extracting root
+ will extract any JAR files from <code>/WEB-INF/lib</code> to a
+ <code>application-jars</code> directory located in the web
+ application's working directory. These extracted JARs will be removed
+ when the web application stops.</p>
+
+ <p>Extracting JAR files from a packed WAR may provide a performance
+ improvement, particularly at web application start when JAR scanning is
+ required by the application.</p>
+
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]