This is an automated email from the ASF dual-hosted git repository.
rmaucher pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/tomcat-maven-plugin.git
The following commit(s) were added to refs/heads/trunk by this push:
new 0fc959f Fix issues from code review
0fc959f is described below
commit 0fc959fb635607b9a9751293dccb0459c069ff82
Author: remm <remm@meteor>
AuthorDate: Thu Jun 4 14:55:03 2026 +0200
Fix issues from code review
---
.../maven/common/deployer/TomcatManager.java | 100 +++---
.../common/deployer/TomcatManagerResponse.java | 46 +--
.../common/messages/DefaultMessagesProvider.java | 36 +--
.../maven/common/messages/MessagesProvider.java | 4 +-
.../run/ClassLoaderEntriesCalculatorResult.java | 3 +-
.../run/DefaultClassLoaderEntriesCalculator.java | 1 +
.../tomcat/maven/common/run/EmbeddedRegistry.java | 32 +-
.../maven/plugin/tomcat/AbstractCatalinaMojo.java | 11 +-
.../maven/plugin/tomcat/AbstractTomcatMojo.java | 1 +
.../plugin/tomcat/deploy/AbstractDeployMojo.java | 2 +-
.../tomcat/deploy/AbstractDeployWarMojo.java | 2 +-
.../maven/plugin/tomcat/deploy/RedeployMojo.java | 3 +-
.../plugin/tomcat/deploy/RedeployOnlyMojo.java | 4 +-
.../maven/plugin/tomcat/deploy/SessionsMojo.java | 7 +-
.../maven/plugin/tomcat/deploy/WaitMojo.java | 6 +-
.../plugin/tomcat/run/AbstractExecWarMojo.java | 74 +++--
.../maven/plugin/tomcat/run/AbstractRunMojo.java | 355 ++++++++++-----------
.../tomcat/run/AbstractStandaloneWarMojo.java | 12 +-
.../maven/plugin/tomcat/run/ExtendedTomcat.java | 3 +
.../tomcat/maven/plugin/tomcat/run/RunMojo.java | 10 +-
.../maven/plugin/tomcat/run/ShutdownMojo.java | 2 +-
.../tomcat/maven/plugin/tomcat/run/Webapp.java | 47 +--
.../apache/tomcat/maven/runner/PasswordUtil.java | 35 +-
.../apache/tomcat/maven/runner/TomcatRunner.java | 25 +-
.../tomcat/maven/runner/TomcatRunnerCli.java | 55 +++-
25 files changed, 447 insertions(+), 429 deletions(-)
diff --git
a/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java
b/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java
index 315bc17..61702c3 100644
--- a/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java
+++ b/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManager.java
@@ -37,6 +37,7 @@ import java.util.Locale;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.IOUtils;
+import org.apache.maven.plugin.logging.Log;
import org.apache.maven.settings.Proxy;
import org.apache.maven.wagon.proxy.ProxyInfo;
import org.apache.maven.wagon.proxy.ProxyUtils;
@@ -47,19 +48,13 @@ import org.apache.maven.wagon.proxy.ProxyUtils;
* @author Mark Hobson ([email protected])
*/
public class TomcatManager {
+
// ----------------------------------------------------------------------
// Constants
// ----------------------------------------------------------------------
private static final int BUFFER_SIZE = 2048;
- private static final int SC_OK = 200;
- private static final int SC_CREATED = 201;
- private static final int SC_ACCEPTED = 202;
- private static final int SC_MOVED_PERMANENTLY = 301;
- private static final int SC_MOVED_TEMPORARILY = 302;
- private static final int SC_SEE_OTHER = 303;
-
// ----------------------------------------------------------------------
// Fields
// ----------------------------------------------------------------------
@@ -67,7 +62,7 @@ public class TomcatManager {
/**
* The full URL of the Tomcat manager instance to use.
*/
- private URL url;
+ private final URL url;
/**
* The username to use when authenticating with Tomcat manager.
@@ -101,6 +96,13 @@ public class TomcatManager {
private Proxy proxySettings;
+ /**
+ * The Maven log instance for output.
+ *
+ * @since 2.2
+ */
+ private Log log;
+
// ----------------------------------------------------------------------
// Constructors
// ----------------------------------------------------------------------
@@ -183,6 +185,16 @@ public class TomcatManager {
return url;
}
+ /**
+ * Sets the Maven log instance for output.
+ *
+ * @param log the Maven log instance
+ * @since 2.2
+ */
+ public void setLog(Log log) {
+ this.log = log;
+ }
+
/**
* Gets the username to use when authenticating with Tomcat manager.
*
@@ -717,14 +729,13 @@ public class TomcatManager {
long remaining = length;
while (remaining > 0) {
int transferSize = (int) Math.min(BUFFER_SIZE,
remaining);
- completed += transferSize;
- int l = stream.read(buffer, 0, transferSize);
- if (l == -1) {
+ int nRead = stream.read(buffer, 0, transferSize);
+ if (nRead < 0) {
break;
}
-
- os.write(buffer, 0, l);
- remaining -= l;
+ completed += nRead;
+ os.write(buffer, 0, nRead);
+ remaining -= nRead;
transferProgressed(completed, length);
}
}
@@ -735,36 +746,18 @@ public class TomcatManager {
}
int statusCode = connection.getResponseCode();
-
- String relocateUrl = null;
- switch (statusCode) {
- // Success Codes
- case SC_OK: // 200
- case SC_CREATED: // 201
- case SC_ACCEPTED: // 202
- break;
- // handle all redirect even if http specs says " the user agent
MUST NOT automatically redirect the request
- // unless it can be confirmed by the user"
- case SC_MOVED_PERMANENTLY: // 301
- case SC_MOVED_TEMPORARILY: // 302
- case SC_SEE_OTHER: // 303
- relocateUrl = calculateRelocatedUrl(connection);
- try {
- this.url = new URI(relocateUrl).toURL();
- } catch (URISyntaxException e) {
- throw new MalformedURLException(e.getMessage());
- }
- return invoke(path, data, length);
- }
-
- String responseBody;
- try (InputStream is = connection.getInputStream() != null ?
connection.getInputStream()
- : connection.getErrorStream()) {
- responseBody = IOUtils.toString(is, StandardCharsets.UTF_8);
+ try {
+ InputStream is;
+ try {
+ is = connection.getInputStream();
+ } catch (IOException e) {
+ is = connection.getErrorStream();
+ }
+ return new TomcatManagerResponse(statusCode,
connection.getResponseMessage(),
+ is != null ? IOUtils.toString(is, StandardCharsets.UTF_8)
: "");
+ } finally {
+ connection.disconnect();
}
-
- return new
TomcatManagerResponse().setStatusCode(statusCode).setReasonPhrase(connection.getResponseMessage())
- .setHttpResponseBody(responseBody);
}
/**
@@ -835,30 +828,25 @@ public class TomcatManager {
if (password != null) {
buffer.append(password);
}
- return "Basic " + new
String(Base64.encodeBase64(buffer.toString().getBytes()));
+ return "Basic " + new
String(Base64.encodeBase64(buffer.toString().getBytes(StandardCharsets.UTF_8),
false));
}
private void transferInitiated(String targetUrl) {
- String message = "Uploading";
-
- System.out.println(message + ": " + targetUrl);
+ if (log != null) {
+ log.info("Uploading: " + targetUrl);
+ }
}
private void transferProgressed(long completedSize, long totalSize) {
- if (!verbose) {
+ if (!verbose || log == null) {
return;
}
- StringBuilder buffer = new StringBuilder(64);
-
- buffer.append(getStatus(completedSize, totalSize)).append(" ");
- buffer.append('\r');
-
- System.out.print(buffer);
+ log.info(getStatus(completedSize, totalSize));
}
private void transferSucceeded(long contentLength, long startTime) {
- if (contentLength >= 0) {
+ if (contentLength >= 0 && log != null) {
String type = "Uploaded";
String len = contentLength >= 1024 ? toKB(contentLength) + " KB" :
contentLength + " B";
@@ -870,7 +858,7 @@ public class TomcatManager {
throughput = " at " + format.format(kbPerSec) + " KB/sec";
}
- System.out.println(type + ": " + url + " (" + len + throughput +
")");
+ log.info(type + ": " + url + " (" + len + throughput + ")");
}
}
diff --git
a/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManagerResponse.java
b/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManagerResponse.java
index 14c7e67..314d1b3 100644
---
a/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManagerResponse.java
+++
b/src/main/java/org/apache/tomcat/maven/common/deployer/TomcatManagerResponse.java
@@ -25,17 +25,24 @@ package org.apache.tomcat.maven.common.deployer;
* @since 2.0
*/
public class TomcatManagerResponse {
- private int statusCode;
- private String reasonPhrase;
+ private final int statusCode;
- private String httpResponseBody;
+ private final String reasonPhrase;
+
+ private final String httpResponseBody;
/**
* Creates an instance of TomcatManagerResponse.
+ *
+ * @param statusCode the HTTP status code
+ * @param reasonPhrase the HTTP reason phrase
+ * @param httpResponseBody the HTTP response body
*/
- public TomcatManagerResponse() {
- // no op
+ public TomcatManagerResponse(int statusCode, String reasonPhrase, String
httpResponseBody) {
+ this.statusCode = statusCode;
+ this.reasonPhrase = reasonPhrase;
+ this.httpResponseBody = httpResponseBody;
}
/**
@@ -46,16 +53,6 @@ public class TomcatManagerResponse {
return statusCode;
}
- /**
- * Sets the HTTP status code.
- * @param statusCode the status code
- * @return this response for chaining
- */
- public TomcatManagerResponse setStatusCode(int statusCode) {
- this.statusCode = statusCode;
- return this;
- }
-
/**
* Returns the HTTP reason phrase.
* @return the reason phrase
@@ -64,16 +61,6 @@ public class TomcatManagerResponse {
return reasonPhrase;
}
- /**
- * Sets the HTTP reason phrase.
- * @param reasonPhrase the reason phrase
- * @return this response for chaining
- */
- public TomcatManagerResponse setReasonPhrase(String reasonPhrase) {
- this.reasonPhrase = reasonPhrase;
- return this;
- }
-
/**
* Returns the HTTP response body.
* @return the response body
@@ -82,13 +69,4 @@ public class TomcatManagerResponse {
return httpResponseBody;
}
- /**
- * Sets the HTTP response body.
- * @param httpResponseBody the response body
- * @return this response for chaining
- */
- public TomcatManagerResponse setHttpResponseBody(String httpResponseBody) {
- this.httpResponseBody = httpResponseBody;
- return this;
- }
}
diff --git
a/src/main/java/org/apache/tomcat/maven/common/messages/DefaultMessagesProvider.java
b/src/main/java/org/apache/tomcat/maven/common/messages/DefaultMessagesProvider.java
index 7f32866..104f264 100644
---
a/src/main/java/org/apache/tomcat/maven/common/messages/DefaultMessagesProvider.java
+++
b/src/main/java/org/apache/tomcat/maven/common/messages/DefaultMessagesProvider.java
@@ -34,7 +34,7 @@ import java.util.ResourceBundle;
public class DefaultMessagesProvider implements MessagesProvider {
/**
- * plugin messages
+ * Plugin messages
*/
private final ResourceBundle messages;
@@ -43,9 +43,11 @@ public class DefaultMessagesProvider implements
MessagesProvider {
* Creates a new instance and loads the message bundle.
*/
public DefaultMessagesProvider() {
- String packageName = getClass().getPackage().getName();
-
- messages = ResourceBundle.getBundle(packageName + ".messages");
+ try {
+ messages =
ResourceBundle.getBundle(getClass().getPackage().getName() + ".messages");
+ } catch (MissingResourceException e) {
+ throw new IllegalStateException("Required message bundle
'messages' not found on classpath", e);
+ }
}
/**
@@ -56,13 +58,6 @@ public class DefaultMessagesProvider implements
MessagesProvider {
return this.messages;
}
- /**
- * Gets the message for the given key from this packages resource bundle.
- *
- * @param key the key for the required message
- *
- * @return the message
- */
@Override
public String getMessage(String key) {
try {
@@ -72,17 +67,16 @@ public class DefaultMessagesProvider implements
MessagesProvider {
}
}
- /**
- * Gets the message for the given key from this packages resource bundle
and formats it with the given parameter.
- *
- * @param key the key for the required message
- * @param params the parameters to be used to format the message with
- *
- * @return the formatted message
- */
@Override
public String getMessage(String key, Object... params) {
- return MessageFormat.format(getMessage(key), params);
+ String template = getMessage(key);
+ if (params == null || params.length == 0) {
+ return template;
+ }
+ try {
+ return MessageFormat.format(template, params);
+ } catch (IllegalArgumentException e) {
+ return template + " [formatting error: " + e.getMessage() + "]";
+ }
}
-
}
diff --git
a/src/main/java/org/apache/tomcat/maven/common/messages/MessagesProvider.java
b/src/main/java/org/apache/tomcat/maven/common/messages/MessagesProvider.java
index 111ed2d..6af72b7 100644
---
a/src/main/java/org/apache/tomcat/maven/common/messages/MessagesProvider.java
+++
b/src/main/java/org/apache/tomcat/maven/common/messages/MessagesProvider.java
@@ -36,9 +36,9 @@ public interface MessagesProvider {
/**
* Returns the formatted message for the given key with the specified
parameters.
* @param key the message key
- * @param param1 the formatting parameters
+ * @param params the formatting parameters
* @return the formatted message string
*/
- String getMessage(String key, Object... param1);
+ String getMessage(String key, Object... params);
}
diff --git
a/src/main/java/org/apache/tomcat/maven/common/run/ClassLoaderEntriesCalculatorResult.java
b/src/main/java/org/apache/tomcat/maven/common/run/ClassLoaderEntriesCalculatorResult.java
index 0c9ea2d..5b7ca7d 100644
---
a/src/main/java/org/apache/tomcat/maven/common/run/ClassLoaderEntriesCalculatorResult.java
+++
b/src/main/java/org/apache/tomcat/maven/common/run/ClassLoaderEntriesCalculatorResult.java
@@ -19,6 +19,7 @@
package org.apache.tomcat.maven.common.run;
import java.io.File;
+import java.util.Collections;
import java.util.List;
/**
@@ -54,7 +55,7 @@ public class ClassLoaderEntriesCalculatorResult {
List<String> buildDirectories) {
this.classPathEntries = classPathEntries;
this.tmpDirectories = tmpDirectories;
- this.buildDirectories = buildDirectories;
+ this.buildDirectories = Collections.unmodifiableList(buildDirectories);
}
/**
diff --git
a/src/main/java/org/apache/tomcat/maven/common/run/DefaultClassLoaderEntriesCalculator.java
b/src/main/java/org/apache/tomcat/maven/common/run/DefaultClassLoaderEntriesCalculator.java
index 494b1b3..5b8f974 100644
---
a/src/main/java/org/apache/tomcat/maven/common/run/DefaultClassLoaderEntriesCalculator.java
+++
b/src/main/java/org/apache/tomcat/maven/common/run/DefaultClassLoaderEntriesCalculator.java
@@ -149,6 +149,7 @@ public class DefaultClassLoaderEntriesCalculator implements
ClassLoaderEntriesCa
}
}
+ // All directories must be added, this is not for cleanup
tmpDirectories.add(tmpDir);
try {
diff --git
a/src/main/java/org/apache/tomcat/maven/common/run/EmbeddedRegistry.java
b/src/main/java/org/apache/tomcat/maven/common/run/EmbeddedRegistry.java
index 78902e7..eb42212 100644
--- a/src/main/java/org/apache/tomcat/maven/common/run/EmbeddedRegistry.java
+++ b/src/main/java/org/apache/tomcat/maven/common/run/EmbeddedRegistry.java
@@ -22,9 +22,9 @@ import org.apache.maven.plugin.logging.Log;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
/**
* Registry which collects all embedded Tomcat Servers so that they will be
shutdown through a shutdown hook when the
@@ -35,15 +35,24 @@ import java.util.Set;
* @since 1.1
*/
public final class EmbeddedRegistry {
- private static EmbeddedRegistry instance;
- private final Set<Object> containers = new HashSet<>(1);
+ private static class Holder {
+ static final EmbeddedRegistry INSTANCE = new EmbeddedRegistry();
+ }
+
+ private final Set<Object> containers = ConcurrentHashMap.newKeySet(1);
/**
* Don't instantiate - use the instance through {@link #getInstance()}.
*/
private EmbeddedRegistry() {
- // no op
+ Runtime.getRuntime().addShutdownHook(new Thread(() -> {
+ try {
+ getInstance().shutdownAll(null);
+ } catch (Exception e) {
+ // ignore, the exception should already have been reported
+ }
+ }));
}
/**
@@ -52,17 +61,7 @@ public final class EmbeddedRegistry {
* @return singleton instance of the registry
*/
public static EmbeddedRegistry getInstance() {
- if (instance == null) {
- instance = new EmbeddedRegistry();
- Runtime.getRuntime().addShutdownHook(new Thread(() -> {
- try {
- getInstance().shutdownAll(null);
- } catch (Exception e) {
- // ignore, the exception should already have been reported
- }
- }));
- }
- return instance;
+ return Holder.INSTANCE;
}
/**
@@ -108,11 +107,10 @@ public final class EmbeddedRegistry {
error(log, e, "Error while shutting down embedded
Tomcat.");
}
} catch (InvocationTargetException e) {
-
if (firstException == null) {
firstException = e;
error(log, e,
- "IllegalAccessException for stop/destroy method in
class " + embedded.getClass().getName());
+ "InvocationTargetException for stop/destroy method
in class " + embedded.getClass().getName());
} else {
error(log, e, "Error while shutting down embedded
Tomcat.");
}
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/AbstractCatalinaMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/AbstractCatalinaMojo.java
index 134fb6e..fcb4800 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/AbstractCatalinaMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/AbstractCatalinaMojo.java
@@ -111,7 +111,7 @@ public abstract class AbstractCatalinaMojo extends
AbstractTomcatMojo {
/**
* The Tomcat manager wrapper object.
*/
- private TomcatManager manager;
+ private volatile TomcatManager manager;
// ----------------------------------------------------------------------
// Mojo Implementation
@@ -155,6 +155,14 @@ public abstract class AbstractCatalinaMojo extends
AbstractTomcatMojo {
* details
*/
protected TomcatManager getManager() throws MojoExecutionException {
+ TomcatManager manager = this.manager;
+ if (manager == null) {
+ manager = getManagerInternal();
+ }
+ return manager;
+ }
+
+ protected synchronized TomcatManager getManagerInternal() throws
MojoExecutionException {
// lazily instantiate when config values have been injected
if (manager == null) {
String userName;
@@ -195,6 +203,7 @@ public abstract class AbstractCatalinaMojo extends
AbstractTomcatMojo {
}
manager = new TomcatManager(url, userName, password, charset,
settings.isInteractiveMode());
+ manager.setLog(getLog());
manager.setUserAgent(name + "/" + version);
}
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/AbstractTomcatMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/AbstractTomcatMojo.java
index 8a56f7e..252d7c6 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/AbstractTomcatMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/AbstractTomcatMojo.java
@@ -88,6 +88,7 @@ public abstract class AbstractTomcatMojo extends AbstractMojo
{
messagesProvider.getMessage("tomcatHttpStatusError",
statusCode, tomcatResponse.getReasonPhrase()) +
": " + tomcatResponse.getHttpResponseBody());
} else if (!tomcatResponse.getHttpResponseBody().startsWith("OK -")) {
+ // Tomcat Manager and Host Manager will always use "OK -" and
"FAIL -" prefixes for their text endpoints
getLog().error(messagesProvider.getMessage("tomcatHttpBodyError",
tomcatResponse.getHttpResponseBody()));
throw new MojoExecutionException(
messagesProvider.getMessage("tomcatHttpBodyError",
tomcatResponse.getHttpResponseBody()));
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/AbstractDeployMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/AbstractDeployMojo.java
index d70972f..9ed3522 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/AbstractDeployMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/AbstractDeployMojo.java
@@ -77,7 +77,7 @@ public abstract class AbstractDeployMojo extends
AbstractWarCatalinaMojo {
* {@inheritDoc}
*/
@Override
- public void invokeManager() throws MojoExecutionException,
TomcatManagerException, IOException {
+ protected void invokeManager() throws MojoExecutionException,
TomcatManagerException, IOException {
if ("war".equals(mode)) {
deployWar();
} else if ("context".equals(mode)) {
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/AbstractDeployWarMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/AbstractDeployWarMojo.java
index 61c00b2..92c8c42 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/AbstractDeployWarMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/AbstractDeployWarMojo.java
@@ -66,7 +66,7 @@ public class AbstractDeployWarMojo extends AbstractDeployMojo
{
*/
@Override
protected void validateWarFile() throws MojoExecutionException {
- if (!warFile.exists() || !warFile.isFile()) {
+ if (!warFile.exists() || !warFile.isFile() || !warFile.canRead()) {
throw new
MojoExecutionException(messagesProvider.getMessage("DeployMojo.missingWar",
warFile.getPath()));
}
}
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/RedeployMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/RedeployMojo.java
index 7207a71..0e6dc6a 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/RedeployMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/RedeployMojo.java
@@ -23,7 +23,8 @@ import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
/**
- * Redeploy a WAR in Tomcat. (Alias for the deploy goal with its update
parameter set to true.)
+ * Redeploy a WAR in Tomcat. Alias for the deploy goal with its update
parameter set to true, so
+ * this goal always undeploys any existing web application.
*
* @author Olivier Lamy
*
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/RedeployOnlyMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/RedeployOnlyMojo.java
index 9376767..177cd62 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/RedeployOnlyMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/RedeployOnlyMojo.java
@@ -21,8 +21,8 @@ package org.apache.tomcat.maven.plugin.tomcat.deploy;
import org.apache.maven.plugins.annotations.Mojo;
/**
- * Redeploy a WAR in Tomcat without forking the package lifecycle. (Alias for
the deploy-only goal with its update
- * parameter set to true.)
+ * Redeploy a WAR in Tomcat without forking the package lifecycle. Alias for
the deploy-only
+ * goal with its update parameter set to true, so this goal always undeploys
any existing web application.
*
* @since 2.1
*/
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/SessionsMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/SessionsMojo.java
index 576cc05..537018a 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/SessionsMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/SessionsMojo.java
@@ -26,7 +26,8 @@ import
org.apache.tomcat.maven.plugin.tomcat.AbstractCatalinaMojo;
import java.io.IOException;
/**
- * List session information for a web application.
+ * List session information for a web application. Session information
+ * can be sensitive material, so exercise caution when using this goal.
*
* @since 3.0
*/
@@ -38,13 +39,11 @@ public class SessionsMojo extends AbstractCatalinaMojo {
public SessionsMojo() {
// default constructor
}
+
// ----------------------------------------------------------------------
// Protected Methods
// ----------------------------------------------------------------------
- /**
- * {@inheritDoc}
- */
@Override
protected void invokeManager() throws MojoExecutionException,
TomcatManagerException, IOException {
getLog().info(messagesProvider.getMessage("SessionsMojo.listSessions",
getURL()));
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/WaitMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/WaitMojo.java
index aef0454..197633e 100644
--- a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/WaitMojo.java
+++ b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/deploy/WaitMojo.java
@@ -56,7 +56,7 @@ public class WaitMojo extends AbstractCatalinaMojo {
* The interval between checks, in milliseconds.
*/
@Parameter(property = "maven.tomcat.wait.interval", defaultValue = "1000")
- private long interval = 1000;
+ private int interval = 1000;
/**
* The HTTP status code to wait for.
@@ -113,8 +113,8 @@ public class WaitMojo extends AbstractCatalinaMojo {
*/
private boolean isServerResponsive(URL url) throws IOException {
HttpURLConnection connection = (HttpURLConnection)
url.openConnection();
- connection.setConnectTimeout((int) interval);
- connection.setReadTimeout((int) interval);
+ connection.setConnectTimeout(interval);
+ connection.setReadTimeout(interval);
connection.setRequestMethod("HEAD");
try {
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractExecWarMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractExecWarMojo.java
index 2c7cd8d..adbf048 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractExecWarMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractExecWarMojo.java
@@ -22,6 +22,7 @@ import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
@@ -292,10 +293,10 @@ public abstract class AbstractExecWarMojo extends
AbstractTomcatMojo {
// * file tomcat.standalone.properties with possible values :
// * useServerXml=true/false to use directly the one provided
// * enableNaming=true/false
- // * wars=foo.war|contextpath;bar.war ( |contextpath is optionnal
if empty use the war name )
+ // * wars=foo.war|contextpath;bar.war ( |contextpath is optional
if empty use the war name )
// * accessLogValveFormat=
// * connectorhttpProtocol: HTTP/1.1 or
org.apache.coyote.http11.Http11NioProtocol
- // * optionnal: conf/ with usual tomcat configuration files
+ // * optional: conf/ with usual tomcat configuration files
// * MANIFEST with Main-Class
Properties properties = new Properties();
@@ -313,12 +314,17 @@ public abstract class AbstractExecWarMojo extends
AbstractTomcatMojo {
if ("war".equals(project.getPackaging())) {
- String pathWithoutSlash = path.startsWith("/") ?
path.substring(1) : path;
- os.putArchiveEntry(new JarArchiveEntry(pathWithoutSlash +
".war"));
- IOUtils.copy(new FileInputStream(projectArtifact.getFile()),
os);
- os.closeArchiveEntry();
+ if (projectArtifact.getFile() != null) {
+ String pathWithoutSlash = path.startsWith("/") ?
path.substring(1) : path;
+ os.putArchiveEntry(new JarArchiveEntry(pathWithoutSlash +
".war"));
+ IOUtils.copy(new
FileInputStream(projectArtifact.getFile()), os);
+ os.closeArchiveEntry();
+
+ properties.put(TomcatRunner.WARS_KEY, pathWithoutSlash +
".war|" + path);
+ } else {
+ throw new MojoExecutionException("No project artifact
found");
+ }
- properties.put(TomcatRunner.WARS_KEY, pathWithoutSlash +
".war|" + path);
} else if (warRunDependencies != null &&
!warRunDependencies.isEmpty()) {
for (WarRunDependency warRunDependency : warRunDependencies) {
if (warRunDependency.dependency != null) {
@@ -335,6 +341,10 @@ public abstract class AbstractExecWarMojo extends
AbstractTomcatMojo {
Artifact artifact =
toMavenArtifact(dependency.getGroupId(), dependency.getArtifactId(),
version, dependency.getType(),
dependency.getClassifier());
+ if (artifact.getFile() == null) {
+ throw new MojoExecutionException("Dependency '" +
dependency.getGroupId() + "':'" +
+ dependency.getArtifactId() + "' not
found");
+ }
File warFileToBundle = new
File(resolvePluginWorkDir(), artifact.getFile().getName());
FileUtils.copyFile(artifact.getFile(),
warFileToBundle);
@@ -603,7 +613,7 @@ public abstract class AbstractExecWarMojo extends
AbstractTomcatMojo {
}
/**
- * Copy the contents of a jar file to another archive
+ * Copy the contents of a jar file to another archive, then close it.
*
* @param file The input jar file
* @param os The output archive
@@ -612,30 +622,42 @@ public abstract class AbstractExecWarMojo extends
AbstractTomcatMojo {
*/
protected void extractJarToArchive(JarFile file,
ArchiveOutputStream<JarArchiveEntry> os, String[] excludes)
throws IOException {
- Enumeration<? extends JarEntry> entries = file.entries();
- while (entries.hasMoreElements()) {
- JarEntry j = entries.nextElement();
-
- if (excludes != null) {
- for (String exclude : excludes) {
- if (SelectorUtils.match(exclude, j.getName())) {
+ try {
+ Enumeration<? extends JarEntry> entries = file.entries();
+ while (entries.hasMoreElements()) {
+ JarEntry j = entries.nextElement();
+
+ if (excludes != null) {
+ boolean excluded = false;
+ for (String exclude : excludes) {
+ if (SelectorUtils.match(exclude, j.getName())) {
+ excluded = true;
+ break;
+ }
+ }
+ if (excluded) {
continue;
}
}
- }
- if ("META-INF/MANIFEST.MF".equalsIgnoreCase(j.getName())) {
- continue;
- }
- if (j.getName().startsWith("META-INF/") &&
- (j.getName().endsWith(".SF") ||
j.getName().endsWith(".DSA") || j.getName().endsWith(".RSA"))) {
- continue;
+ if ("META-INF/MANIFEST.MF".equalsIgnoreCase(j.getName())) {
+ continue;
+ }
+ if (j.getName().startsWith("META-INF/") &&
+ (j.getName().endsWith(".SF") ||
j.getName().endsWith(".DSA") || j.getName().endsWith(".RSA"))) {
+ continue;
+ }
+ os.putArchiveEntry(new JarArchiveEntry(j.getName()));
+ if (!j.isDirectory()) {
+ try (InputStream is = file.getInputStream(j)) {
+ IOUtils.copy(is, os);
+ }
+ }
+ os.closeArchiveEntry();
}
- os.putArchiveEntry(new JarArchiveEntry(j.getName()));
- IOUtils.copy(file.getInputStream(j), os);
- os.closeArchiveEntry();
+ } finally {
+ file.close();
}
- file.close();
}
private Artifact toMavenArtifact(String groupId, String artifactId, String
version, String type, String classifier)
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractRunMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractRunMojo.java
index f9ccbf6..d584108 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractRunMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractRunMojo.java
@@ -732,9 +732,9 @@ public abstract class AbstractRunMojo extends
AbstractTomcatMojo {
* @throws MojoExecutionException if parsing fails
*/
protected StandardContext parseContextFile(File file) throws
MojoExecutionException {
- try {
+ try (FileInputStream fis = new FileInputStream(file)) {
StandardContext standardContext = new StandardContext();
- XMLStreamReader reader =
XMLInputFactory.newFactory().createXMLStreamReader(new FileInputStream(file));
+ XMLStreamReader reader =
XMLInputFactory.newFactory().createXMLStreamReader(fis);
int tag = reader.next();
@@ -757,7 +757,7 @@ public abstract class AbstractRunMojo extends
AbstractTomcatMojo {
}
return standardContext;
- } catch (XMLStreamException | FileNotFoundException e) {
+ } catch (XMLStreamException | IOException e) {
throw new MojoExecutionException(e.getMessage(), e);
}
}
@@ -775,11 +775,6 @@ public abstract class AbstractRunMojo extends
AbstractTomcatMojo {
return new WebappLoader();
}
- /**
- * Determine whether the passed context.xml file declares the context as
reloadable or not.
- *
- * @return false by default, true if reloadable="true" in context.xml.
- */
/**
* Determine whether the passed context.xml file declares the context as
reloadable or not.
*
@@ -795,6 +790,9 @@ public abstract class AbstractRunMojo extends
AbstractTomcatMojo {
try {
if (contextFile != null && contextFile.exists()) {
DocumentBuilderFactory builderFactory =
DocumentBuilderFactory.newInstance();
+
builderFactory.setFeature(javax.xml.XMLConstants.FEATURE_SECURE_PROCESSING,
true);
+
builderFactory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",
true);
+ builderFactory.setExpandEntityReferences(false);
DocumentBuilder builder = builderFactory.newDocumentBuilder();
Document contextDoc = builder.parse(contextFile);
contextDoc.getDocumentElement().normalize();
@@ -816,11 +814,6 @@ public abstract class AbstractRunMojo extends
AbstractTomcatMojo {
}
- /**
- * Gets the webapp directory to run.
- *
- * @return the webapp directory
- */
/**
* Gets the webapp directory to run.
* @return the webapp directory
@@ -922,7 +915,7 @@ public abstract class AbstractRunMojo extends
AbstractTomcatMojo {
String[] files = scanner.getIncludedFiles();
if (files != null && files.length > 0) {
- getLog().info("Coping additional tomcat config files");
+ getLog().info("Copying additional tomcat config files");
for (int i = 0; i < files.length; i++) {
File file = new File(additionalConfigFilesDir,
files[i]);
@@ -962,233 +955,229 @@ public abstract class AbstractRunMojo extends
AbstractTomcatMojo {
* @throws MojoExecutionException if the server could not be configured
*/
private void startContainer() throws IOException, LifecycleException,
MojoExecutionException, Exception {
- String previousCatalinaBase = System.getProperty("catalina.base");
-
- try {
- // Set the system properties
- setupSystemProperties();
+ // Set the system properties
+ setupSystemProperties();
- System.setProperty("catalina.base",
configurationDir.getAbsolutePath());
+ System.setProperty("catalina.base",
configurationDir.getAbsolutePath());
- if (serverXml != null) {
- if (!serverXml.exists()) {
- throw new MojoExecutionException(serverXml.getPath() + "
not exists");
- }
+ if (serverXml != null) {
+ if (!serverXml.exists()) {
+ throw new MojoExecutionException(serverXml.getPath() + " not
exists");
+ }
- Catalina container = new Catalina();
+ Catalina container = new Catalina();
- if (useSeparateTomcatClassLoader) {
-
Thread.currentThread().setContextClassLoader(getTomcatClassLoader());
- container.setParentClassLoader(getTomcatClassLoader());
- }
+ if (useSeparateTomcatClassLoader) {
+
Thread.currentThread().setContextClassLoader(getTomcatClassLoader());
+ container.setParentClassLoader(getTomcatClassLoader());
+ }
- container.setUseNaming(this.useNaming);
- container.setConfigFile(serverXml.getAbsolutePath());
- container.start();
- EmbeddedRegistry.getInstance().register(container);
- } else {
+ container.setUseNaming(this.useNaming);
+ container.setConfigFile(serverXml.getAbsolutePath());
+ container.start();
+ EmbeddedRegistry.getInstance().register(container);
+ } else {
- System.setProperty("java.util.logging.manager",
"org.apache.juli.ClassLoaderLogManager");
- System.setProperty("java.util.logging.config.file",
- new File(configurationDir,
"conf/logging.properties").toString());
+ System.setProperty("java.util.logging.manager",
"org.apache.juli.ClassLoaderLogManager");
+ System.setProperty("java.util.logging.config.file",
+ new File(configurationDir,
"conf/logging.properties").toString());
- // Trigger loading of catalina.properties
- CatalinaProperties.getProperty("foo");
+ // Trigger loading of catalina.properties
+ CatalinaProperties.getProperty("foo");
- Tomcat embeddedTomcat = new ExtendedTomcat(configurationDir);
+ Tomcat embeddedTomcat = new ExtendedTomcat(configurationDir);
- embeddedTomcat.setBaseDir(configurationDir.getAbsolutePath());
- MemoryRealm memoryRealm = new MemoryRealm();
+ embeddedTomcat.setBaseDir(configurationDir.getAbsolutePath());
+ MemoryRealm memoryRealm = new MemoryRealm();
- if (tomcatUsers != null) {
- if (!tomcatUsers.exists()) {
- throw new MojoExecutionException(" tomcatUsers " +
tomcatUsers.getPath() + " not exists");
- }
- getLog().info("use tomcat-users.xml from " +
tomcatUsers.getAbsolutePath());
- memoryRealm.setPathname(tomcatUsers.getAbsolutePath());
+ if (tomcatUsers != null) {
+ if (!tomcatUsers.exists()) {
+ throw new MojoExecutionException(" tomcatUsers " +
tomcatUsers.getPath() + " not exists");
}
+ getLog().info("use tomcat-users.xml from " +
tomcatUsers.getAbsolutePath());
+ memoryRealm.setPathname(tomcatUsers.getAbsolutePath());
+ }
- embeddedTomcat.getEngine().setRealm(memoryRealm);
+ embeddedTomcat.getEngine().setRealm(memoryRealm);
- Context ctx = createContext(embeddedTomcat);
+ Context ctx = createContext(embeddedTomcat);
- if (useNaming) {
- embeddedTomcat.enableNaming();
- }
+ if (useNaming) {
+ embeddedTomcat.enableNaming();
+ }
- embeddedTomcat.getHost().setAppBase(new File(configurationDir,
"webapps").getAbsolutePath());
+ embeddedTomcat.getHost().setAppBase(new File(configurationDir,
"webapps").getAbsolutePath());
- if (hostName != null) {
- embeddedTomcat.getHost().setName(hostName);
+ if (hostName != null) {
+ embeddedTomcat.getHost().setName(hostName);
+ }
+ if (aliases != null) {
+ for (String alias : aliases) {
+ embeddedTomcat.getHost().addAlias(alias);
}
- if (aliases != null) {
- for (String alias : aliases) {
- embeddedTomcat.getHost().addAlias(alias);
- }
- }
- createStaticContext(embeddedTomcat, ctx,
embeddedTomcat.getHost());
+ }
+ createStaticContext(embeddedTomcat, ctx, embeddedTomcat.getHost());
- Connector connector = new Connector(protocol);
- connector.setPort(port);
- connector.setMaxPostSize(maxPostSize);
+ Connector connector = new Connector(protocol);
+ connector.setPort(port);
+ connector.setMaxPostSize(maxPostSize);
- if (httpsPort > 0) {
- connector.setRedirectPort(httpsPort);
- }
+ if (httpsPort > 0) {
+ connector.setRedirectPort(httpsPort);
+ }
- if (address != null) {
- connector.setProperty("address", address);
- }
+ if (address != null) {
+ connector.setProperty("address", address);
+ }
- connector.setURIEncoding(uriEncoding);
+ connector.setURIEncoding(uriEncoding);
- connector.setUseBodyEncodingForURI(this.useBodyEncodingForURI);
+ connector.setUseBodyEncodingForURI(this.useBodyEncodingForURI);
- embeddedTomcat.getService().addConnector(connector);
+ embeddedTomcat.getService().addConnector(connector);
- embeddedTomcat.setConnector(connector);
+ embeddedTomcat.setConnector(connector);
- AccessLogValve alv = new AccessLogValve();
- alv.setDirectory(new File(configurationDir,
"logs").getAbsolutePath());
- alv.setPattern("%h %l %u %t \"%r\" %s %b %I %D");
- embeddedTomcat.getHost().getPipeline().addValve(alv);
+ AccessLogValve alv = new AccessLogValve();
+ alv.setDirectory(new File(configurationDir,
"logs").getAbsolutePath());
+ alv.setPattern("%h %l %u %t \"%r\" %s %b %I %D");
+ embeddedTomcat.getHost().getPipeline().addValve(alv);
- // create https connector
- Connector httpsConnector = null;
- if (httpsPort > 0) {
- httpsConnector = new Connector(protocol);
- httpsConnector.setPort(httpsPort);
- httpsConnector.setMaxPostSize(maxPostSize);
- httpsConnector.setSecure(true);
- httpsConnector.setProperty("SSLEnabled", "true");
- httpsConnector.setURIEncoding(uriEncoding);
-
httpsConnector.setUseBodyEncodingForURI(this.useBodyEncodingForURI);
+ // create https connector
+ Connector httpsConnector = null;
+ if (httpsPort > 0) {
+ httpsConnector = new Connector(protocol);
+ httpsConnector.setPort(httpsPort);
+ httpsConnector.setMaxPostSize(maxPostSize);
+ httpsConnector.setSecure(true);
+ httpsConnector.setProperty("SSLEnabled", "true");
+ httpsConnector.setURIEncoding(uriEncoding);
+
httpsConnector.setUseBodyEncodingForURI(this.useBodyEncodingForURI);
- SSLHostConfig hostConfig = new SSLHostConfig();
- SSLHostConfigCertificate certificate = new
SSLHostConfigCertificate(hostConfig,
- SSLHostConfigCertificate.DEFAULT_TYPE);
+ SSLHostConfig hostConfig = new SSLHostConfig();
+ SSLHostConfigCertificate certificate = new
SSLHostConfigCertificate(hostConfig,
+ SSLHostConfigCertificate.DEFAULT_TYPE);
- if (keystoreFile != null) {
- certificate.setCertificateKeystoreFile(keystoreFile);
- }
- if (keystorePass != null) {
-
certificate.setCertificateKeystorePassword(keystorePass);
- httpsConnector.setProperty("keystorePass",
keystorePass);
- }
- if (keystoreType != null) {
- certificate.setCertificateKeystoreType(keystoreType);
- }
+ if (keystoreFile != null) {
+ certificate.setCertificateKeystoreFile(keystoreFile);
+ }
+ if (keystorePass != null) {
+ certificate.setCertificateKeystorePassword(keystorePass);
+ httpsConnector.setProperty("keystorePass", keystorePass);
+ }
+ if (keystoreType != null) {
+ certificate.setCertificateKeystoreType(keystoreType);
+ }
- if (trustManagerClassName != null) {
-
hostConfig.setTrustManagerClassName(trustManagerClassName);
- }
+ if (trustManagerClassName != null) {
+ hostConfig.setTrustManagerClassName(trustManagerClassName);
+ }
- if (trustMaxCertLength != null) {
+ if (trustMaxCertLength != null) {
+ try {
hostConfig.setCertificateVerificationDepth(Integer.parseInt(trustMaxCertLength));
+ } catch (NumberFormatException e) {
+ throw new MojoExecutionException("Invalid value for
trustMaxCertLength: '" +
+ trustMaxCertLength + "'. Must be an integer.",
e);
}
+ }
- if (truststoreAlgorithm != null) {
- hostConfig.setTruststoreAlgorithm(truststoreAlgorithm);
- }
+ if (truststoreAlgorithm != null) {
+ hostConfig.setTruststoreAlgorithm(truststoreAlgorithm);
+ }
- if (truststoreFile != null) {
- hostConfig.setTruststoreFile(truststoreFile);
- }
+ if (truststoreFile != null) {
+ hostConfig.setTruststoreFile(truststoreFile);
+ }
- if (truststorePass != null) {
- hostConfig.setTruststorePassword(truststorePass);
- }
+ if (truststorePass != null) {
+ hostConfig.setTruststorePassword(truststorePass);
+ }
- if (truststoreProvider != null) {
- hostConfig.setTruststoreProvider(truststoreProvider);
- }
+ if (truststoreProvider != null) {
+ hostConfig.setTruststoreProvider(truststoreProvider);
+ }
- if (truststoreType != null) {
- hostConfig.setTruststoreType(truststoreType);
- }
- hostConfig.setCertificateVerificationAsString(clientAuth);
+ if (truststoreType != null) {
+ hostConfig.setTruststoreType(truststoreType);
+ }
+ hostConfig.setCertificateVerificationAsString(clientAuth);
- if (address != null) {
- httpsConnector.setProperty("address", address);
- }
- hostConfig.addCertificate(certificate);
- httpsConnector.addSslHostConfig(hostConfig);
+ if (address != null) {
+ httpsConnector.setProperty("address", address);
+ }
+ hostConfig.addCertificate(certificate);
+ httpsConnector.addSslHostConfig(hostConfig);
-
embeddedTomcat.getEngine().getService().addConnector(httpsConnector);
+
embeddedTomcat.getEngine().getService().addConnector(httpsConnector);
- }
+ }
- // create ajp connector
- Connector ajpConnector = null;
- if (ajpPort > 0) {
- ajpConnector = new Connector(ajpProtocol);
- ajpConnector.setPort(ajpPort);
- ajpConnector.setURIEncoding(uriEncoding);
-
ajpConnector.setUseBodyEncodingForURI(this.useBodyEncodingForURI);
- if (address != null) {
- ajpConnector.setProperty("address", address);
- }
- ajpConnector.setProperty("secretRequired", "false");
-
embeddedTomcat.getEngine().getService().addConnector(ajpConnector);
+ // create ajp connector
+ Connector ajpConnector = null;
+ if (ajpPort > 0) {
+ ajpConnector = new Connector(ajpProtocol);
+ ajpConnector.setPort(ajpPort);
+ ajpConnector.setURIEncoding(uriEncoding);
+
ajpConnector.setUseBodyEncodingForURI(this.useBodyEncodingForURI);
+ if (address != null) {
+ ajpConnector.setProperty("address", address);
}
+ ajpConnector.setProperty("secretRequired", "false");
+
embeddedTomcat.getEngine().getService().addConnector(ajpConnector);
+ }
- if (addContextWarDependencies ||
!getAdditionalWebapps().isEmpty()) {
- createDependencyContexts(embeddedTomcat);
- }
+ if (addContextWarDependencies ||
!getAdditionalWebapps().isEmpty()) {
+ createDependencyContexts(embeddedTomcat);
+ }
- if (useSeparateTomcatClassLoader) {
-
Thread.currentThread().setContextClassLoader(getTomcatClassLoader());
-
embeddedTomcat.getEngine().setParentClassLoader(getTomcatClassLoader());
- }
+ if (useSeparateTomcatClassLoader) {
+
Thread.currentThread().setContextClassLoader(getTomcatClassLoader());
+
embeddedTomcat.getEngine().setParentClassLoader(getTomcatClassLoader());
+ }
- embeddedTomcat.start();
+ embeddedTomcat.start();
- Properties portProperties = new Properties();
+ Properties portProperties = new Properties();
- portProperties.put("tomcat.maven.http.port",
Integer.toString(connector.getLocalPort()));
+ portProperties.put("tomcat.maven.http.port",
Integer.toString(connector.getLocalPort()));
-
session.getUserProperties().setProperty("tomcat.maven.http.port",
- Integer.toString(connector.getLocalPort()));
- System.setProperty("tomcat.maven.http.port",
Integer.toString(connector.getLocalPort()));
+ session.getUserProperties().setProperty("tomcat.maven.http.port",
+ Integer.toString(connector.getLocalPort()));
+ System.setProperty("tomcat.maven.http.port",
Integer.toString(connector.getLocalPort()));
- if (httpsConnector != null) {
-
session.getUserProperties().setProperty("tomcat.maven.https.port",
- Integer.toString(httpsConnector.getLocalPort()));
- portProperties.put("tomcat.maven.https.port",
Integer.toString(httpsConnector.getLocalPort()));
- System.setProperty("tomcat.maven.https.port",
Integer.toString(httpsConnector.getLocalPort()));
- }
+ if (httpsConnector != null) {
+
session.getUserProperties().setProperty("tomcat.maven.https.port",
+ Integer.toString(httpsConnector.getLocalPort()));
+ portProperties.put("tomcat.maven.https.port",
Integer.toString(httpsConnector.getLocalPort()));
+ System.setProperty("tomcat.maven.https.port",
Integer.toString(httpsConnector.getLocalPort()));
+ }
- if (ajpConnector != null) {
-
session.getUserProperties().setProperty("tomcat.maven.ajp.port",
- Integer.toString(ajpConnector.getLocalPort()));
- portProperties.put("tomcat.maven.ajp.port",
Integer.toString(ajpConnector.getLocalPort()));
- System.setProperty("tomcat.maven.ajp.port",
Integer.toString(ajpConnector.getLocalPort()));
+ if (ajpConnector != null) {
+
session.getUserProperties().setProperty("tomcat.maven.ajp.port",
+ Integer.toString(ajpConnector.getLocalPort()));
+ portProperties.put("tomcat.maven.ajp.port",
Integer.toString(ajpConnector.getLocalPort()));
+ System.setProperty("tomcat.maven.ajp.port",
Integer.toString(ajpConnector.getLocalPort()));
+ }
+ if (propertiesPortFilePath != null) {
+ File propertiesPortsFile = new File(propertiesPortFilePath);
+ if (propertiesPortsFile.exists()) {
+ propertiesPortsFile.delete();
}
- if (propertiesPortFilePath != null) {
- File propertiesPortsFile = new
File(propertiesPortFilePath);
- if (propertiesPortsFile.exists()) {
- propertiesPortsFile.delete();
- }
- FileOutputStream fileOutputStream = new
FileOutputStream(propertiesPortsFile);
- try {
- portProperties.store(fileOutputStream, "Apache Tomcat
Maven plugin port used");
- } finally {
- IOUtils.closeQuietly(fileOutputStream);
- }
+ FileOutputStream fileOutputStream = new
FileOutputStream(propertiesPortsFile);
+ try {
+ portProperties.store(fileOutputStream, "Apache Tomcat
Maven plugin port used");
+ } finally {
+ IOUtils.closeQuietly(fileOutputStream);
}
-
- EmbeddedRegistry.getInstance().register(embeddedTomcat);
-
}
+ EmbeddedRegistry.getInstance().register(embeddedTomcat);
- } finally {
- if (previousCatalinaBase != null) {
- System.setProperty("catalina.base", previousCatalinaBase);
- }
}
+
}
private List<Webapp> getAdditionalWebapps() {
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractStandaloneWarMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractStandaloneWarMojo.java
index 3b74a8d..1af42f8 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractStandaloneWarMojo.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/AbstractStandaloneWarMojo.java
@@ -81,12 +81,12 @@ public abstract class AbstractStandaloneWarMojo extends
AbstractExecWarMojo {
* @since 2.2
*/
@Parameter(property = "maven.tomcat.exec.war.attachArtifactType",
defaultValue = "war", required = true)
- protected String attachArtifactClassifierType;
+ protected String attachArtifactType;
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
if (!"war".equals(project.getPackaging())) {
- throw new MojoFailureException("Pacakaging must be of type war for
standalone-war goal.");
+ throw new MojoFailureException("Packaging must be of type war for
standalone-war goal.");
}
File warExecFile = new File(buildDirectory, finalName);
@@ -221,7 +221,7 @@ public abstract class AbstractStandaloneWarMojo extends
AbstractExecWarMojo {
if (attachArtifact) {
// MavenProject project, String artifactType, String
artifactClassifier, File artifactFile
- projectHelper.attachArtifact(project,
attachArtifactClassifierType, attachArtifactClassifier,
+ projectHelper.attachArtifact(project, attachArtifactType,
attachArtifactClassifier,
execWarJar);
}
@@ -259,6 +259,12 @@ public abstract class AbstractStandaloneWarMojo extends
AbstractExecWarMojo {
IOUtils.closeQuietly(tmpManifestWriter);
IOUtils.closeQuietly(execWarJarOutputStream);
IOUtils.closeQuietly(tmpPropertiesFileOutputStream);
+ if (tmpPropertiesFile != null) {
+ tmpPropertiesFile.delete();
+ }
+ if (tmpManifestFile != null) {
+ tmpManifestFile.delete();
+ }
}
}
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/ExtendedTomcat.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/ExtendedTomcat.java
index 66f26d4..b5bf346 100644
---
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/ExtendedTomcat.java
+++
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/ExtendedTomcat.java
@@ -42,6 +42,9 @@ public class ExtendedTomcat extends Tomcat {
*/
public ExtendedTomcat(File configurationDir) {
super();
+ if (configurationDir == null || !configurationDir.exists() ||
!configurationDir.isDirectory()) {
+ throw new IllegalArgumentException("configurationDir must not be
null and must exist");
+ }
this.configurationDir = configurationDir;
}
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/RunMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/RunMojo.java
index 071feab..0f7d5b0 100644
--- a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/RunMojo.java
+++ b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/RunMojo.java
@@ -187,11 +187,11 @@ public class RunMojo extends AbstractRunMojo {
FileWriter fw = null;
StringWriter sw = new StringWriter();
try {
- temporaryContextFile = File.createTempFile("tomcat-maven-plugin",
"temp-ctx-file");
- temporaryContextFile.deleteOnExit();
-
// format to modify/create <Context backgroundProcessorDelay="5"
reloadable="false">
if (contextFile != null && contextFile.exists()) {
+ temporaryContextFile =
File.createTempFile("tomcat-maven-plugin", "temp-ctx-file");
+ temporaryContextFile.deleteOnExit();
+
MavenFileFilterRequest mavenFileFilterRequest = new
MavenFileFilterRequest();
mavenFileFilterRequest.setFrom(contextFile);
mavenFileFilterRequest.setTo(temporaryContextFile);
@@ -205,12 +205,16 @@ public class RunMojo extends AbstractRunMojo {
Xpp3Dom xpp3Dom = Xpp3DomBuilder.build(fr);
xpp3Dom.setAttribute("backgroundProcessorDelay",
Integer.toString(backgroundProcessorDelay));
xpp3Dom.setAttribute("reloadable",
Boolean.toString(isContextReloadable()));
+ IOUtil.close(fr);
fw = new FileWriter(temporaryContextFile);
Xpp3DomWriter.write(fw, xpp3Dom);
Xpp3DomWriter.write(sw, xpp3Dom);
getLog().debug(" generated context file " + sw.toString());
} else {
if (contextReloadable) {
+ temporaryContextFile =
File.createTempFile("tomcat-maven-plugin", "temp-ctx-file");
+ temporaryContextFile.deleteOnExit();
+
// don't care about using a complicated xml api to create
one xml line :-)
StringBuilder sb = new StringBuilder("<Context
").append("backgroundProcessorDelay=\"")
.append(Integer.toString(backgroundProcessorDelay)).append("\"").append("
reloadable=\"")
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/ShutdownMojo.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/ShutdownMojo.java
index 1aacaf7..ffd7001 100644
--- a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/ShutdownMojo.java
+++ b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/ShutdownMojo.java
@@ -28,7 +28,7 @@ import
org.apache.tomcat.maven.plugin.tomcat.AbstractTomcatMojo;
/**
* <p>
* Shuts down all possibly started embedded Tomcat servers. This will be
automatically done through a shutdown hook or
- * you may call this Mojo to shut them down explictly.
+ * you may call this Mojo to shut them down explicitly.
* </p>
* <p>
* By default the <code>shutdown</code> goal is not bound to any phase. For
integration tests you might want to bind it
diff --git
a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/Webapp.java
b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/Webapp.java
index 2d39b1a..fedbf16 100644
--- a/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/Webapp.java
+++ b/src/main/java/org/apache/tomcat/maven/plugin/tomcat/run/Webapp.java
@@ -20,25 +20,6 @@ package org.apache.tomcat.maven.plugin.tomcat.run;
import java.io.File;
-/*
- * 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.
- */
-
import org.apache.maven.artifact.Artifact;
/**
@@ -48,29 +29,12 @@ import org.apache.maven.artifact.Artifact;
*/
public class Webapp {
- /**
- *
- */
private String groupId;
- /**
- *
- */
private String artifactId;
- /**
- *
- */
private String version = null;
- /**
- *
- */
private String type = "war";
- /**
- *
- */
private String classifier;
- /**
- * @parameter
- */
+
private String contextPath;
private Artifact artifact;
private File contextFile;
@@ -181,10 +145,13 @@ public class Webapp {
* @return the context path
*/
public String getContextPath() {
- if (contextPath == null || contextPath.isEmpty()) {
- return this.artifactId;
+ if (contextPath != null && !contextPath.isEmpty()) {
+ return contextPath;
+ }
+ if (artifactId != null && !artifactId.isEmpty()) {
+ return artifactId;
}
- return contextPath;
+ throw new IllegalStateException("Either contextPath or artifactId must
be configured");
}
/**
diff --git a/src/main/java/org/apache/tomcat/maven/runner/PasswordUtil.java
b/src/main/java/org/apache/tomcat/maven/runner/PasswordUtil.java
index 23a8c11..4951285 100644
--- a/src/main/java/org/apache/tomcat/maven/runner/PasswordUtil.java
+++ b/src/main/java/org/apache/tomcat/maven/runner/PasswordUtil.java
@@ -18,6 +18,9 @@
*/
package org.apache.tomcat.maven.runner;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Properties;
@@ -34,10 +37,6 @@ import java.util.Properties;
* They are not secure, but prevent casual observation.
* </p>
*
- * @see <a href=
- *
"http://grepcode.com/file_/repo1.maven.org/maven2/org.mortbay.jetty/jetty/6.1.11/org/mortbay/jetty/security/Password.java/?v=source"
- * >Jetty Source org.mortbay.jetty.security.Password</a>
- *
* @since 2.0
*/
public class PasswordUtil {
@@ -60,7 +59,7 @@ public class PasswordUtil {
*/
public static String obfuscate(String s) {
StringBuilder buf = new StringBuilder();
- byte[] b = s.getBytes();
+ byte[] b = s.getBytes(StandardCharsets.UTF_8);
buf.append(__OBFUSCATE);
for (int i = 0; i < b.length; i++) {
@@ -94,7 +93,9 @@ public class PasswordUtil {
public static String deobfuscate(String s) {
if (s.startsWith(__OBFUSCATE)) {
s = s.substring(__OBFUSCATE.length());
-
+ if (s.length() % 4 != 0) {
+ throw new IllegalArgumentException("Invalid obfuscated
password: length must be a multiple of 4");
+ }
byte[] b = new byte[s.length() / 2];
int l = 0;
for (int i = 0; i < s.length(); i += 4) {
@@ -104,7 +105,7 @@ public class PasswordUtil {
int i2 = (i0 % 256);
b[l++] = (byte) ((i1 + i2 - 254) / 2);
}
- return new String(b, 0, l);
+ return new String(b, 0, l, StandardCharsets.UTF_8);
} else {
return s;
}
@@ -116,15 +117,19 @@ public class PasswordUtil {
*/
public static void deobfuscateSystemProps() {
Properties props = System.getProperties();
+ List<String> keysToModify = new ArrayList<>();
for (Object obj : props.keySet()) {
if (obj instanceof String) {
String key = (String) obj;
String value = props.getProperty(key);
if (value != null && value.startsWith(__OBFUSCATE)) {
- System.setProperty(key, deobfuscate(value));
+ keysToModify.add(key);
}
}
}
+ for (String key : keysToModify) {
+ System.setProperty(key, deobfuscate(System.getProperty(key)));
+ }
}
/**
@@ -132,10 +137,14 @@ public class PasswordUtil {
* @param args command-line arguments
*/
public static void main(String[] args) {
- if (args[0].startsWith(__OBFUSCATE)) {
- System.out.println(PasswordUtil.deobfuscate(args[1]));
+ if (args.length < 1) {
+ System.err.println("Usage: PasswordUtil <password>");
+ System.exit(1);
+ }
+ String input = args[0];
+ if (input.startsWith(__OBFUSCATE)) {
+ System.out.println(deobfuscate(input));
} else {
- System.out.println(PasswordUtil.obfuscate(args[1]));
+ System.out.println(obfuscate(input));
}
- }
-}
+ }}
diff --git a/src/main/java/org/apache/tomcat/maven/runner/TomcatRunner.java
b/src/main/java/org/apache/tomcat/maven/runner/TomcatRunner.java
index ee0fb0e..fd6f5f8 100644
--- a/src/main/java/org/apache/tomcat/maven/runner/TomcatRunner.java
+++ b/src/main/java/org/apache/tomcat/maven/runner/TomcatRunner.java
@@ -49,8 +49,7 @@ import org.apache.tomcat.util.ExceptionUtils;
import org.apache.tomcat.util.http.fileupload.FileUtils;
/**
- * FIXME add junit for that but when
https://issues.apache.org/bugzilla/show_bug.cgi?id=52028 fixed Main class used
to
- * run the standalone wars in a Apache Tomcat instance.
+ * Main class used to run the standalone wars in a Apache Tomcat instance.
*
* @author Olivier Lamy
*
@@ -118,6 +117,11 @@ public class TomcatRunner {
*/
public int ajpPort;
+ /**
+ * AJP port number.
+ */
+ public String ajpSecret;
+
/**
* Path to the server.xml configuration file.
*/
@@ -126,7 +130,7 @@ public class TomcatRunner {
/**
* Runtime properties loaded from the standalone properties file.
*/
- public Properties runtimeProperties;
+ public Properties runtimeProperties = new Properties();
/**
* Whether to reset the extraction directory on startup.
@@ -380,7 +384,11 @@ public class TomcatRunner {
Connector ajpConnector = new
Connector("org.apache.coyote.ajp.AjpProtocol");
ajpConnector.setPort(ajpPort);
ajpConnector.setURIEncoding(uriEncoding);
- ajpConnector.setProperty("secretRequired", "false");
+ if (ajpSecret != null) {
+ ajpConnector.setProperty("secret", ajpSecret);
+ } else {
+ ajpConnector.setProperty("secretRequired", "false");
+ }
tomcat.getService().addConnector(ajpConnector);
}
@@ -563,6 +571,9 @@ public class TomcatRunner {
throw new Exception("FATAL: impossible to create
directories:" + parentFile);
}
+ if (inputStream == null) {
+ throw new IOException("War resource not found on
classpath: " + entry.getValue());
+ }
expand(inputStream, expandFile);
} finally {
@@ -613,7 +624,7 @@ public class TomcatRunner {
}
/**
- * @param warsValue we can value in format:
wars=foo.war|contextpath;bar.war ( |contextpath is optionnal if empty
+ * @param warsValue we can value in format:
wars=foo.war|contextpath;bar.war ( |contextpath is optional if empty
* use the war name) so here we return war file name
and populate webappWarPerContext
*/
private void populateWebAppWarPerContext(String warsValue) {
@@ -631,9 +642,9 @@ public class TomcatRunner {
if (separatorIndex >= 0) {
warFileName = warValue.substring(0, separatorIndex);
contextValue = warValue.substring(separatorIndex + 1);
-
} else {
- warFileName = contextValue;
+ warFileName = warValue;
+ contextValue = warValue;
}
debugMessage("populateWebAppWarPerContext
contextValue/warFileName:" + contextValue + "/" + warFileName);
this.webappWarPerContext.put(contextValue, warFileName);
diff --git a/src/main/java/org/apache/tomcat/maven/runner/TomcatRunnerCli.java
b/src/main/java/org/apache/tomcat/maven/runner/TomcatRunnerCli.java
index f701055..77990eb 100644
--- a/src/main/java/org/apache/tomcat/maven/runner/TomcatRunnerCli.java
+++ b/src/main/java/org/apache/tomcat/maven/runner/TomcatRunnerCli.java
@@ -63,6 +63,9 @@ public class TomcatRunnerCli {
static final Option AJP_PORT =
Option.builder().longOpt("ajpPort").hasArg().argName("ajpPort")
.desc("ajp port to use").get();
+ static final Option AJP_SECRET =
Option.builder().longOpt("ajpSecret").hasArg().argName("ajpSecret")
+ .desc("ajp secret to use").get();
+
static final Option SERVER_XML_PATH =
Option.builder().longOpt("serverXmlPath").hasArg().argName("serverXmlPath")
.desc("server.xml to use, optional").get();
@@ -97,7 +100,7 @@ public class TomcatRunnerCli {
static final Options OPTIONS = new Options();
static {
-
OPTIONS.addOption(HTTP_PORT).addOption(HTTPS_PORT).addOption(AJP_PORT).addOption(MAX_POST_SIZE)
+
OPTIONS.addOption(HTTP_PORT).addOption(HTTPS_PORT).addOption(AJP_PORT).addOption(AJP_SECRET).addOption(MAX_POST_SIZE)
.addOption(SERVER_XML_PATH).addOption(RESET_EXTRACT).addOption(HELP).addOption(DEBUG)
.addOption(SYS_PROPS).addOption(HTTP_PROTOCOL).addOption(CLIENT_AUTH).addOption(KEY_ALIAS)
.addOption(OBFUSCATE).addOption(EXTRACT_DIRECTORY).addOption(URI_ENCODING);
@@ -145,23 +148,55 @@ public class TomcatRunnerCli {
String port =
tomcatRunner.runtimeProperties.getProperty(TomcatRunner.HTTP_PORT_KEY);
if (port != null) {
- tomcatRunner.httpPort = Integer.parseInt(port);
+ try {
+ tomcatRunner.httpPort = Integer.parseInt(port);
+ } catch (NumberFormatException e) {
+ System.err.println("Invalid value for " +
HTTP_PORT.getArgName() + " '" +
+ port + "'. Must be an integer.");
+ System.exit(1);
+ System.exit(1);
+ }
}
// cli win for the port
if (line.hasOption(HTTP_PORT)) {
- tomcatRunner.httpPort =
Integer.parseInt(line.getOptionValue(HTTP_PORT));
+ try {
+ tomcatRunner.httpPort =
Integer.parseInt(line.getOptionValue(HTTP_PORT));
+ } catch (NumberFormatException e) {
+ System.err.println("Invalid value for " +
HTTP_PORT.getArgName() + " '" +
+ line.getOptionValue(HTTP_PORT) + "'. Must be an
integer.");
+ System.exit(1);
+ }
}
-
if (line.hasOption(MAX_POST_SIZE)) {
- tomcatRunner.maxPostSize =
Integer.parseInt(line.getOptionValue(MAX_POST_SIZE));
+ try {
+ tomcatRunner.maxPostSize =
Integer.parseInt(line.getOptionValue(MAX_POST_SIZE));
+ } catch (NumberFormatException e) {
+ System.err.println("Invalid value for " +
MAX_POST_SIZE.getArgName() + " '" +
+ line.getOptionValue(MAX_POST_SIZE) + "'. Must be an
integer.");
+ System.exit(1);
+ }
}
-
if (line.hasOption(HTTPS_PORT)) {
- tomcatRunner.httpsPort =
Integer.parseInt(line.getOptionValue(HTTPS_PORT));
+ try {
+ tomcatRunner.httpsPort =
Integer.parseInt(line.getOptionValue(HTTPS_PORT));
+ } catch (NumberFormatException e) {
+ System.err.println("Invalid value for " +
HTTPS_PORT.getArgName() + " '" +
+ line.getOptionValue(HTTPS_PORT) + "'. Must be an
integer.");
+ System.exit(1);
+ }
}
if (line.hasOption(AJP_PORT)) {
- tomcatRunner.ajpPort =
Integer.parseInt(line.getOptionValue(AJP_PORT));
+ try {
+ tomcatRunner.ajpPort =
Integer.parseInt(line.getOptionValue(AJP_PORT));
+ } catch (NumberFormatException e) {
+ System.err.println("Invalid value for " +
AJP_PORT.getArgName() + " '" +
+ line.getOptionValue(AJP_PORT) + "'. Must be an
integer.");
+ System.exit(1);
+ }
+ }
+ if (line.hasOption(AJP_SECRET)) {
+ tomcatRunner.ajpSecret = line.getOptionValue(AJP_SECRET);
}
if (line.hasOption(RESET_EXTRACT)) {
tomcatRunner.resetExtract = true;
@@ -205,7 +240,9 @@ public class TomcatRunnerCli {
InputStream is = Thread.currentThread().getContextClassLoader()
.getResourceAsStream(STAND_ALONE_PROPERTIES_FILENAME);
Properties properties = new Properties();
- properties.load(is);
+ if (is != null) {
+ properties.load(is);
+ }
return properties;
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]