Skip to content

Commit

Permalink
Remove support for multiple WAR files (#377)
Browse files Browse the repository at this point in the history
  • Loading branch information
basil committed May 3, 2024
1 parent 952786c commit 5a65223
Show file tree
Hide file tree
Showing 6 changed files with 13 additions and 119 deletions.
21 changes: 1 addition & 20 deletions README.md
Expand Up @@ -37,10 +37,6 @@ To run a single war file:

java -jar winstone.jar --warfile=<location of warfile> (+ other options)

To run a directory full of war files:

java -jar winstone.jar --webappsDir=<location of webapps directory> (+ other options)

To run locally exploded web archive:

java -jar winstone.jar --webroot=<location of webroot> (+ other options)
Expand All @@ -51,10 +47,9 @@ To run locally exploded web archive:
Winstone Servlet Engine, (c) 2003-2006 Rick Knowles
Usage: java winstone.jar [--option=value] [--option=value] [etc]

Required options: either --webroot OR --warfile OR --webappsDir
Required options: either --webroot OR --warfile
--webroot = set document root folder.
--warfile = set location of warfile to extract from.
--webappsDir = set directory for multiple webapps to be deployed from
Other options:
--javaHome = Override the JAVA_HOME variable
--config = load configuration properties from here. Default is ./winstone.properties
Expand Down Expand Up @@ -146,20 +141,6 @@ just supply the warfile or webroot directory as an argument:
* `java -jar winstone.jar --webroot=<webroot>`, or
* `java -jar winstone.jar --warfile=<warfile>`

If you need to support *multiple webapps*, use the `--webappsDir` switch,
to which you pass a directory that contains multiple warfiles/webroots.

* `java -jar winstone.jar --webappsDir=<dir containing multiple webroots>`

The directory becomes the prefix name for that webapp (so hello becomes `/hello`, etc).
The directory named ROOT becomes the no-prefix webapp.

So, for example, if you had a directory `/usr/local/webapps` which contained
sub-directories `ROOT` and `test`, if you executed
`java -jar winstone.jar --webappsDir=/usr/local/webapps`, you would find that
the test folder would act as a webroot for requests prefixed with
`/test`, while other requests would go to the webapp in the `ROOT` folder

## Development
If you have some unit test failures you may add an interface/ip alias such

Expand Down
83 changes: 7 additions & 76 deletions src/main/java/winstone/HostConfiguration.java
Expand Up @@ -13,7 +13,6 @@
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.RequestLog;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
import org.eclipse.jetty.server.handler.RequestLogHandler;
import org.eclipse.jetty.webapp.WebAppContext;
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer;
Expand Down Expand Up @@ -58,8 +57,8 @@ public class HostConfiguration {
private MimeTypes mimeTypes = new MimeTypes();
private final LoginService loginService;

public HostConfiguration(Server server, String hostname, ClassLoader commonLibCL,
@NonNull Map<String, String> args, File webappsDir) throws IOException {
public HostConfiguration(Server server, String hostname, ClassLoader commonLibCL, @NonNull Map<String, String> args)
throws IOException {
this.server = server;
this.hostname = hostname;
this.args = new HashMap<>(args);
Expand All @@ -79,18 +78,12 @@ public HostConfiguration(Server server, String hostname, ClassLoader commonLibCL
File warfile = Option.WARFILE.get(this.args);
File webroot = Option.WEBROOT.get(this.args);

Handler handler;
// If single-webapp mode
if (webappsDir == null && ((warfile != null) || (webroot != null))) {
String prefix = Option.PREFIX.get(this.args);
if (prefix.endsWith("/")) // trim off the trailing '/' that Jetty doesn't like
prefix = prefix.substring(0,prefix.length()-1);
handler = configureAccessLog(create(getWebRoot(webroot,warfile), prefix),"webapp");
}
// Otherwise multi-webapp mode
else {
handler = initMultiWebappDir(webappsDir);
String prefix = Option.PREFIX.get(this.args);
if (prefix.endsWith("/")) {
// trim off the trailing '/' that Jetty doesn't like
prefix = prefix.substring(0, prefix.length() - 1);
}
Handler handler = configureAccessLog(create(getWebRoot(webroot, warfile), prefix), "webapp");

{// load additional mime types
loadBuiltinMimeTypes();
Expand Down Expand Up @@ -343,66 +336,4 @@ private void deleteRecursive(File dir) {
Logger.logDirectMessage(Level.WARNING, null, "Failed to delete dirs " + dir.getAbsolutePath(), ex);
}
}

@SuppressFBWarnings(value = "PATH_TRAVERSAL_IN", justification = "false positive, we're not being called from a webapp")
protected ContextHandlerCollection initMultiWebappDir(File webappsDir) {
ContextHandlerCollection webApps = new ContextHandlerCollection();

if (webappsDir == null) {
webappsDir = new File("webapps");
}
if (!webappsDir.exists()) {
throw new WinstoneException(Launcher.RESOURCES.getString("HostConfig.WebAppDirNotFound", webappsDir.getPath()));
} else if (!webappsDir.isDirectory()) {
throw new WinstoneException(Launcher.RESOURCES.getString("HostConfig.WebAppDirIsNotDirectory", webappsDir.getPath()));
} else {
File[] children = webappsDir.listFiles();
if (children != null) {
for (File aChildren : children) {
String childName = aChildren.getName();

// Check any directories for warfiles that match, and skip: only deploy the war file
if (aChildren.isDirectory()) {
File matchingWarFile = new File(webappsDir, aChildren.getName() + ".war");
if (matchingWarFile.exists() && matchingWarFile.isFile()) {
Logger.log(Level.FINER, Launcher.RESOURCES, "HostConfig.SkippingWarfileDir", childName);
} else {
String prefix = childName.equalsIgnoreCase("ROOT") ? "" : "/" + childName;
if (!this.webapps.containsKey(prefix)) {
try {
WebAppContext context = create(aChildren, prefix);
webApps.addHandler(configureAccessLog(context,childName));
Logger.log(Level.INFO, Launcher.RESOURCES, "HostConfig.DeployingWebapp", childName);
} catch (Throwable err) {
Logger.log(Level.SEVERE, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
}
}
}
} else if (childName.endsWith(".war")) {
String outputName = childName.substring(0, childName.lastIndexOf(".war"));
String prefix = outputName.equalsIgnoreCase("ROOT") ? "" : "/" + outputName;

if (!this.webapps.containsKey(prefix)) {
File outputDir = new File(webappsDir, outputName);
try {
Files.createDirectories(outputDir.toPath());
} catch (Exception ex) {
Logger.logDirectMessage(Level.WARNING, null, "Failed to mkdirs " + outputDir.getAbsolutePath(), ex);
}
try {
WebAppContext context = create(
getWebRoot(new File(webappsDir, outputName), aChildren), prefix);
webApps.addHandler(configureAccessLog(context,outputName));
Logger.log(Level.INFO, Launcher.RESOURCES, "HostConfig.DeployingWebapp", childName);
} catch (Throwable err) {
Logger.log(Level.SEVERE, Launcher.RESOURCES, "HostConfig.WebappInitError", prefix, err);
}
}
}
}
}
}

return webApps;
}
}
15 changes: 3 additions & 12 deletions src/main/java/winstone/HostGroup.java
Expand Up @@ -7,9 +7,7 @@
package winstone;

import org.eclipse.jetty.server.Server;
import winstone.cmdline.Option;

import java.io.File;
import java.io.IOException;
import java.util.Hashtable;
import java.util.Map;
Expand Down Expand Up @@ -38,12 +36,8 @@ public HostGroup(
this.server = server;
this.hostConfigs = new Hashtable<>();

// Is this the single or multiple configuration ? Check args
File webappsDir = Option.WEBAPPS_DIR.get(args);

// If host mode
initHost(webappsDir, DEFAULT_HOSTNAME, commonLibCL,
args);
initHost(DEFAULT_HOSTNAME, commonLibCL, args);
this.defaultHostName = DEFAULT_HOSTNAME;
Logger.log(Level.FINER, Launcher.RESOURCES, "HostGroup.InitSingleComplete",
this.hostConfigs.size() + "", this.hostConfigs.keySet() + "");
Expand All @@ -59,12 +53,9 @@ public HostConfiguration getHostByName(String hostname) {
return this.hostConfigs.get(this.defaultHostName);
}

protected void initHost(File webappsDir, String hostname,
ClassLoader commonLibCL,
Map<String, String> args) throws IOException {
protected void initHost(String hostname, ClassLoader commonLibCL, Map<String, String> args) throws IOException {
Logger.log(Level.FINER, Launcher.RESOURCES, "HostGroup.DeployingHost", hostname);
HostConfiguration config = new HostConfiguration(server, hostname, commonLibCL,
args, webappsDir);
HostConfiguration config = new HostConfiguration(server, hostname, commonLibCL, args);
this.hostConfigs.put(hostname, config);
}
}
4 changes: 1 addition & 3 deletions src/main/java/winstone/Launcher.java
Expand Up @@ -484,8 +484,7 @@ public static void main(String[] argv) throws IOException {
deployEmbeddedWarfile(args);

// Check for embedded warfile
if (!Option.WEBROOT.isIn(args) && !Option.WARFILE.isIn(args)
&& !Option.WEBAPPS_DIR.isIn(args)) {
if (!Option.WEBROOT.isIn(args) && !Option.WARFILE.isIn(args)) {

Check warning on line 487 in src/main/java/winstone/Launcher.java

View check run for this annotation

ci.jenkins.io / Code Coverage

Not covered line

Line 487 is not covered by tests
printUsage();
return;
}
Expand Down Expand Up @@ -561,7 +560,6 @@ protected static void deployEmbeddedWarfile(Map<String, String> args) throws IOE

Option.WARFILE.put(args, tempWarfile.getAbsolutePath());
Option.WARFILE.put(args, tempWebroot.getAbsolutePath());
Option.WEBAPPS_DIR.remove(args);
}
}

Expand Down
1 change: 0 additions & 1 deletion src/main/java/winstone/cmdline/Option.java
Expand Up @@ -37,7 +37,6 @@ public static List<Option<?>> all(Class<?> clazz) {

public static final OFile WEBROOT=file("webroot");
public static final OFile WARFILE=file("warfile");
public static final OFile WEBAPPS_DIR=file("webappsDir");
public static final OFile JAVA_HOME=file("javaHome");
public static final OFile CONFIG=file("config");
public static final OString PREFIX=string("prefix","");
Expand Down
8 changes: 1 addition & 7 deletions src/main/resources/winstone/LocalStrings.properties
Expand Up @@ -4,16 +4,11 @@ WebAppConfig.LoggerError=Error instantiating access logger class: [#0]
WebAppConfig.LoggerDisabled=Access logging disabled - no logger class defined

HostConfig.PrefixUnknown=Unknown webapp prefix: [#0]
HostConfig.WebAppDirNotFound=Webapps dir [#0] not found
HostConfig.WebAppDirIsNotDirectory=Webapps dir [#0] is not a directory
HostConfig.InitComplete=Initialized [#0] webapps: prefixes - [#1]
HostConfig.SkippingWarfileDir=Webapp dir deployment [#0] skipped, since there is a war file of the same name to check for re-extraction
HostConfig.DeployingWebapp=Deployed web application found at [#0]
HostConfig.WarFileInvalid=The warfile supplied is unavailable or invalid ([#0])
HostConfig.WebRootNotDirectory=The webroot supplied is not a valid directory ([#0])
HostConfig.WebRootExists=The webroot supplied already exists - overwriting where newer ([#0])
HostConfig.BeginningWarExtraction=Beginning extraction from war file
HostConfig.WebappInitError=Error initializing web application: prefix [[#0]]

HostGroup.InitSingleComplete=Initialized in non-virtual-host mode
HostGroup.DeployingHost=Deploying host found at [#0]
Expand Down Expand Up @@ -47,10 +42,9 @@ Launcher.ExtraLibFolder=You are using an extra library folder, support for which
# Keep synchronized with jenkinsci/jenkins/war/src/main/java/executable/Main.java
Launcher.UsageInstructions.Header=[#0], (c) 2003-2006 Rick Knowles\n\
Usage: java winstone.jar [--option=value] [--option=value] [etc]\n\n\
Required options: either --webroot OR --warfile OR --webappsDir \n\
Required options: either --webroot OR --warfile \n\
\ --webroot = set document root folder.\n\
\ --warfile = set location of warfile to extract from.\n\
\ --webappsDir = set directory for multiple webapps to be deployed from\n\
Other options:\n\
Launcher.UsageInstructions.Options=\
Expand Down

0 comments on commit 5a65223

Please sign in to comment.