Commit f1c4aca7 authored by Emmanuel Bourg's avatar Emmanuel Bourg

Imported Upstream version 8.0.8

parent d83103e9
......@@ -45,35 +45,30 @@ source distribution, do the following:
Note regarding later versions of Java:
As documented elsewhere, one of components in Apache Tomcat includes
a private copy of the Apache Commons DBCP library. The source code
for this library is downloaded, processed by the build script
(renaming the packages) and compiled.
a private copy of the Apache Commons DBCP library.
Due to changes in JDBC interfaces implemented by the library between
versions of Java SE specification, the library has to target specific
version of Java and can be compiled only with the JDK version
implementing this version of specification.
The JDBC interfaces implemented by DBCP frequently change in non-backwards
compatible ways between versions of the Java SE specification. Therefore,
it is likely that DBCP will only compile with the specific version of Java
listed above and that compilation will fail if a later version of Java is
used.
See Apache Commons DBCP project web site for more details on
available versions of the library and its requirements,
http://commons.apache.org/dbcp/
If you really want to use a later version of JDK to build Tomcat,
several workarounds are possible. One of them is to skip building
the component (tomcat-dbcp.jar).
3. Install the JDK according to the instructions included with the release.
4. Set an environment variable JAVA_HOME to the pathname of the directory
into which you installed the JDK release.
(2) Install Apache Ant 1.8.x on your computer
(2) Install Apache Ant version 1.8.2 or later on your computer
1. If Apache Ant 1.8.x is already installed on your computer, skip to (3).
1. If Apache Ant version 1.8.2 or later is already installed on your computer, skip to (3).
2. Download a binary distribution of Ant 1.8.x from:
2. Download a binary distribution of Ant from:
http://ant.apache.org/bindownload.cgi
......@@ -352,7 +347,13 @@ For example:
(7.3) Other configuration options
1. It is possible to enable generation of access log file when the tests
1. It is possible to configure the directory where JUnit reports are
written to. It is configured by "test.reports" property. The default
value is
output/build/logs
2. It is possible to enable generation of access log file when the tests
are run. This is off by default and can be enabled by the following
property:
......@@ -363,7 +364,7 @@ For example:
output/build/logs
2. The testsuite respects logging configuration as configured by
3. The testsuite respects logging configuration as configured by
${tomcat.source}/conf/logging.properties
The log files will be written to the temporary directory used by the
......@@ -371,17 +372,24 @@ For example:
output/test-tmp/logs
3. It is possible to configure formatter used by JUnit reports. For
example the following property disables generation of separate report
4. It is possible to configure formatter used by JUnit reports.
Configuration properties are "junit.formatter.type",
"junit.formatter.extension" and "junit.formatter.usefile".
For example the following property disables generation of separate report
files:
junit.formatter.usefile=false
4. Optional support is provided for the Cobertura code coverage tool. It
5. Optional support is provided for the Cobertura code coverage tool. It
can be enabled using the following property:
test.cobertura=true
The report files by default are written to
output/coverage
* NOTE: Cobertura is licensed under GPL v2 with parts of it being under
Apache License v1.1. See http://cobertura.sf.net for details. Using it
during Tomcat build is optional and is off by default.
......
......@@ -32,8 +32,12 @@ org.apache.tomcat.util.bcel is copied from:
/commons/proper/bcel/trunk/src/main/java/org/apache/bcel
DBCP
org.apache.tomcat.dbcp is generated by the build process from Commons DBCP and
Commons Pool.
org.apache.tomcat.dbcp.dbcp2 is copied from:
/commons/proper/dbcp/trunk/src/main/java/org/apache/commons/dbcp2
and
/commons/proper/dbcp/trunk/src/main/resources/org/apache/commons/dbcp2
org.apache.tomcat.dbcp.pool2 is copied from:
/commons/proper/pool/trunk/src/main/java/org/apache/commons/pool2
FileUpload
org.apache.tomcat.util.http.fileupload is copied from:
......
......@@ -212,9 +212,11 @@ but possibly 7.1.x).
- Use of <> operator where possible
- Complete
- Use of try with resources
- Not started
- Complete
- Catching multiple exceptions
- Not started
- Started
- javax.[annotation to el] complete
- remainder TODO
13. Fix all FindBugs warnings
- Complete
......
......@@ -75,7 +75,7 @@ set "EXECUTABLE=%CATALINA_HOME%\bin\tomcat@VERSION_MAJOR@.exe"
rem Set default Service name
set SERVICE_NAME=Tomcat@VERSION_MAJOR@
set DISPLAYNAME=Apache Tomcat @VERSION_MAJOR@ %SERVICE_NAME%
set DISPLAYNAME=Apache Tomcat @VERSION_MAJOR_MINOR@ %SERVICE_NAME%
if "x%1x" == "xx" goto displayUsage
set SERVICE_CMD=%1
......@@ -85,7 +85,7 @@ if "x%1x" == "xx" goto checkServiceCmd
if "x%1x" == "x/userx" goto runAsUser
if "x%1x" == "x--userx" goto runAsUser
set SERVICE_NAME=%1
set DISPLAYNAME=Apache Tomcat @VERSION_MAJOR@ %1
set DISPLAYNAME=Apache Tomcat @VERSION_MAJOR_MINOR@ %1
shift
if "x%1x" == "xx" goto checkServiceCmd
goto checkUser
......@@ -100,7 +100,7 @@ goto end
if /i %SERVICE_CMD% == install goto doInstall
if /i %SERVICE_CMD% == remove goto doRemove
if /i %SERVICE_CMD% == uninstall goto doRemove
echo Unknown parameter "%1"
echo Unknown parameter "%SERVICE_CMD%"
:displayUsage
echo.
echo Usage: service.bat install/remove [service_name] [/user username]
......@@ -128,12 +128,13 @@ echo Using CATALINA_BASE: "%CATALINA_BASE%"
echo Using JAVA_HOME: "%JAVA_HOME%"
echo Using JRE_HOME: "%JRE_HOME%"
rem Set the server jvm from JAVA_HOME
rem Try to use the server jvm
set "JVM=%JRE_HOME%\bin\server\jvm.dll"
if exist "%JVM%" goto foundJvm
rem Set the client jvm from JAVA_HOME
rem Try to use the client jvm
set "JVM=%JRE_HOME%\bin\client\jvm.dll"
if exist "%JVM%" goto foundJvm
echo Warning: Neither 'server' nor 'client' jvm.dll was found at JRE_HOME.
set JVM=auto
:foundJvm
echo Using JVM: "%JVM%"
......
......@@ -25,7 +25,7 @@
# ----- Version Control Flags -----
version.major=8
version.minor=0
version.build=5
version.build=8
version.patch=0
version.suffix=
......@@ -144,7 +144,7 @@ npn.jar=${npn.home}/npn-${npn.version}.jar
npn.loc=http://repo1.maven.org/maven2/org/eclipse/jetty/npn/npn-api/${npn.version}/npn-api-${npn.version}.jar
# ----- Tomcat native library -----
tomcat-native.version=1.1.29
tomcat-native.version=1.1.30
tomcat-native.home=${base.path}/tomcat-native-${tomcat-native.version}
tomcat-native.tar.gz=${tomcat-native.home}/tomcat-native.tar.gz
tomcat-native.loc.1=${base-tomcat.loc.1}/tomcat-connectors/native/${tomcat-native.version}/source/tomcat-native-${tomcat-native.version}-src.tar.gz
......@@ -152,18 +152,6 @@ tomcat-native.loc.2=${base-tomcat.loc.2}/tomcat-connectors/native/${tomcat-nativ
tomcat-native.win.1=${base-tomcat.loc.1}/tomcat-connectors/native/${tomcat-native.version}/binaries/tomcat-native-${tomcat-native.version}-win32-bin.zip
tomcat-native.win.2=${base-tomcat.loc.2}/tomcat-connectors/native/${tomcat-native.version}/binaries/tomcat-native-${tomcat-native.version}-win32-bin.zip
# ----- Commons DBCP, version 2.0 or later -----
commons-dbcp.version=2.0
commons-dbcp.home=${base.path}/commons-dbcp2-${commons-dbcp.version}-src
commons-dbcp-src.loc.1=${base-commons.loc.1}/dbcp/source/commons-dbcp2-${commons-dbcp.version}-src.tar.gz
commons-dbcp-src.loc.2=${base-commons.loc.2}/dbcp/source/commons-dbcp2-${commons-dbcp.version}-src.tar.gz
# ----- Commons Pool, version 2.1 or later -----
commons-pool.version=2.2
commons-pool.home=${base.path}/commons-pool2-${commons-pool.version}-src
commons-pool-src.loc.1=${base-commons.loc.1}/pool/source/commons-pool2-${commons-pool.version}-src.tar.gz
commons-pool-src.loc.2=${base-commons.loc.2}/pool/source/commons-pool2-${commons-pool.version}-src.tar.gz
# ----- NSIS, version 2.0 or later -----
nsis.home=${base.path}/nsis-2.46
nsis.exe=${nsis.home}/makensis.exe
......@@ -241,4 +229,4 @@ cobertura.lib=${cobertura.home}/lib
cobertura.loc=${base-sf.loc}/cobertura/cobertura-2.0.3-bin.tar.gz
# ----- JVM settings for unit tests
java.net.preferIPv4Stack=false
\ No newline at end of file
java.net.preferIPv4Stack=false
This diff is collapsed.
......@@ -19,7 +19,7 @@
# passed to checkPackageAccess unless the
# corresponding RuntimePermission ("accessClassInPackage."+package) has
# been granted.
package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.
package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat.
#
# List of comma-separated packages that start with or equal this string
# will cause a security exception to be thrown when
......@@ -30,7 +30,8 @@ package.access=sun.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,o
# by default, no packages are restricted for definition, and none of
# the class loaders supplied with the JDK call checkPackageDefinition.
#
package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.tomcat.,org.apache.jasper.
package.definition=sun.,java.,org.apache.catalina.,org.apache.coyote.,\
org.apache.jasper.,org.apache.naming.,org.apache.tomcat.
#
#
......
......@@ -94,6 +94,10 @@
<!-- path that points to a location below either -->
<!-- $CATALINA_BASE/conf (checked first) or -->
<!-- $CATALINA_HOME/conf (checked second).[null] -->
<!-- -->
<!-- showServerInfo Should server information be presented in the -->
<!-- response sent to clients when directory -->
<!-- listings is enabled? [true] -->
<servlet>
<servlet-name>default</servlet-name>
......
......@@ -95,16 +95,9 @@ public class BeanELResolver extends ELResolver {
Method m = this.property(context, base, property).read(context);
try {
return m.invoke(base, (Object[]) null);
} catch (IllegalAccessException e) {
throw new ELException(e);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof ThreadDeath) {
throw (ThreadDeath) cause;
}
if (cause instanceof VirtualMachineError) {
throw (VirtualMachineError) cause;
}
Util.handleThrowable(cause);
throw new ELException(Util.message(context, "propertyReadError",
base.getClass().getName(), property.toString()), cause);
} catch (Exception e) {
......@@ -132,16 +125,9 @@ public class BeanELResolver extends ELResolver {
Method m = this.property(context, base, property).write(context);
try {
m.invoke(base, value);
} catch (IllegalAccessException e) {
throw new ELException(e);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof ThreadDeath) {
throw (ThreadDeath) cause;
}
if (cause instanceof VirtualMachineError) {
throw (VirtualMachineError) cause;
}
Util.handleThrowable(cause);
throw new ELException(Util.message(context, "propertyWriteError",
base.getClass().getName(), property.toString()), cause);
} catch (Exception e) {
......
......@@ -188,26 +188,13 @@ public abstract class ExpressionFactory {
(ExpressionFactory) constructor.newInstance(properties);
}
} catch (InstantiationException e) {
throw new ELException(
"Unable to create ExpressionFactory of type: " + clazz.getName(),
e);
} catch (IllegalAccessException e) {
throw new ELException(
"Unable to create ExpressionFactory of type: " + clazz.getName(),
e);
} catch (IllegalArgumentException e) {
} catch (InstantiationException | IllegalAccessException | IllegalArgumentException e) {
throw new ELException(
"Unable to create ExpressionFactory of type: " + clazz.getName(),
e);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
if (cause instanceof ThreadDeath) {
throw (ThreadDeath) cause;
}
if (cause instanceof VirtualMachineError) {
throw (VirtualMachineError) cause;
}
Util.handleThrowable(cause);
throw new ELException(
"Unable to create ExpressionFactory of type: " + clazz.getName(),
e);
......@@ -382,11 +369,8 @@ public abstract class ExpressionFactory {
if (is != null) {
String line = null;
BufferedReader br = null;
InputStreamReader isr = null;
try {
isr = new InputStreamReader(is, "UTF-8");
br = new BufferedReader(isr);
try (InputStreamReader isr = new InputStreamReader(is, "UTF-8");
BufferedReader br = new BufferedReader(isr)) {
line = br.readLine();
if (line != null && line.trim().length() > 0) {
return line.trim();
......@@ -398,16 +382,6 @@ public abstract class ExpressionFactory {
throw new ELException("Failed to read " + SERVICE_RESOURCE_NAME,
e);
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException ioe) {/*Ignore*/}
try {
if (isr != null) {
isr.close();
}
} catch (IOException ioe) {/*Ignore*/}
try {
is.close();
} catch (IOException ioe) {/*Ignore*/}
......@@ -420,9 +394,7 @@ public abstract class ExpressionFactory {
private static String getClassNameJreDir() {
File file = new File(PROPERTY_FILE);
if (file.canRead()) {
InputStream is = null;
try {
is = new FileInputStream(file);
try (InputStream is = new FileInputStream(file)){
Properties props = new Properties();
props.load(is);
String value = props.getProperty(PROPERTY_NAME);
......@@ -433,14 +405,6 @@ public abstract class ExpressionFactory {
// Should not happen - ignore it if it does
} catch (IOException e) {
throw new ELException("Failed to read " + PROPERTY_FILE, e);
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
// Ignore
}
}
}
}
return null;
......
......@@ -118,8 +118,8 @@ class Util {
if (factory == null) {
final Lock writeLock = cacheValue.getLock().writeLock();
writeLock.lock();
try {
writeLock.lock();
factory = cacheValue.getExpressionFactory();
if (factory == null) {
factory = ExpressionFactory.newInstance();
......@@ -228,7 +228,7 @@ class Util {
private static Wrapper findWrapper(Class<?> clazz, List<Wrapper> wrappers,
String name, Class<?>[] paramTypes, Object[] paramValues) {
Map<Wrapper,Integer> candidates = new HashMap<>();
Map<Wrapper,MatchResult> candidates = new HashMap<>();
int paramCount;
if (paramTypes == null) {
......@@ -255,6 +255,8 @@ class Util {
// Check the parameters match
int exactMatch = 0;
int assignableMatch = 0;
int coercibleMatch = 0;
boolean noMatch = false;
for (int i = 0; i < mParamCount; i++) {
// Can't be null
......@@ -263,12 +265,16 @@ class Util {
} else if (i == (mParamCount - 1) && w.isVarArgs()) {
Class<?> varType = mParamTypes[i].getComponentType();
for (int j = i; j < paramCount; j++) {
if (!isAssignableFrom(paramTypes[j], varType)) {
if (isAssignableFrom(paramTypes[j], varType)) {
assignableMatch++;
} else {
if (paramValues == null) {
noMatch = true;
break;
} else {
if (!isCoercibleFrom(paramValues[j], varType)) {
if (isCoercibleFrom(paramValues[j], varType)) {
coercibleMatch++;
} else {
noMatch = true;
break;
}
......@@ -278,12 +284,16 @@ class Util {
// lead to a varArgs method matching when the result
// should be ambiguous
}
} else if (!isAssignableFrom(paramTypes[i], mParamTypes[i])) {
} else if (isAssignableFrom(paramTypes[i], mParamTypes[i])) {
assignableMatch++;
} else {
if (paramValues == null) {
noMatch = true;
break;
} else {
if (!isCoercibleFrom(paramValues[i], mParamTypes[i])) {
if (isCoercibleFrom(paramValues[i], mParamTypes[i])) {
coercibleMatch++;
} else {
noMatch = true;
break;
}
......@@ -300,26 +310,26 @@ class Util {
return w;
}
candidates.put(w, Integer.valueOf(exactMatch));
candidates.put(w, new MatchResult(exactMatch, assignableMatch, coercibleMatch));
}
// Look for the method that has the highest number of parameters where
// the type matches exactly
int bestMatch = 0;
MatchResult bestMatch = new MatchResult(0, 0, 0);
Wrapper match = null;
boolean multiple = false;
for (Map.Entry<Wrapper, Integer> entry : candidates.entrySet()) {
if (entry.getValue().intValue() > bestMatch ||
match == null) {
bestMatch = entry.getValue().intValue();
for (Map.Entry<Wrapper, MatchResult> entry : candidates.entrySet()) {
int cmp = entry.getValue().compareTo(bestMatch);
if (cmp > 0 || match == null) {
bestMatch = entry.getValue();
match = entry.getKey();
multiple = false;
} else if (entry.getValue().intValue() == bestMatch) {
} else if (cmp == 0) {
multiple = true;
}
}
if (multiple) {
if (bestMatch == paramCount - 1) {
if (bestMatch.getExact() == paramCount - 1) {
// Only one parameter is not an exact match - try using the
// super class
match = resolveAmbiguousWrapper(candidates.keySet(), paramTypes);
......@@ -700,4 +710,45 @@ class Util {
return c.isVarArgs();
}
}
/*
* This class duplicates code in org.apache.el.util.ReflectionUtil. When
* making changes keep the code in sync.
*/
private static class MatchResult implements Comparable<MatchResult> {
private final int exact;
private final int assignable;
private final int coercible;
public MatchResult(int exact, int assignable, int coercible) {
this.exact = exact;
this.assignable = assignable;
this.coercible = coercible;
}
public int getExact() {
return exact;
}
public int getAssignable() {
return assignable;
}
public int getCoercible() {
return coercible;
}
@Override
public int compareTo(MatchResult o) {
int cmp = Integer.compare(this.getExact(), o.getExact());
if (cmp == 0) {
cmp = Integer.compare(this.getAssignable(), o.getAssignable());
if (cmp == 0) {
cmp = Integer.compare(this.getCoercible(), o.getCoercible());
}
}
return cmp;
}
}
}
......@@ -1632,4 +1632,10 @@ public interface Context extends Container {
* The class loader to restore as the thread context class loader
*/
public void unbind(boolean usePrivilegedAction, ClassLoader originalClassLoader);
/**
* Obtain the token necessary for operations on the associated JNDI naming
* context.
*/
public Object getNamingToken();
}
......@@ -206,4 +206,11 @@ public interface Server extends Lifecycle {
* @param service The Service to be removed
*/
public void removeService(Service service);
/**
* Obtain the token necessary for operations on the associated JNDI naming
* context.
*/
public Object getNamingToken();
}
......@@ -258,7 +258,14 @@ public class SpnegoAuthenticator extends AuthenticatorBase {
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
} catch (PrivilegedActionException e) {
log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
Throwable cause = e.getCause();
if (cause instanceof GSSException) {
if (log.isDebugEnabled()) {
log.debug(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
}
} else {
log.error(sm.getString("spnegoAuthenticator.serviceLoginFail"), e);
}
response.setHeader("WWW-Authenticate", "Negotiate");
response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return false;
......
......@@ -655,6 +655,39 @@ public class CoyoteAdapter implements Adapter {
}
private static class RecycleRequiredException extends Exception {
private static final long serialVersionUID = 1L;
}
@Override
public void checkRecycled(org.apache.coyote.Request req,
org.apache.coyote.Response res) {
Request request = (Request) req.getNote(ADAPTER_NOTES);
Response response = (Response) res.getNote(ADAPTER_NOTES);
try {
if (request != null && request.getHost() != null) {
throw new RecycleRequiredException();
}
if (response != null && response.getContentWritten() != 0) {
throw new RecycleRequiredException();
}
} catch (RecycleRequiredException e) {
String message = sm.getString("coyoteAdapter.checkRecycled");