parent
67d93f9f74
commit
2acb97db2f
|
@ -10,8 +10,8 @@
|
||||||
<name>Jetty :: Jetty Maven Plugin</name>
|
<name>Jetty :: Jetty Maven Plugin</name>
|
||||||
<description>Jetty maven plugins</description>
|
<description>Jetty maven plugins</description>
|
||||||
<properties>
|
<properties>
|
||||||
<mavenVersion>3.0.3</mavenVersion>
|
<mavenVersion>3.5.0</mavenVersion>
|
||||||
<pluginToolsVersion>3.4</pluginToolsVersion>
|
<pluginToolsVersion>3.5</pluginToolsVersion>
|
||||||
<bundle-symbolic-name>${project.groupId}.maven.plugin</bundle-symbolic-name>
|
<bundle-symbolic-name>${project.groupId}.maven.plugin</bundle-symbolic-name>
|
||||||
<it.debug>false</it.debug>
|
<it.debug>false</it.debug>
|
||||||
<jetty.stopKey>FOOBEER</jetty.stopKey>
|
<jetty.stopKey>FOOBEER</jetty.stopKey>
|
||||||
|
@ -80,6 +80,11 @@
|
||||||
<version>${pluginToolsVersion}</version>
|
<version>${pluginToolsVersion}</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.maven.shared</groupId>
|
||||||
|
<artifactId>maven-artifact-transfer</artifactId>
|
||||||
|
<version>0.9.1</version>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.eclipse.jetty</groupId>
|
<groupId>org.eclipse.jetty</groupId>
|
||||||
<artifactId>jetty-util</artifactId>
|
<artifactId>jetty-util</artifactId>
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.maven.plugin;
|
package org.eclipse.jetty.maven.plugin;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
|
@ -55,6 +58,7 @@ import org.eclipse.jetty.server.handler.HandlerCollection;
|
||||||
import org.eclipse.jetty.util.PathWatcher;
|
import org.eclipse.jetty.util.PathWatcher;
|
||||||
import org.eclipse.jetty.util.StringUtil;
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -538,8 +542,15 @@ public abstract class AbstractJettyMojo extends AbstractMojo
|
||||||
//context xml file can OVERRIDE those settings
|
//context xml file can OVERRIDE those settings
|
||||||
if (contextXml != null)
|
if (contextXml != null)
|
||||||
{
|
{
|
||||||
File file = FileUtils.getFile(contextXml);
|
Path path = Paths.get(contextXml);
|
||||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(file));
|
if (!path.isAbsolute())
|
||||||
|
{
|
||||||
|
Path workDir = Paths.get(System.getProperty("user.dir"));
|
||||||
|
path = workDir.resolve(path);
|
||||||
|
contextXml = path.toFile().getAbsolutePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(path.toFile()));
|
||||||
getLog().info("Applying context xml file "+contextXml);
|
getLog().info("Applying context xml file "+contextXml);
|
||||||
xmlConfiguration.configure(webApp);
|
xmlConfiguration.configure(webApp);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,514 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
package org.eclipse.jetty.maven.plugin;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.file.FileAlreadyExistsException;
|
||||||
|
import java.nio.file.FileVisitOption;
|
||||||
|
import java.nio.file.FileVisitResult;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.nio.file.SimpleFileVisitor;
|
||||||
|
import java.nio.file.attribute.BasicFileAttributes;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.apache.maven.artifact.Artifact;
|
||||||
|
import org.apache.maven.artifact.repository.ArtifactRepository;
|
||||||
|
import org.apache.maven.execution.MavenSession;
|
||||||
|
import org.apache.maven.model.Dependency;
|
||||||
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
|
import org.apache.maven.plugin.MojoFailureException;
|
||||||
|
import org.apache.maven.plugin.descriptor.PluginDescriptor;
|
||||||
|
import org.apache.maven.project.DefaultProjectBuildingRequest;
|
||||||
|
import org.apache.maven.project.ProjectBuildingRequest;
|
||||||
|
import org.apache.maven.shared.artifact.DefaultArtifactCoordinate;
|
||||||
|
import org.apache.maven.shared.artifact.resolve.ArtifactResolver;
|
||||||
|
import org.apache.maven.shared.artifact.resolve.ArtifactResolverException;
|
||||||
|
import org.eclipse.jetty.util.IO;
|
||||||
|
import org.eclipse.jetty.util.TypeUtil;
|
||||||
|
import org.eclipse.jetty.util.resource.JarResource;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JettyRunDistro
|
||||||
|
*
|
||||||
|
* @goal run-distro
|
||||||
|
* @requiresDependencyResolution test
|
||||||
|
* @execute phase="test-compile"
|
||||||
|
* @description Runs unassembled webapp in a locally installed jetty distro
|
||||||
|
*/
|
||||||
|
public class JettyRunDistro extends JettyRunMojo
|
||||||
|
{
|
||||||
|
|
||||||
|
public static final String JETTY_HOME_GROUPID = "org.eclipse.jetty";
|
||||||
|
public static final String JETTY_HOME_ARTIFACTID = "jetty-home";
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This plugin
|
||||||
|
*
|
||||||
|
* @parameter default-value="${plugin}"
|
||||||
|
* @readonly
|
||||||
|
* @required
|
||||||
|
*/
|
||||||
|
protected PluginDescriptor plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The target directory
|
||||||
|
*
|
||||||
|
* @parameter default-value="${project.build.directory}"
|
||||||
|
* @required
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
protected File target;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @parameter
|
||||||
|
*/
|
||||||
|
private File jettyHome;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @parameter
|
||||||
|
*/
|
||||||
|
private File jettyBase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional list of other modules to
|
||||||
|
* activate.
|
||||||
|
* @parameter
|
||||||
|
*/
|
||||||
|
private String[] modules;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Optional list of jetty properties to put on the command line
|
||||||
|
* @parameter
|
||||||
|
*/
|
||||||
|
private String[] properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @parameter default-value="${session}"
|
||||||
|
* @required
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
private MavenSession session;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The project's remote repositories to use for the resolution.
|
||||||
|
*
|
||||||
|
* @parameter default-value="${project.remoteArtifactRepositories}"
|
||||||
|
* @required
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
private List<ArtifactRepository> remoteRepositories;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @component
|
||||||
|
*/
|
||||||
|
private ArtifactResolver artifactResolver;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @parameter default-value="${plugin.version}"
|
||||||
|
* @readonly
|
||||||
|
*/
|
||||||
|
private String pluginVersion;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @parameter default-value="true"
|
||||||
|
*/
|
||||||
|
private boolean waitForChild;
|
||||||
|
|
||||||
|
|
||||||
|
private File targetBase;
|
||||||
|
|
||||||
|
private List<Dependency> libExtJars;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// IDEAS:
|
||||||
|
// 5. try to use the scanner as normal and remake the properties and context.xml file to get the
|
||||||
|
// deployer to automatically redeploy it on changes.
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.maven.plugin.JettyRunMojo#execute()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void execute() throws MojoExecutionException, MojoFailureException
|
||||||
|
{
|
||||||
|
List<Dependency> pdeps = plugin.getPlugin().getDependencies();
|
||||||
|
if (pdeps != null && !pdeps.isEmpty())
|
||||||
|
{
|
||||||
|
boolean warned = false;
|
||||||
|
for (Dependency d:pdeps)
|
||||||
|
{
|
||||||
|
if (d.getGroupId().equalsIgnoreCase("org.eclipse.jetty"))
|
||||||
|
{
|
||||||
|
if (!warned)
|
||||||
|
{
|
||||||
|
getLog().warn("Jetty jars detected in <pluginDependencies>: use <modules> in <configuration> parameter instead to select appropriate jetty modules.");
|
||||||
|
warned = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (libExtJars == null)
|
||||||
|
libExtJars = new ArrayList<>();
|
||||||
|
libExtJars.add(d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
super.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#startJetty()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void startJetty() throws MojoExecutionException
|
||||||
|
{
|
||||||
|
//don't start jetty locally, set up enough configuration to run a new process
|
||||||
|
//with a jetty distro
|
||||||
|
try
|
||||||
|
{
|
||||||
|
printSystemProperties();
|
||||||
|
|
||||||
|
//download and install jetty-home if necessary
|
||||||
|
configureJettyHome();
|
||||||
|
|
||||||
|
//ensure config of the webapp based on settings in plugin
|
||||||
|
configureWebApplication();
|
||||||
|
|
||||||
|
//configure jetty base
|
||||||
|
configureJettyBase();
|
||||||
|
|
||||||
|
//create the command to run the new process
|
||||||
|
ProcessBuilder command = configureCommand();
|
||||||
|
|
||||||
|
|
||||||
|
if (waitForChild)
|
||||||
|
{
|
||||||
|
command.inheritIO();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
command.redirectErrorStream(true);
|
||||||
|
command.redirectOutput(new File(target, "jetty.out"));
|
||||||
|
}
|
||||||
|
|
||||||
|
Process process = command.start();
|
||||||
|
|
||||||
|
if (waitForChild)
|
||||||
|
process.waitFor();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
throw new MojoExecutionException("Failed to start Jetty", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If jetty home does not exist, download it and
|
||||||
|
* unpack to build dir.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void configureJettyHome() throws Exception
|
||||||
|
{
|
||||||
|
if (jettyHome == null)
|
||||||
|
{
|
||||||
|
//no jetty home, download from repo and unpack it. Get the same version as the plugin
|
||||||
|
Artifact jettyHomeArtifact = resolveArtifact(JETTY_HOME_GROUPID, JETTY_HOME_ARTIFACTID, pluginVersion, "zip");
|
||||||
|
JarResource res = (JarResource) JarResource.newJarResource(Resource.newResource(jettyHomeArtifact.getFile()));
|
||||||
|
res.copyTo(target);
|
||||||
|
//zip will unpack to target/jetty-home-<VERSION>
|
||||||
|
jettyHome = new File (target, JETTY_HOME_ARTIFACTID+"-"+pluginVersion);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!jettyHome.exists())
|
||||||
|
throw new IllegalStateException(jettyHome.getAbsolutePath()+" does not exist");
|
||||||
|
}
|
||||||
|
|
||||||
|
getLog().info("jetty.home = "+jettyHome.getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve an Artifact from remote repo if necessary.
|
||||||
|
*
|
||||||
|
* @param groupId the groupid of the artifact
|
||||||
|
* @param artifactId the artifactId of the artifact
|
||||||
|
* @param version the version of the artifact
|
||||||
|
* @param extension the extension type of the artifact eg "zip", "jar"
|
||||||
|
* @return the artifact from the local or remote repo
|
||||||
|
* @throws ArtifactResolverException
|
||||||
|
*/
|
||||||
|
public Artifact resolveArtifact (String groupId, String artifactId, String version, String extension)
|
||||||
|
throws ArtifactResolverException
|
||||||
|
{
|
||||||
|
DefaultArtifactCoordinate coordinate = new DefaultArtifactCoordinate();
|
||||||
|
coordinate.setGroupId(groupId);
|
||||||
|
coordinate.setArtifactId(artifactId);
|
||||||
|
coordinate.setVersion(version);
|
||||||
|
coordinate.setExtension(extension);
|
||||||
|
|
||||||
|
ProjectBuildingRequest buildingRequest =
|
||||||
|
new DefaultProjectBuildingRequest(session.getProjectBuildingRequest());
|
||||||
|
|
||||||
|
buildingRequest.setRemoteRepositories(remoteRepositories);
|
||||||
|
|
||||||
|
return artifactResolver.resolveArtifact( buildingRequest, coordinate ).getArtifact();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create or configure a jetty base.
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void configureJettyBase() throws Exception
|
||||||
|
{
|
||||||
|
if (jettyBase != null && !jettyBase.exists())
|
||||||
|
throw new IllegalStateException(jettyBase.getAbsolutePath() +" does not exist");
|
||||||
|
|
||||||
|
targetBase = new File(target, "jetty-base");
|
||||||
|
Path targetBasePath = targetBase.toPath();
|
||||||
|
if (Files.exists(targetBasePath))
|
||||||
|
IO.delete(targetBase);
|
||||||
|
|
||||||
|
targetBase.mkdirs();
|
||||||
|
|
||||||
|
if (jettyBase != null)
|
||||||
|
{
|
||||||
|
Path jettyBasePath = jettyBase.toPath();
|
||||||
|
|
||||||
|
//copy the existing jetty base
|
||||||
|
Files.walkFileTree(jettyBasePath,EnumSet.of(FileVisitOption.FOLLOW_LINKS),
|
||||||
|
Integer.MAX_VALUE,
|
||||||
|
new SimpleFileVisitor<Path>()
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @see java.nio.file.SimpleFileVisitor#preVisitDirectory(java.lang.Object, java.nio.file.attribute.BasicFileAttributes)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) throws IOException
|
||||||
|
{
|
||||||
|
Path targetDir = targetBasePath.resolve(jettyBasePath.relativize(dir));
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Files.copy(dir, targetDir);
|
||||||
|
}
|
||||||
|
catch (FileAlreadyExistsException e)
|
||||||
|
{
|
||||||
|
if (!Files.isDirectory(targetDir)) //ignore attempt to recreate dir
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see java.nio.file.SimpleFileVisitor#visitFile(java.lang.Object, java.nio.file.attribute.BasicFileAttributes)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException
|
||||||
|
{
|
||||||
|
if (contextXml != null && Files.isSameFile(Paths.get(contextXml), file))
|
||||||
|
return FileVisitResult.CONTINUE; //skip copying the context xml file
|
||||||
|
Files.copy(file, targetBasePath.resolve(jettyBasePath.relativize(file)));
|
||||||
|
return FileVisitResult.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
//make the jetty base structure
|
||||||
|
Path modulesPath = Files.createDirectories(targetBasePath.resolve("modules"));
|
||||||
|
Path etcPath = Files.createDirectories(targetBasePath.resolve("etc"));
|
||||||
|
Path libPath = Files.createDirectories(targetBasePath.resolve("lib"));
|
||||||
|
Path webappPath = Files.createDirectories(targetBasePath.resolve("webapps"));
|
||||||
|
Path mavenLibPath = Files.createDirectories(libPath.resolve("maven"));
|
||||||
|
|
||||||
|
//copy in the jetty-maven-plugin jar
|
||||||
|
URI thisJar = TypeUtil.getLocationOfClass(this.getClass());
|
||||||
|
if (thisJar == null)
|
||||||
|
throw new IllegalStateException("Can't find jar for jetty-maven-plugin");
|
||||||
|
|
||||||
|
try(InputStream jarStream = thisJar.toURL().openStream();
|
||||||
|
FileOutputStream fileStream = new FileOutputStream(mavenLibPath.resolve("plugin.jar").toFile()))
|
||||||
|
{
|
||||||
|
IO.copy(jarStream,fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy in the maven.xml webapp file
|
||||||
|
try (InputStream mavenXmlStream = getClass().getClassLoader().getResourceAsStream("maven.xml");
|
||||||
|
FileOutputStream fileStream = new FileOutputStream(webappPath.resolve("maven.xml").toFile()))
|
||||||
|
{
|
||||||
|
IO.copy(mavenXmlStream, fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
//copy in the maven.mod file
|
||||||
|
try (InputStream mavenModStream = getClass().getClassLoader().getResourceAsStream("maven.mod");
|
||||||
|
FileOutputStream fileStream = new FileOutputStream(modulesPath.resolve("maven.mod").toFile()))
|
||||||
|
{
|
||||||
|
IO.copy(mavenModStream, fileStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
//if there were plugin dependencies, copy them into lib/ext
|
||||||
|
if (libExtJars != null && !libExtJars.isEmpty())
|
||||||
|
{
|
||||||
|
Path libExtPath = Files.createDirectories(libPath.resolve("ext"));
|
||||||
|
for (Dependency d:libExtJars)
|
||||||
|
{
|
||||||
|
Artifact a = resolveArtifact(d.getGroupId(), d.getArtifactId(), d.getVersion(), d.getType());
|
||||||
|
try (InputStream jarStream = new FileInputStream(a.getFile());
|
||||||
|
FileOutputStream fileStream = new FileOutputStream(libExtPath.resolve(d.getGroupId()+"."+d.getArtifactId()+"-"+d.getVersion()+"."+d.getType()).toFile()))
|
||||||
|
{
|
||||||
|
IO.copy(jarStream, fileStream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//create properties file that describes the webapp
|
||||||
|
createPropertiesFile(etcPath.resolve("maven.props").toFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert webapp config to properties
|
||||||
|
*
|
||||||
|
* @param file the file to place the properties into
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public void createPropertiesFile (File file)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
WebAppPropertyConverter.toProperties(webApp, file, contextXml);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Make the command to spawn a process to
|
||||||
|
* run jetty from a distro.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ProcessBuilder configureCommand()
|
||||||
|
{
|
||||||
|
List<String> cmd = new ArrayList<>();
|
||||||
|
cmd.add("java");
|
||||||
|
cmd.add("-jar");
|
||||||
|
cmd.add(new File(jettyHome, "start.jar").getAbsolutePath());
|
||||||
|
cmd.add("-DSTOP.PORT="+stopPort);
|
||||||
|
if (stopKey != null)
|
||||||
|
cmd.add("-DSTOP.KEY="+stopKey);
|
||||||
|
|
||||||
|
StringBuilder tmp = new StringBuilder();
|
||||||
|
tmp.append("--module=");
|
||||||
|
tmp.append("server,http,webapp,deploy");
|
||||||
|
if (modules != null)
|
||||||
|
{
|
||||||
|
for (String m:modules)
|
||||||
|
{
|
||||||
|
if (tmp.indexOf(m) < 0)
|
||||||
|
tmp.append(","+m);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (libExtJars != null && !libExtJars.isEmpty() && tmp.indexOf("ext") < 0)
|
||||||
|
tmp.append(",ext");
|
||||||
|
tmp.append(",maven");
|
||||||
|
|
||||||
|
cmd.add(tmp.toString());
|
||||||
|
|
||||||
|
|
||||||
|
if (properties != null)
|
||||||
|
{
|
||||||
|
tmp.delete(0, tmp.length());
|
||||||
|
for (String p:properties)
|
||||||
|
tmp.append(" "+p);
|
||||||
|
cmd.add(tmp.toString());
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
ProcessBuilder builder = new ProcessBuilder(cmd);
|
||||||
|
builder.directory(targetBase);
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#startScanner()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void startScanner() throws Exception
|
||||||
|
{
|
||||||
|
//don't scan
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#stopScanner()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void stopScanner() throws Exception
|
||||||
|
{
|
||||||
|
//don't scan
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#restartWebApp(boolean)
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void restartWebApp(boolean reconfigureScanner) throws Exception
|
||||||
|
{
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @see org.eclipse.jetty.maven.plugin.AbstractJettyMojo#configureScanner()
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void configureScanner() throws MojoExecutionException
|
||||||
|
{
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -143,9 +143,7 @@ public class JettyRunForkedMojo extends JettyRunMojo
|
||||||
*/
|
*/
|
||||||
private Random random;
|
private Random random;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private Resource originalBaseResource;
|
|
||||||
private boolean originalPersistTemp;
|
private boolean originalPersistTemp;
|
||||||
|
|
||||||
|
|
||||||
|
@ -256,9 +254,6 @@ public class JettyRunForkedMojo extends JettyRunMojo
|
||||||
|
|
||||||
//ensure config of the webapp based on settings in plugin
|
//ensure config of the webapp based on settings in plugin
|
||||||
configureWebApplication();
|
configureWebApplication();
|
||||||
|
|
||||||
//copy the base resource as configured by the plugin
|
|
||||||
originalBaseResource = webApp.getBaseResource();
|
|
||||||
|
|
||||||
//get the original persistance setting
|
//get the original persistance setting
|
||||||
originalPersistTemp = webApp.isPersistTempDirectory();
|
originalPersistTemp = webApp.isPersistTempDirectory();
|
||||||
|
@ -295,13 +290,15 @@ public class JettyRunForkedMojo extends JettyRunMojo
|
||||||
//leave everything unpacked for the forked process to use
|
//leave everything unpacked for the forked process to use
|
||||||
webApp.setPersistTempDirectory(true);
|
webApp.setPersistTempDirectory(true);
|
||||||
|
|
||||||
webApp.start(); //just enough to generate the quickstart
|
webApp.start(); //just enough to generate the quickstart
|
||||||
|
|
||||||
//save config of the webapp BEFORE we stop
|
//save config of the webapp BEFORE we stop
|
||||||
File props = prepareConfiguration();
|
File props = prepareConfiguration();
|
||||||
|
|
||||||
webApp.stop();
|
webApp.stop();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (tpool != null)
|
if (tpool != null)
|
||||||
tpool.stop();
|
tpool.stop();
|
||||||
|
|
||||||
|
@ -461,106 +458,7 @@ public class JettyRunForkedMojo extends JettyRunMojo
|
||||||
{
|
{
|
||||||
//work out the configuration based on what is configured in the pom
|
//work out the configuration based on what is configured in the pom
|
||||||
File propsFile = new File (target, "fork.props");
|
File propsFile = new File (target, "fork.props");
|
||||||
if (propsFile.exists())
|
WebAppPropertyConverter.toProperties(webApp, propsFile, contextXml);
|
||||||
propsFile.delete();
|
|
||||||
|
|
||||||
propsFile.createNewFile();
|
|
||||||
//propsFile.deleteOnExit();
|
|
||||||
|
|
||||||
Properties props = new Properties();
|
|
||||||
|
|
||||||
|
|
||||||
//web.xml
|
|
||||||
if (webApp.getDescriptor() != null)
|
|
||||||
{
|
|
||||||
props.put("web.xml", webApp.getDescriptor());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (webApp.getQuickStartWebDescriptor() != null)
|
|
||||||
{
|
|
||||||
props.put("quickstart.web.xml", webApp.getQuickStartWebDescriptor().getFile().getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
//sort out the context path
|
|
||||||
if (webApp.getContextPath() != null)
|
|
||||||
{
|
|
||||||
props.put("context.path", webApp.getContextPath());
|
|
||||||
}
|
|
||||||
|
|
||||||
//tmp dir
|
|
||||||
props.put("tmp.dir", webApp.getTempDirectory().getAbsolutePath());
|
|
||||||
props.put("tmp.dir.persist", Boolean.toString(originalPersistTemp));
|
|
||||||
|
|
||||||
//send over the original base resources before any overlays were added
|
|
||||||
if (originalBaseResource instanceof ResourceCollection)
|
|
||||||
props.put("base.dirs.orig", toCSV(((ResourceCollection)originalBaseResource).getResources()));
|
|
||||||
else
|
|
||||||
props.put("base.dirs.orig", originalBaseResource.toString());
|
|
||||||
|
|
||||||
//send over the calculated resource bases that includes unpacked overlays, but none of the
|
|
||||||
//meta-inf resources
|
|
||||||
Resource postOverlayResources = (Resource)webApp.getAttribute(MavenWebInfConfiguration.RESOURCE_BASES_POST_OVERLAY);
|
|
||||||
if (postOverlayResources instanceof ResourceCollection)
|
|
||||||
props.put("base.dirs", toCSV(((ResourceCollection)postOverlayResources).getResources()));
|
|
||||||
else
|
|
||||||
props.put("base.dirs", postOverlayResources.toString());
|
|
||||||
|
|
||||||
|
|
||||||
//web-inf classes
|
|
||||||
if (webApp.getClasses() != null)
|
|
||||||
{
|
|
||||||
props.put("classes.dir",webApp.getClasses().getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (useTestScope && webApp.getTestClasses() != null)
|
|
||||||
{
|
|
||||||
props.put("testClasses.dir", webApp.getTestClasses().getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
//web-inf lib
|
|
||||||
List<File> deps = webApp.getWebInfLib();
|
|
||||||
StringBuffer strbuff = new StringBuffer();
|
|
||||||
for (int i=0; i<deps.size(); i++)
|
|
||||||
{
|
|
||||||
File d = deps.get(i);
|
|
||||||
strbuff.append(d.getAbsolutePath());
|
|
||||||
if (i < deps.size()-1)
|
|
||||||
strbuff.append(",");
|
|
||||||
}
|
|
||||||
props.put("lib.jars", strbuff.toString());
|
|
||||||
|
|
||||||
//any war files
|
|
||||||
List<Artifact> warArtifacts = getWarArtifacts();
|
|
||||||
for (int i=0; i<warArtifacts.size(); i++)
|
|
||||||
{
|
|
||||||
strbuff.setLength(0);
|
|
||||||
Artifact a = warArtifacts.get(i);
|
|
||||||
strbuff.append(a.getGroupId()+",");
|
|
||||||
strbuff.append(a.getArtifactId()+",");
|
|
||||||
strbuff.append(a.getFile().getAbsolutePath());
|
|
||||||
props.put("maven.war.artifact."+i, strbuff.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//any overlay configuration
|
|
||||||
WarPluginInfo warPlugin = new WarPluginInfo(project);
|
|
||||||
|
|
||||||
//add in the war plugins default includes and excludes
|
|
||||||
props.put("maven.war.includes", toCSV(warPlugin.getDependentMavenWarIncludes()));
|
|
||||||
props.put("maven.war.excludes", toCSV(warPlugin.getDependentMavenWarExcludes()));
|
|
||||||
|
|
||||||
|
|
||||||
List<OverlayConfig> configs = warPlugin.getMavenWarOverlayConfigs();
|
|
||||||
int i=0;
|
|
||||||
for (OverlayConfig c:configs)
|
|
||||||
{
|
|
||||||
props.put("maven.war.overlay."+(i++), c.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(propsFile)))
|
|
||||||
{
|
|
||||||
props.store(out, "properties for forked webapp");
|
|
||||||
}
|
|
||||||
return propsFile;
|
return propsFile;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -571,29 +469,6 @@ public class JettyRunForkedMojo extends JettyRunMojo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return
|
|
||||||
* @throws MalformedURLException
|
|
||||||
* @throws IOException
|
|
||||||
*/
|
|
||||||
private List<Artifact> getWarArtifacts()
|
|
||||||
throws MalformedURLException, IOException
|
|
||||||
{
|
|
||||||
List<Artifact> warArtifacts = new ArrayList<Artifact>();
|
|
||||||
for ( Iterator<Artifact> iter = project.getArtifacts().iterator(); iter.hasNext(); )
|
|
||||||
{
|
|
||||||
Artifact artifact = iter.next();
|
|
||||||
|
|
||||||
if (artifact.getType().equals("war"))
|
|
||||||
warArtifacts.add(artifact);
|
|
||||||
}
|
|
||||||
|
|
||||||
return warArtifacts;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPluginArtifact(Artifact artifact)
|
public boolean isPluginArtifact(Artifact artifact)
|
||||||
{
|
{
|
||||||
if (pluginArtifacts == null || pluginArtifacts.isEmpty())
|
if (pluginArtifacts == null || pluginArtifacts.isEmpty())
|
||||||
|
@ -747,32 +622,4 @@ public class JettyRunForkedMojo extends JettyRunMojo
|
||||||
thread.setDaemon(true);
|
thread.setDaemon(true);
|
||||||
thread.start();
|
thread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String toCSV (List<String> strings)
|
|
||||||
{
|
|
||||||
if (strings == null)
|
|
||||||
return "";
|
|
||||||
StringBuffer strbuff = new StringBuffer();
|
|
||||||
Iterator<String> itor = strings.iterator();
|
|
||||||
while (itor.hasNext())
|
|
||||||
{
|
|
||||||
strbuff.append(itor.next());
|
|
||||||
if (itor.hasNext())
|
|
||||||
strbuff.append(",");
|
|
||||||
}
|
|
||||||
return strbuff.toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
private String toCSV (Resource[] resources)
|
|
||||||
{
|
|
||||||
StringBuffer rb = new StringBuffer();
|
|
||||||
|
|
||||||
for (Resource r:resources)
|
|
||||||
{
|
|
||||||
if (rb.length() > 0) rb.append(",");
|
|
||||||
rb.append(r.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
return rb.toString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,21 +18,9 @@
|
||||||
|
|
||||||
package org.eclipse.jetty.maven.plugin;
|
package org.eclipse.jetty.maven.plugin;
|
||||||
|
|
||||||
import org.apache.maven.artifact.Artifact;
|
|
||||||
import org.apache.maven.plugin.MojoExecutionException;
|
|
||||||
import org.apache.maven.plugin.MojoFailureException;
|
|
||||||
import org.apache.maven.plugins.annotations.Parameter;
|
|
||||||
import org.apache.maven.project.MavenProject;
|
|
||||||
import org.codehaus.plexus.util.StringUtils;
|
|
||||||
import org.eclipse.jetty.util.PathWatcher;
|
|
||||||
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
|
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.nio.file.Path;
|
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -41,8 +29,20 @@ import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collector;
|
|
||||||
import java.util.stream.Collectors;
|
import org.apache.maven.artifact.Artifact;
|
||||||
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
|
import org.apache.maven.plugin.MojoFailureException;
|
||||||
|
import org.apache.maven.plugins.annotations.Parameter;
|
||||||
|
import org.apache.maven.project.MavenProject;
|
||||||
|
import org.codehaus.plexus.util.StringUtils;
|
||||||
|
import org.eclipse.jetty.util.PathWatcher;
|
||||||
|
import org.eclipse.jetty.util.PathWatcher.PathWatchEvent;
|
||||||
|
import org.eclipse.jetty.util.resource.JarResource;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||||
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This goal is used in-situ on a Maven project without first requiring that the project
|
* This goal is used in-situ on a Maven project without first requiring that the project
|
||||||
|
@ -162,6 +162,10 @@ public class JettyRunMojo extends AbstractJettyMojo
|
||||||
* List of deps that are wars
|
* List of deps that are wars
|
||||||
*/
|
*/
|
||||||
protected List<Artifact> warArtifacts;
|
protected List<Artifact> warArtifacts;
|
||||||
|
|
||||||
|
|
||||||
|
protected Resource originalBaseResource;
|
||||||
|
|
||||||
|
|
||||||
@Parameter(defaultValue = "${reactorProjects}", readonly = true, required = true)
|
@Parameter(defaultValue = "${reactorProjects}", readonly = true, required = true)
|
||||||
private List<MavenProject> reactorProjects;
|
private List<MavenProject> reactorProjects;
|
||||||
|
@ -275,9 +279,19 @@ public class JettyRunMojo extends AbstractJettyMojo
|
||||||
Resource webAppSourceDirectoryResource = Resource.newResource(webAppSourceDirectory.getCanonicalPath());
|
Resource webAppSourceDirectoryResource = Resource.newResource(webAppSourceDirectory.getCanonicalPath());
|
||||||
if (webApp.getWar() == null)
|
if (webApp.getWar() == null)
|
||||||
webApp.setWar(webAppSourceDirectoryResource.toString());
|
webApp.setWar(webAppSourceDirectoryResource.toString());
|
||||||
|
|
||||||
if (webApp.getBaseResource() == null)
|
//The first time we run, remember the original base dir
|
||||||
webApp.setBaseResource(webAppSourceDirectoryResource);
|
if (originalBaseResource == null)
|
||||||
|
{
|
||||||
|
if (webApp.getBaseResource() == null)
|
||||||
|
originalBaseResource = webAppSourceDirectoryResource;
|
||||||
|
else
|
||||||
|
originalBaseResource = webApp.getBaseResource();
|
||||||
|
}
|
||||||
|
|
||||||
|
//On every subsequent re-run set it back to the original base dir before
|
||||||
|
//we might have applied any war overlays onto it
|
||||||
|
webApp.setBaseResource(originalBaseResource);
|
||||||
|
|
||||||
if (classesDirectory != null)
|
if (classesDirectory != null)
|
||||||
webApp.setClasses (classesDirectory);
|
webApp.setClasses (classesDirectory);
|
||||||
|
@ -286,55 +300,12 @@ public class JettyRunMojo extends AbstractJettyMojo
|
||||||
|
|
||||||
webApp.setWebInfLib(getDependencyFiles());
|
webApp.setWebInfLib(getDependencyFiles());
|
||||||
|
|
||||||
//get copy of a list of war artifacts
|
|
||||||
Set<Artifact> matchedWarArtifacts = new HashSet<Artifact>();
|
|
||||||
|
|
||||||
//process any overlays and the war type artifacts
|
//if we have not already set web.xml location, need to set one up
|
||||||
List<Overlay> overlays = new ArrayList<>();
|
if (webApp.getDescriptor() == null)
|
||||||
for (OverlayConfig config:warPluginInfo.getMavenWarOverlayConfigs())
|
|
||||||
{
|
{
|
||||||
//overlays can be individually skipped
|
//Has an explicit web.xml file been configured to use?
|
||||||
if (config.isSkip())
|
if (webXml != null)
|
||||||
continue;
|
|
||||||
|
|
||||||
//an empty overlay refers to the current project - important for ordering
|
|
||||||
if (config.isCurrentProject())
|
|
||||||
{
|
|
||||||
Overlay overlay = new Overlay(config, null);
|
|
||||||
overlays.add(overlay);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if a war matches an overlay config
|
|
||||||
Artifact a = getArtifactForOverlay(config, getWarArtifacts());
|
|
||||||
if (a != null)
|
|
||||||
{
|
|
||||||
matchedWarArtifacts.add(a);
|
|
||||||
SelectiveJarResource r = new SelectiveJarResource(new URL("jar:"+Resource.toURL(a.getFile()).toString()+"!/"));
|
|
||||||
r.setIncludes(config.getIncludes());
|
|
||||||
r.setExcludes(config.getExcludes());
|
|
||||||
Overlay overlay = new Overlay(config, r);
|
|
||||||
overlays.add(overlay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//iterate over the left over war artifacts and unpack them (without include/exclude processing) as necessary
|
|
||||||
for (Artifact a: getWarArtifacts())
|
|
||||||
{
|
|
||||||
if (!matchedWarArtifacts.contains(a))
|
|
||||||
{
|
|
||||||
Overlay overlay = new Overlay(null, Resource.newResource(new URL("jar:"+Resource.toURL(a.getFile()).toString()+"!/")));
|
|
||||||
overlays.add(overlay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
webApp.setOverlays(overlays);
|
|
||||||
|
|
||||||
//if we have not already set web.xml location, need to set one up
|
|
||||||
if (webApp.getDescriptor() == null)
|
|
||||||
{
|
|
||||||
//Has an explicit web.xml file been configured to use?
|
|
||||||
if (webXml != null)
|
|
||||||
{
|
{
|
||||||
Resource r = Resource.newResource(webXml);
|
Resource r = Resource.newResource(webXml);
|
||||||
if (r.exists() && !r.isDirectory())
|
if (r.exists() && !r.isDirectory())
|
||||||
|
@ -362,9 +333,14 @@ public class JettyRunMojo extends AbstractJettyMojo
|
||||||
webApp.setDescriptor(f.getCanonicalPath());
|
webApp.setDescriptor(f.getCanonicalPath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
getLog().info( "web.xml file = "+webApp.getDescriptor());
|
|
||||||
getLog().info("Webapp directory = " + webAppSourceDirectory.getCanonicalPath());
|
//process any overlays and the war type artifacts
|
||||||
|
List<Overlay> overlays = getOverlays();
|
||||||
|
unpackOverlays(overlays); //this sets up the base resource collection
|
||||||
|
|
||||||
|
getLog().info( "web.xml file = "+webApp.getDescriptor());
|
||||||
|
getLog().info("Webapp directory = " + webAppSourceDirectory.getCanonicalPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File toFile(Resource resource)
|
private static File toFile(Resource resource)
|
||||||
|
@ -628,7 +604,125 @@ public class JettyRunMojo extends AbstractJettyMojo
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
private List<Overlay> getOverlays()
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
//get copy of a list of war artifacts
|
||||||
|
Set<Artifact> matchedWarArtifacts = new HashSet<Artifact>();
|
||||||
|
List<Overlay> overlays = new ArrayList<Overlay>();
|
||||||
|
for (OverlayConfig config:warPluginInfo.getMavenWarOverlayConfigs())
|
||||||
|
{
|
||||||
|
//overlays can be individually skipped
|
||||||
|
if (config.isSkip())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
//an empty overlay refers to the current project - important for ordering
|
||||||
|
if (config.isCurrentProject())
|
||||||
|
{
|
||||||
|
Overlay overlay = new Overlay(config, null);
|
||||||
|
overlays.add(overlay);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if a war matches an overlay config
|
||||||
|
Artifact a = getArtifactForOverlay(config, getWarArtifacts());
|
||||||
|
if (a != null)
|
||||||
|
{
|
||||||
|
matchedWarArtifacts.add(a);
|
||||||
|
SelectiveJarResource r = new SelectiveJarResource(new URL("jar:"+Resource.toURL(a.getFile()).toString()+"!/"));
|
||||||
|
r.setIncludes(config.getIncludes());
|
||||||
|
r.setExcludes(config.getExcludes());
|
||||||
|
Overlay overlay = new Overlay(config, r);
|
||||||
|
overlays.add(overlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//iterate over the left over war artifacts and unpack them (without include/exclude processing) as necessary
|
||||||
|
for (Artifact a: getWarArtifacts())
|
||||||
|
{
|
||||||
|
if (!matchedWarArtifacts.contains(a))
|
||||||
|
{
|
||||||
|
Overlay overlay = new Overlay(null, Resource.newResource(new URL("jar:"+Resource.toURL(a.getFile()).toString()+"!/")));
|
||||||
|
overlays.add(overlay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return overlays;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public void unpackOverlays (List<Overlay> overlays)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
if (overlays == null || overlays.isEmpty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
List<Resource> resourceBaseCollection = new ArrayList<Resource>();
|
||||||
|
|
||||||
|
for (Overlay o:overlays)
|
||||||
|
{
|
||||||
|
//can refer to the current project in list of overlays for ordering purposes
|
||||||
|
if (o.getConfig() != null && o.getConfig().isCurrentProject() && webApp.getBaseResource().exists())
|
||||||
|
{
|
||||||
|
resourceBaseCollection.add(webApp.getBaseResource());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Resource unpacked = unpackOverlay(o);
|
||||||
|
//_unpackedOverlayResources.add(unpacked); //remember the unpacked overlays for later so we can delete the tmp files
|
||||||
|
resourceBaseCollection.add(unpacked); //add in the selectively unpacked overlay in the correct order to the webapps resource base
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!resourceBaseCollection.contains(webApp.getBaseResource()) && webApp.getBaseResource().exists())
|
||||||
|
{
|
||||||
|
if (webApp.getBaseAppFirst())
|
||||||
|
{
|
||||||
|
resourceBaseCollection.add(0, webApp.getBaseResource());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
resourceBaseCollection.add(webApp.getBaseResource());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
webApp.setBaseResource(new ResourceCollection(resourceBaseCollection.toArray(new Resource[resourceBaseCollection.size()])));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public Resource unpackOverlay (Overlay overlay)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (overlay.getResource() == null)
|
||||||
|
return null; //nothing to unpack
|
||||||
|
|
||||||
|
//Get the name of the overlayed war and unpack it to a dir of the
|
||||||
|
//same name in the temporary directory
|
||||||
|
String name = overlay.getResource().getName();
|
||||||
|
if (name.endsWith("!/"))
|
||||||
|
name = name.substring(0,name.length()-2);
|
||||||
|
int i = name.lastIndexOf('/');
|
||||||
|
if (i>0)
|
||||||
|
name = name.substring(i+1,name.length());
|
||||||
|
name = name.replace('.', '_');
|
||||||
|
//name = name+(++COUNTER); //add some digits to ensure uniqueness
|
||||||
|
File overlaysDir = new File (project.getBuild().getDirectory(), "jetty_overlays");
|
||||||
|
File dir = new File(overlaysDir, name);
|
||||||
|
|
||||||
|
//if specified targetPath, unpack to that subdir instead
|
||||||
|
File unpackDir = dir;
|
||||||
|
if (overlay.getConfig() != null && overlay.getConfig().getTargetPath() != null)
|
||||||
|
unpackDir = new File (dir, overlay.getConfig().getTargetPath());
|
||||||
|
|
||||||
|
//only unpack if the overlay is newer
|
||||||
|
if (!unpackDir.exists() || (overlay.getResource().lastModified() > unpackDir.lastModified()))
|
||||||
|
{
|
||||||
|
boolean made=unpackDir.mkdirs();
|
||||||
|
overlay.getResource().copyTo(unpackDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
//use top level of unpacked content
|
||||||
|
return Resource.newResource(dir.getCanonicalPath());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return
|
* @return
|
||||||
|
|
|
@ -31,9 +31,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.TreeSet;
|
import java.util.TreeSet;
|
||||||
|
|
||||||
import org.eclipse.jetty.annotations.AnnotationConfiguration;
|
|
||||||
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
|
import org.eclipse.jetty.plus.webapp.EnvConfiguration;
|
||||||
import org.eclipse.jetty.plus.webapp.PlusConfiguration;
|
|
||||||
import org.eclipse.jetty.quickstart.PreconfigureDescriptorProcessor;
|
import org.eclipse.jetty.quickstart.PreconfigureDescriptorProcessor;
|
||||||
import org.eclipse.jetty.quickstart.QuickStartDescriptorGenerator;
|
import org.eclipse.jetty.quickstart.QuickStartDescriptorGenerator;
|
||||||
import org.eclipse.jetty.servlet.FilterHolder;
|
import org.eclipse.jetty.servlet.FilterHolder;
|
||||||
|
@ -47,12 +45,8 @@ import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||||
import org.eclipse.jetty.webapp.Configuration;
|
import org.eclipse.jetty.webapp.Configuration;
|
||||||
import org.eclipse.jetty.webapp.FragmentConfiguration;
|
|
||||||
import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
|
|
||||||
import org.eclipse.jetty.webapp.MetaInfConfiguration;
|
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* JettyWebAppContext
|
* JettyWebAppContext
|
||||||
|
@ -73,7 +67,14 @@ public class JettyWebAppContext extends WebAppContext
|
||||||
private static final String WEB_INF_CLASSES_PREFIX = "/WEB-INF/classes";
|
private static final String WEB_INF_CLASSES_PREFIX = "/WEB-INF/classes";
|
||||||
private static final String WEB_INF_LIB_PREFIX = "/WEB-INF/lib";
|
private static final String WEB_INF_LIB_PREFIX = "/WEB-INF/lib";
|
||||||
|
|
||||||
|
|
||||||
|
public static final String[] MINIMUM_CONFIGURATION_CLASSES = {
|
||||||
|
"org.eclipse.jetty.maven.plugin.MavenWebInfConfiguration",
|
||||||
|
"org.eclipse.jetty.webapp.WebXmlConfiguration",
|
||||||
|
"org.eclipse.jetty.webapp.MetaInfConfiguration",
|
||||||
|
"org.eclipse.jetty.webapp.FragmentConfiguration",
|
||||||
|
"org.eclipse.jetty.webapp.JettyWebXmlConfiguration"
|
||||||
|
};
|
||||||
public static final String[] DEFAULT_CONFIGURATION_CLASSES = {
|
public static final String[] DEFAULT_CONFIGURATION_CLASSES = {
|
||||||
"org.eclipse.jetty.maven.plugin.MavenWebInfConfiguration",
|
"org.eclipse.jetty.maven.plugin.MavenWebInfConfiguration",
|
||||||
"org.eclipse.jetty.webapp.WebXmlConfiguration",
|
"org.eclipse.jetty.webapp.WebXmlConfiguration",
|
||||||
|
@ -86,7 +87,7 @@ public class JettyWebAppContext extends WebAppContext
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
private final String[] QUICKSTART_CONFIGURATION_CLASSES = {
|
public static final String[] QUICKSTART_CONFIGURATION_CLASSES = {
|
||||||
"org.eclipse.jetty.maven.plugin.MavenQuickStartConfiguration",
|
"org.eclipse.jetty.maven.plugin.MavenQuickStartConfiguration",
|
||||||
"org.eclipse.jetty.plus.webapp.EnvConfiguration",
|
"org.eclipse.jetty.plus.webapp.EnvConfiguration",
|
||||||
"org.eclipse.jetty.plus.webapp.PlusConfiguration",
|
"org.eclipse.jetty.plus.webapp.PlusConfiguration",
|
||||||
|
@ -375,18 +376,11 @@ public class JettyWebAppContext extends WebAppContext
|
||||||
@Override
|
@Override
|
||||||
public void doStart () throws Exception
|
public void doStart () throws Exception
|
||||||
{
|
{
|
||||||
//choose if this will be a quickstart or normal start
|
|
||||||
if (!isGenerateQuickStart() && getQuickStartWebDescriptor() != null)
|
if (isGenerateQuickStart())
|
||||||
{
|
{
|
||||||
setConfigurationClasses(QUICKSTART_CONFIGURATION_CLASSES);
|
_preconfigProcessor = new PreconfigureDescriptorProcessor();
|
||||||
}
|
getMetaData().addDescriptorProcessor(_preconfigProcessor);
|
||||||
else
|
|
||||||
{
|
|
||||||
if (isGenerateQuickStart())
|
|
||||||
{
|
|
||||||
_preconfigProcessor = new PreconfigureDescriptorProcessor();
|
|
||||||
getMetaData().addDescriptorProcessor(_preconfigProcessor);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Set up the pattern that tells us where the jars are that need scanning
|
//Set up the pattern that tells us where the jars are that need scanning
|
||||||
|
@ -444,9 +438,7 @@ public class JettyWebAppContext extends WebAppContext
|
||||||
for (Configuration c:getConfigurations())
|
for (Configuration c:getConfigurations())
|
||||||
{
|
{
|
||||||
if (c instanceof EnvConfiguration && getJettyEnvXml() != null)
|
if (c instanceof EnvConfiguration && getJettyEnvXml() != null)
|
||||||
((EnvConfiguration)c).setJettyEnvXml(Resource.toURL(new File(getJettyEnvXml())));
|
((EnvConfiguration)c).setJettyEnvXml(Resource.toURL(new File(getJettyEnvXml())));
|
||||||
else if (c instanceof MavenQuickStartConfiguration && getQuickStartWebDescriptor() != null)
|
|
||||||
((MavenQuickStartConfiguration)c).setQuickStartWebXml(getQuickStartWebDescriptor());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,22 +39,8 @@ import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
public class MavenQuickStartConfiguration extends QuickStartConfiguration
|
public class MavenQuickStartConfiguration extends QuickStartConfiguration
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(QuickStartConfiguration.class);
|
private static final Logger LOG = Log.getLogger(QuickStartConfiguration.class);
|
||||||
|
|
||||||
private Resource _quickStartWebXml;
|
|
||||||
|
|
||||||
|
|
||||||
public void setQuickStartWebXml (Resource r)
|
|
||||||
{
|
|
||||||
_quickStartWebXml = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Resource getQuickStartWebXml(WebAppContext context) throws Exception
|
|
||||||
{
|
|
||||||
return _quickStartWebXml;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void preConfigure(WebAppContext context) throws Exception
|
public void preConfigure(WebAppContext context) throws Exception
|
||||||
|
@ -65,7 +51,7 @@ public class MavenQuickStartConfiguration extends QuickStartConfiguration
|
||||||
|
|
||||||
|
|
||||||
//look for quickstart-web.xml in WEB-INF of webapp
|
//look for quickstart-web.xml in WEB-INF of webapp
|
||||||
Resource quickStartWebXml = getQuickStartWebXml(context);
|
Resource quickStartWebXml = ((JettyWebAppContext)context).getQuickStartWebDescriptor();
|
||||||
LOG.debug("quickStartWebXml={}",quickStartWebXml);
|
LOG.debug("quickStartWebXml={}",quickStartWebXml);
|
||||||
|
|
||||||
context.getMetaData().setWebXml(quickStartWebXml);
|
context.getMetaData().setWebXml(quickStartWebXml);
|
||||||
|
|
|
@ -19,17 +19,14 @@
|
||||||
package org.eclipse.jetty.maven.plugin;
|
package org.eclipse.jetty.maven.plugin;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
|
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
|
||||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||||
import org.eclipse.jetty.webapp.WebAppContext;
|
import org.eclipse.jetty.webapp.WebAppContext;
|
||||||
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||||
|
@ -45,11 +42,6 @@ import org.eclipse.jetty.webapp.WebInfConfiguration;
|
||||||
public class MavenWebInfConfiguration extends WebInfConfiguration
|
public class MavenWebInfConfiguration extends WebInfConfiguration
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(MavenWebInfConfiguration.class);
|
private static final Logger LOG = Log.getLogger(MavenWebInfConfiguration.class);
|
||||||
|
|
||||||
public static final String RESOURCE_BASES_POST_OVERLAY = "org.eclipse.jetty.resource.postOverlay";
|
|
||||||
protected static int COUNTER = 0;
|
|
||||||
protected Resource _originalResourceBase;
|
|
||||||
protected List<Resource> _unpackedOverlayResources;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext)
|
* @see org.eclipse.jetty.webapp.WebInfConfiguration#configure(org.eclipse.jetty.webapp.WebAppContext)
|
||||||
|
@ -84,91 +76,6 @@ public class MavenWebInfConfiguration extends WebInfConfiguration
|
||||||
context.setServerClasses( newServerClasses );
|
context.setServerClasses( newServerClasses );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.webapp.AbstractConfiguration#postConfigure(org.eclipse.jetty.webapp.WebAppContext)
|
|
||||||
*/
|
|
||||||
public void postConfigure(WebAppContext context) throws Exception
|
|
||||||
{
|
|
||||||
super.postConfigure(context);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#deconfigure(org.eclipse.jetty.webapp.WebAppContext)
|
|
||||||
*/
|
|
||||||
public void deconfigure(WebAppContext context) throws Exception
|
|
||||||
{
|
|
||||||
super.deconfigure(context);
|
|
||||||
//restore whatever the base resource was before we might have included overlaid wars
|
|
||||||
context.setBaseResource(_originalResourceBase);
|
|
||||||
//undo the setting of the overlayed resources
|
|
||||||
context.removeAttribute(RESOURCE_BASES_POST_OVERLAY);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @see org.eclipse.jetty.webapp.WebInfConfiguration#unpack(org.eclipse.jetty.webapp.WebAppContext)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void unpack(WebAppContext context) throws IOException
|
|
||||||
{
|
|
||||||
//Unpack and find base resource as normal
|
|
||||||
super.unpack(context);
|
|
||||||
|
|
||||||
//Get the base resource for the "virtual" webapp
|
|
||||||
_originalResourceBase = context.getBaseResource();
|
|
||||||
|
|
||||||
JettyWebAppContext jwac = (JettyWebAppContext)context;
|
|
||||||
|
|
||||||
//determine sequencing of overlays
|
|
||||||
_unpackedOverlayResources = new ArrayList<Resource>();
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (jwac.getOverlays() != null && !jwac.getOverlays().isEmpty())
|
|
||||||
{
|
|
||||||
List<Resource> resourceBaseCollection = new ArrayList<Resource>();
|
|
||||||
|
|
||||||
for (Overlay o:jwac.getOverlays())
|
|
||||||
{
|
|
||||||
//can refer to the current project in list of overlays for ordering purposes
|
|
||||||
if (o.getConfig() != null && o.getConfig().isCurrentProject() && _originalResourceBase.exists())
|
|
||||||
{
|
|
||||||
resourceBaseCollection.add(_originalResourceBase);
|
|
||||||
LOG.debug("Adding virtual project to resource base list");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Resource unpacked = unpackOverlay(jwac,o);
|
|
||||||
_unpackedOverlayResources.add(unpacked); //remember the unpacked overlays for later so we can delete the tmp files
|
|
||||||
resourceBaseCollection.add(unpacked); //add in the selectively unpacked overlay in the correct order to the webapps resource base
|
|
||||||
LOG.debug("Adding "+unpacked+" to resource base list");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!resourceBaseCollection.contains(_originalResourceBase) && _originalResourceBase.exists())
|
|
||||||
{
|
|
||||||
if (jwac.getBaseAppFirst())
|
|
||||||
{
|
|
||||||
LOG.debug("Adding virtual project first in resource base list");
|
|
||||||
resourceBaseCollection.add(0, _originalResourceBase);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LOG.debug("Adding virtual project last in resource base list");
|
|
||||||
resourceBaseCollection.add(_originalResourceBase);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jwac.setBaseResource(new ResourceCollection(resourceBaseCollection.toArray(new Resource[resourceBaseCollection.size()])));
|
|
||||||
}
|
|
||||||
|
|
||||||
jwac.setAttribute(RESOURCE_BASES_POST_OVERLAY, jwac.getBaseResource());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the jars to examine from the files from which we have
|
* Get the jars to examine from the files from which we have
|
||||||
* synthesized the classpath. Note that the classpath is not
|
* synthesized the classpath. Note that the classpath is not
|
||||||
|
@ -249,38 +156,4 @@ public class MavenWebInfConfiguration extends WebInfConfiguration
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected Resource unpackOverlay (WebAppContext context, Overlay overlay)
|
|
||||||
throws IOException
|
|
||||||
{
|
|
||||||
LOG.debug("Unpacking overlay: " + overlay);
|
|
||||||
|
|
||||||
if (overlay.getResource() == null)
|
|
||||||
return null; //nothing to unpack
|
|
||||||
|
|
||||||
//Get the name of the overlayed war and unpack it to a dir of the
|
|
||||||
//same name in the temporary directory
|
|
||||||
String name = overlay.getResource().getName();
|
|
||||||
if (name.endsWith("!/"))
|
|
||||||
name = name.substring(0,name.length()-2);
|
|
||||||
int i = name.lastIndexOf('/');
|
|
||||||
if (i>0)
|
|
||||||
name = name.substring(i+1,name.length());
|
|
||||||
name = name.replace('.', '_');
|
|
||||||
name = name+(++COUNTER); //add some digits to ensure uniqueness
|
|
||||||
File dir = new File(context.getTempDirectory(), name);
|
|
||||||
|
|
||||||
//if specified targetPath, unpack to that subdir instead
|
|
||||||
File unpackDir = dir;
|
|
||||||
if (overlay.getConfig() != null && overlay.getConfig().getTargetPath() != null)
|
|
||||||
unpackDir = new File (dir, overlay.getConfig().getTargetPath());
|
|
||||||
|
|
||||||
overlay.getResource().copyTo(unpackDir);
|
|
||||||
//use top level of unpacked content
|
|
||||||
Resource unpackedOverlay = Resource.newResource(dir.getCanonicalPath());
|
|
||||||
|
|
||||||
LOG.debug("Unpacked overlay: "+overlay+" to "+unpackedOverlay);
|
|
||||||
return unpackedOverlay;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,21 +19,8 @@
|
||||||
package org.eclipse.jetty.maven.plugin;
|
package org.eclipse.jetty.maven.plugin;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileInputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.nio.file.Paths;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Enumeration;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
|
||||||
import java.util.Set;
|
|
||||||
import java.util.TreeMap;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.eclipse.jetty.server.Handler;
|
import org.eclipse.jetty.server.Handler;
|
||||||
import org.eclipse.jetty.server.Server;
|
import org.eclipse.jetty.server.Server;
|
||||||
|
@ -43,8 +30,6 @@ import org.eclipse.jetty.util.StringUtil;
|
||||||
import org.eclipse.jetty.util.log.Log;
|
import org.eclipse.jetty.util.log.Log;
|
||||||
import org.eclipse.jetty.util.log.Logger;
|
import org.eclipse.jetty.util.log.Logger;
|
||||||
import org.eclipse.jetty.util.resource.Resource;
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
import org.eclipse.jetty.util.resource.ResourceCollection;
|
|
||||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -55,8 +40,7 @@ public class Starter
|
||||||
{
|
{
|
||||||
private static final Logger LOG = Log.getLogger(Starter.class);
|
private static final Logger LOG = Log.getLogger(Starter.class);
|
||||||
|
|
||||||
private List<File> jettyXmls; // list of jetty.xml config files to apply - Mandatory
|
private List<File> jettyXmls; // list of jetty.xml config files to apply
|
||||||
private File contextXml; //name of context xml file to configure the webapp - Mandatory
|
|
||||||
|
|
||||||
private Server server;
|
private Server server;
|
||||||
private JettyWebAppContext webApp;
|
private JettyWebAppContext webApp;
|
||||||
|
@ -64,57 +48,10 @@ public class Starter
|
||||||
|
|
||||||
private int stopPort=0;
|
private int stopPort=0;
|
||||||
private String stopKey=null;
|
private String stopKey=null;
|
||||||
private Properties props;
|
private File propsFile;
|
||||||
private String token;
|
private String token;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Artifact
|
|
||||||
*
|
|
||||||
* A mock maven Artifact class as the maven jars are not put onto the classpath for the
|
|
||||||
* execution of this class.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
public class Artifact
|
|
||||||
{
|
|
||||||
public String gid;
|
|
||||||
public String aid;
|
|
||||||
public String path;
|
|
||||||
public Resource resource;
|
|
||||||
|
|
||||||
public Artifact (String csv)
|
|
||||||
{
|
|
||||||
if (csv != null && !"".equals(csv))
|
|
||||||
{
|
|
||||||
String[] atoms = StringUtil.csvSplit(csv);
|
|
||||||
if (atoms.length >= 3)
|
|
||||||
{
|
|
||||||
gid = atoms[0].trim();
|
|
||||||
aid = atoms[1].trim();
|
|
||||||
path = atoms[2].trim();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Artifact (String gid, String aid, String path)
|
|
||||||
{
|
|
||||||
this.gid = gid;
|
|
||||||
this.aid = aid;
|
|
||||||
this.path = path;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o)
|
|
||||||
{
|
|
||||||
if (!(o instanceof Artifact))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
Artifact ao = (Artifact)o;
|
|
||||||
return (((gid == null && ao.gid == null) || (gid != null && gid.equals(ao.gid)))
|
|
||||||
&& ((aid == null && ao.aid == null) || (aid != null && aid.equals(ao.aid))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
public void configureJetty () throws Exception
|
public void configureJetty () throws Exception
|
||||||
{
|
{
|
||||||
|
@ -146,19 +83,6 @@ public class Starter
|
||||||
webApp.setQuickStartWebDescriptor(Resource.newResource(qs));
|
webApp.setQuickStartWebDescriptor(Resource.newResource(qs));
|
||||||
}
|
}
|
||||||
|
|
||||||
//set up the webapp from the context xml file provided
|
|
||||||
//NOTE: just like jetty:run mojo this means that the context file can
|
|
||||||
//potentially override settings made in the pom. Ideally, we'd like
|
|
||||||
//the pom to override the context xml file, but as the other mojos all
|
|
||||||
//configure a WebAppContext in the pom (the <webApp> element), it is
|
|
||||||
//already configured by the time the context xml file is applied.
|
|
||||||
if (contextXml != null)
|
|
||||||
{
|
|
||||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.toURL(contextXml));
|
|
||||||
xmlConfiguration.getIdMap().put("Server",server);
|
|
||||||
xmlConfiguration.configure(webApp);
|
|
||||||
}
|
|
||||||
|
|
||||||
ServerSupport.addWebApplication(server, webApp);
|
ServerSupport.addWebApplication(server, webApp);
|
||||||
|
|
||||||
if(stopPort>0 && stopKey!=null)
|
if(stopPort>0 && stopKey!=null)
|
||||||
|
@ -173,147 +97,11 @@ public class Starter
|
||||||
public void configureWebApp ()
|
public void configureWebApp ()
|
||||||
throws Exception
|
throws Exception
|
||||||
{
|
{
|
||||||
if (props == null)
|
if (propsFile == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
//apply a properties file that defines the things that we configure in the jetty:run plugin:
|
//apply a properties file that defines the things that we configure in the jetty:run plugin
|
||||||
// - the context path
|
WebAppPropertyConverter.fromProperties(webApp, propsFile, server);
|
||||||
String str = props.getProperty("context.path");
|
|
||||||
if (str != null)
|
|
||||||
webApp.setContextPath(str);
|
|
||||||
|
|
||||||
|
|
||||||
// - web.xml
|
|
||||||
str = props.getProperty("web.xml");
|
|
||||||
if (str != null)
|
|
||||||
webApp.setDescriptor(str);
|
|
||||||
|
|
||||||
str = props.getProperty("quickstart.web.xml");
|
|
||||||
if (str != null)
|
|
||||||
webApp.setQuickStartWebDescriptor(Resource.newResource(new File(str)));
|
|
||||||
|
|
||||||
// - the tmp directory
|
|
||||||
str = props.getProperty("tmp.dir");
|
|
||||||
if (str != null)
|
|
||||||
webApp.setTempDirectory(new File(str.trim()));
|
|
||||||
|
|
||||||
str = props.getProperty("tmp.dir.persist");
|
|
||||||
if (str != null)
|
|
||||||
webApp.setPersistTempDirectory(Boolean.valueOf(str));
|
|
||||||
|
|
||||||
//Get the calculated base dirs which includes the overlays
|
|
||||||
str = props.getProperty("base.dirs");
|
|
||||||
if (str != null && !"".equals(str.trim()))
|
|
||||||
{
|
|
||||||
ResourceCollection bases = new ResourceCollection(StringUtil.csvSplit(str));
|
|
||||||
webApp.setWar(null);
|
|
||||||
webApp.setBaseResource(bases);
|
|
||||||
}
|
|
||||||
|
|
||||||
//Get the original base dirs without the overlays
|
|
||||||
str = props.getProperty("base.dirs.orig");
|
|
||||||
if (str != null && !"".equals(str.trim()))
|
|
||||||
{
|
|
||||||
ResourceCollection bases = new ResourceCollection(StringUtil.csvSplit(str));
|
|
||||||
webApp.setAttribute ("org.eclipse.jetty.resources.originalBases", bases);
|
|
||||||
}
|
|
||||||
|
|
||||||
//For overlays
|
|
||||||
str = props.getProperty("maven.war.includes");
|
|
||||||
List<String> defaultWarIncludes = fromCSV(str);
|
|
||||||
str = props.getProperty("maven.war.excludes");
|
|
||||||
List<String> defaultWarExcludes = fromCSV(str);
|
|
||||||
|
|
||||||
//List of war artifacts
|
|
||||||
List<Artifact> wars = new ArrayList<Artifact>();
|
|
||||||
|
|
||||||
//List of OverlayConfigs
|
|
||||||
TreeMap<String, OverlayConfig> orderedConfigs = new TreeMap<String, OverlayConfig>();
|
|
||||||
Enumeration<String> pnames = (Enumeration<String>)props.propertyNames();
|
|
||||||
while (pnames.hasMoreElements())
|
|
||||||
{
|
|
||||||
String n = pnames.nextElement();
|
|
||||||
if (n.startsWith("maven.war.artifact"))
|
|
||||||
{
|
|
||||||
Artifact a = new Artifact((String)props.get(n));
|
|
||||||
a.resource = Resource.newResource("jar:"+Resource.toURL(new File(a.path)).toString()+"!/");
|
|
||||||
wars.add(a);
|
|
||||||
}
|
|
||||||
else if (n.startsWith("maven.war.overlay"))
|
|
||||||
{
|
|
||||||
OverlayConfig c = new OverlayConfig ((String)props.get(n), defaultWarIncludes, defaultWarExcludes);
|
|
||||||
orderedConfigs.put(n,c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Set<Artifact> matchedWars = new HashSet<Artifact>();
|
|
||||||
|
|
||||||
//process any overlays and the war type artifacts
|
|
||||||
List<Overlay> overlays = new ArrayList<>();
|
|
||||||
for (OverlayConfig config:orderedConfigs.values())
|
|
||||||
{
|
|
||||||
//overlays can be individually skipped
|
|
||||||
if (config.isSkip())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
//an empty overlay refers to the current project - important for ordering
|
|
||||||
if (config.isCurrentProject())
|
|
||||||
{
|
|
||||||
Overlay overlay = new Overlay(config, null);
|
|
||||||
overlays.add(overlay);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//if a war matches an overlay config
|
|
||||||
Artifact a = getArtifactForOverlayConfig(config, wars);
|
|
||||||
if (a != null)
|
|
||||||
{
|
|
||||||
matchedWars.add(a);
|
|
||||||
SelectiveJarResource r = new SelectiveJarResource(new URL("jar:"+Resource.toURL(new File(a.path)).toString()+"!/"));
|
|
||||||
r.setIncludes(config.getIncludes());
|
|
||||||
r.setExcludes(config.getExcludes());
|
|
||||||
Overlay overlay = new Overlay(config, r);
|
|
||||||
overlays.add(overlay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//iterate over the left over war artifacts and unpack them (without include/exclude processing) as necessary
|
|
||||||
for (Artifact a: wars)
|
|
||||||
{
|
|
||||||
if (!matchedWars.contains(a))
|
|
||||||
{
|
|
||||||
Overlay overlay = new Overlay(null, a.resource);
|
|
||||||
overlays.add(overlay);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
webApp.setOverlays(overlays);
|
|
||||||
|
|
||||||
|
|
||||||
// - the equivalent of web-inf classes
|
|
||||||
str = props.getProperty("classes.dir");
|
|
||||||
if (str != null && !"".equals(str.trim()))
|
|
||||||
{
|
|
||||||
webApp.setClasses(new File(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
str = props.getProperty("testClasses.dir");
|
|
||||||
if (str != null && !"".equals(str.trim()))
|
|
||||||
{
|
|
||||||
webApp.setTestClasses(new File(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
// - the equivalent of web-inf lib
|
|
||||||
str = props.getProperty("lib.jars");
|
|
||||||
if (str != null && !"".equals(str.trim()))
|
|
||||||
{
|
|
||||||
List<File> jars = new ArrayList<File>();
|
|
||||||
String[] names = StringUtil.csvSplit(str);
|
|
||||||
for (int j=0; names != null && j < names.length; j++)
|
|
||||||
jars.add(new File(names[j].trim()));
|
|
||||||
webApp.setWebInfLib(jars);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void getConfiguration (String[] args)
|
public void getConfiguration (String[] args)
|
||||||
|
@ -340,21 +128,10 @@ public class Starter
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//--context-xml
|
|
||||||
if ("--context-xml".equals(args[i]))
|
|
||||||
{
|
|
||||||
contextXml = new File(args[++i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
//--props
|
//--props
|
||||||
if ("--props".equals(args[i]))
|
if ("--props".equals(args[i]))
|
||||||
{
|
{
|
||||||
File f = new File(args[++i].trim());
|
propsFile = new File(args[++i].trim());
|
||||||
props = new Properties();
|
|
||||||
try (InputStream in = new FileInputStream(f))
|
|
||||||
{
|
|
||||||
props.load(in);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//--token
|
//--token
|
||||||
|
@ -419,25 +196,6 @@ public class Starter
|
||||||
System.arraycopy(existing, 0, children, 1, existing.length);
|
System.arraycopy(existing, 0, children, 1, existing.length);
|
||||||
handlers.setHandlers(children);
|
handlers.setHandlers(children);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected Artifact getArtifactForOverlayConfig (OverlayConfig c, List<Artifact> wars)
|
|
||||||
{
|
|
||||||
if (wars == null || wars.isEmpty() || c == null)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
Artifact war = null;
|
|
||||||
Iterator<Artifact> itor = wars.iterator();
|
|
||||||
while(itor.hasNext() && war == null)
|
|
||||||
{
|
|
||||||
Artifact a = itor.next();
|
|
||||||
if (c.matchesArtifact(a.gid, a.aid, null))
|
|
||||||
war = a;
|
|
||||||
}
|
|
||||||
return war;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param csv
|
* @param csv
|
||||||
|
@ -456,6 +214,9 @@ public class Starter
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param args
|
||||||
|
*/
|
||||||
public static final void main(String[] args)
|
public static final void main(String[] args)
|
||||||
{
|
{
|
||||||
if (args == null)
|
if (args == null)
|
||||||
|
|
|
@ -0,0 +1,276 @@
|
||||||
|
//
|
||||||
|
// ========================================================================
|
||||||
|
// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd.
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
// All rights reserved. This program and the accompanying materials
|
||||||
|
// are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
// and Apache License v2.0 which accompanies this distribution.
|
||||||
|
//
|
||||||
|
// The Eclipse Public License is available at
|
||||||
|
// http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
//
|
||||||
|
// The Apache License v2.0 is available at
|
||||||
|
// http://www.opensource.org/licenses/apache2.0.php
|
||||||
|
//
|
||||||
|
// You may elect to redistribute this code under either of these licenses.
|
||||||
|
// ========================================================================
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
package org.eclipse.jetty.maven.plugin;
|
||||||
|
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileInputStream;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.OutputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
|
||||||
|
import org.eclipse.jetty.server.Server;
|
||||||
|
import org.eclipse.jetty.util.StringUtil;
|
||||||
|
import org.eclipse.jetty.util.resource.Resource;
|
||||||
|
import org.eclipse.jetty.util.resource.ResourceCollection;
|
||||||
|
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* WebAppPropertyConverter
|
||||||
|
*
|
||||||
|
* Converts a webapp's configuration to a properties file, and
|
||||||
|
* vice versa.
|
||||||
|
*/
|
||||||
|
public class WebAppPropertyConverter
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a webapp to properties stored in a file.
|
||||||
|
*
|
||||||
|
* @param webApp the webapp to convert
|
||||||
|
* @param propsFile the file to put the properties into
|
||||||
|
* @param contextXml the optional context xml file related to the webApp
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void toProperties(JettyWebAppContext webApp, File propsFile, String contextXml)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
if (webApp == null)
|
||||||
|
throw new IllegalArgumentException("No webapp");
|
||||||
|
if (propsFile == null)
|
||||||
|
throw new IllegalArgumentException("No properties file");
|
||||||
|
|
||||||
|
//work out the configuration based on what is configured in the pom
|
||||||
|
if (propsFile.exists())
|
||||||
|
propsFile.delete();
|
||||||
|
|
||||||
|
propsFile.createNewFile();
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
//web.xml
|
||||||
|
if (webApp.getDescriptor() != null)
|
||||||
|
{
|
||||||
|
props.put("web.xml", webApp.getDescriptor());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webApp.getQuickStartWebDescriptor() != null)
|
||||||
|
{
|
||||||
|
props.put("quickstart.web.xml", webApp.getQuickStartWebDescriptor().getFile().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
//sort out the context path
|
||||||
|
if (webApp.getContextPath() != null)
|
||||||
|
{
|
||||||
|
props.put("context.path", webApp.getContextPath());
|
||||||
|
}
|
||||||
|
|
||||||
|
//tmp dir
|
||||||
|
props.put("tmp.dir", webApp.getTempDirectory().getAbsolutePath());
|
||||||
|
//props.put("tmp.dir.persist", Boolean.toString(originalPersistTemp));
|
||||||
|
props.put("tmp.dir.persist", Boolean.toString(webApp.isPersistTempDirectory()));
|
||||||
|
|
||||||
|
//send over the calculated resource bases that includes unpacked overlays
|
||||||
|
Resource baseResource = webApp.getBaseResource();
|
||||||
|
if (baseResource instanceof ResourceCollection)
|
||||||
|
props.put("base.dirs", toCSV(((ResourceCollection)webApp.getBaseResource()).getResources()));
|
||||||
|
else
|
||||||
|
props.put("base.dirs", webApp.getBaseResource().toString());
|
||||||
|
|
||||||
|
|
||||||
|
//web-inf classes
|
||||||
|
if (webApp.getClasses() != null)
|
||||||
|
{
|
||||||
|
props.put("classes.dir",webApp.getClasses().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (webApp.getTestClasses() != null)
|
||||||
|
{
|
||||||
|
props.put("testClasses.dir", webApp.getTestClasses().getAbsolutePath());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//web-inf lib
|
||||||
|
List<File> deps = webApp.getWebInfLib();
|
||||||
|
StringBuffer strbuff = new StringBuffer();
|
||||||
|
if (deps != null)
|
||||||
|
{
|
||||||
|
for (int i=0; i<deps.size(); i++)
|
||||||
|
{
|
||||||
|
File d = deps.get(i);
|
||||||
|
strbuff.append(d.getAbsolutePath());
|
||||||
|
if (i < deps.size()-1)
|
||||||
|
strbuff.append(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
props.put("lib.jars", strbuff.toString());
|
||||||
|
|
||||||
|
//context xml to apply
|
||||||
|
if (contextXml != null)
|
||||||
|
props.put("context.xml", contextXml);
|
||||||
|
|
||||||
|
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(propsFile)))
|
||||||
|
{
|
||||||
|
props.store(out, "properties for forked webapp");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure a webapp from a properties file.
|
||||||
|
*
|
||||||
|
* @param webApp the webapp to configure
|
||||||
|
* @param resource the properties file to apply
|
||||||
|
* @param server the Server instance to use
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void fromProperties (JettyWebAppContext webApp, String resource, Server server)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
if (resource == null)
|
||||||
|
throw new IllegalStateException("No resource");
|
||||||
|
|
||||||
|
fromProperties(webApp, Resource.newResource(resource).getFile(), server);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure a webapp from a properties file
|
||||||
|
* @param webApp the webapp to configure
|
||||||
|
* @param propsFile the properties to apply
|
||||||
|
* @param server the Server instance
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public static void fromProperties (JettyWebAppContext webApp, File propsFile, Server server)
|
||||||
|
throws Exception
|
||||||
|
{
|
||||||
|
if (webApp == null)
|
||||||
|
throw new IllegalArgumentException("No webapp");
|
||||||
|
if (propsFile == null)
|
||||||
|
throw new IllegalArgumentException("No properties file");
|
||||||
|
|
||||||
|
if (!propsFile.exists())
|
||||||
|
throw new IllegalArgumentException (propsFile.getCanonicalPath()+" does not exist");
|
||||||
|
|
||||||
|
Properties props = new Properties();
|
||||||
|
try (InputStream in = new FileInputStream(propsFile))
|
||||||
|
{
|
||||||
|
props.load(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
String str = props.getProperty("context.path");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
webApp.setContextPath(str);
|
||||||
|
|
||||||
|
|
||||||
|
// - web.xml
|
||||||
|
str = props.getProperty("web.xml");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
webApp.setDescriptor(str);
|
||||||
|
|
||||||
|
//TODO the WebAppStarter class doesn't set up the QUICKSTART_CONFIGURATION_CLASSES, but the Starter class does!!!
|
||||||
|
str = props.getProperty("quickstart.web.xml");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
{
|
||||||
|
webApp.setQuickStartWebDescriptor(Resource.newResource(new File(str)));
|
||||||
|
webApp.setConfigurationClasses(JettyWebAppContext.QUICKSTART_CONFIGURATION_CLASSES);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - the tmp directory
|
||||||
|
str = props.getProperty("tmp.dir");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
webApp.setTempDirectory(new File(str.trim()));
|
||||||
|
|
||||||
|
str = props.getProperty("tmp.dir.persist");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
webApp.setPersistTempDirectory(Boolean.valueOf(str));
|
||||||
|
|
||||||
|
//Get the calculated base dirs which includes the overlays
|
||||||
|
str = props.getProperty("base.dirs");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
{
|
||||||
|
ResourceCollection bases = new ResourceCollection(StringUtil.csvSplit(str));
|
||||||
|
webApp.setWar(null);
|
||||||
|
webApp.setBaseResource(bases);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - the equivalent of web-inf classes
|
||||||
|
str = props.getProperty("classes.dir");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
{
|
||||||
|
webApp.setClasses(new File(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
str = props.getProperty("testClasses.dir");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
{
|
||||||
|
webApp.setTestClasses(new File(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
// - the equivalent of web-inf lib
|
||||||
|
str = props.getProperty("lib.jars");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
{
|
||||||
|
List<File> jars = new ArrayList<File>();
|
||||||
|
String[] names = StringUtil.csvSplit(str);
|
||||||
|
for (int j=0; names != null && j < names.length; j++)
|
||||||
|
jars.add(new File(names[j].trim()));
|
||||||
|
webApp.setWebInfLib(jars);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//set up the webapp from the context xml file provided
|
||||||
|
//NOTE: just like jetty:run mojo this means that the context file can
|
||||||
|
//potentially override settings made in the pom. Ideally, we'd like
|
||||||
|
//the pom to override the context xml file, but as the other mojos all
|
||||||
|
//configure a WebAppContext in the pom (the <webApp> element), it is
|
||||||
|
//already configured by the time the context xml file is applied.
|
||||||
|
str = (String)props.getProperty("context.xml");
|
||||||
|
if (!StringUtil.isBlank(str))
|
||||||
|
{
|
||||||
|
XmlConfiguration xmlConfiguration = new XmlConfiguration(Resource.newResource(str).getURI().toURL());
|
||||||
|
xmlConfiguration.getIdMap().put("Server",server);
|
||||||
|
xmlConfiguration.configure(webApp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert an array of Resources to csv file names
|
||||||
|
*
|
||||||
|
* @param resources the resources to convert
|
||||||
|
*
|
||||||
|
* @return csv string of resource filenames
|
||||||
|
*/
|
||||||
|
private static String toCSV (Resource[] resources)
|
||||||
|
{
|
||||||
|
StringBuffer rb = new StringBuffer();
|
||||||
|
|
||||||
|
for (Resource r:resources)
|
||||||
|
{
|
||||||
|
if (rb.length() > 0) rb.append(",");
|
||||||
|
rb.append(r.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return rb.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,10 @@
|
||||||
|
[description]
|
||||||
|
Enables an unassembled maven webapp to run in a jetty distro
|
||||||
|
|
||||||
|
[depends]
|
||||||
|
server
|
||||||
|
webapp
|
||||||
|
annotations
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
lib/maven/**.jar
|
|
@ -0,0 +1,21 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
|
||||||
|
|
||||||
|
<Configure id="wac" class="org.eclipse.jetty.maven.plugin.JettyWebAppContext">
|
||||||
|
|
||||||
|
<Call class="org.eclipse.jetty.webapp.Configuration$ClassList" name="setServerDefault">
|
||||||
|
<Arg><Ref id="Server" /></Arg>
|
||||||
|
<Call name="replace">
|
||||||
|
<Arg>org.eclipse.jetty.webapp.WebInfConfiguration</Arg>
|
||||||
|
<Arg>org.eclipse.jetty.maven.plugin.MavenWebInfConfiguration</Arg>
|
||||||
|
</Call>
|
||||||
|
</Call>
|
||||||
|
|
||||||
|
|
||||||
|
<Call class="org.eclipse.jetty.maven.plugin.WebAppPropertyConverter" name="fromProperties">
|
||||||
|
<Arg><Ref id="wac"/></Arg>
|
||||||
|
<Arg><Property name="jetty.base" default="."/>/etc/maven.props</Arg>
|
||||||
|
<Arg><Ref id="Server"/></Arg>
|
||||||
|
</Call>
|
||||||
|
|
||||||
|
</Configure>
|
|
@ -197,5 +197,24 @@ public interface Configuration
|
||||||
throw new IllegalArgumentException("beforeClass '"+beforeClass+"' not found in "+this);
|
throw new IllegalArgumentException("beforeClass '"+beforeClass+"' not found in "+this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void replace(@Name("replaceClass") String replaceClass, @Name("configClass") String configClass)
|
||||||
|
{
|
||||||
|
if (replaceClass!=null && configClass!=null)
|
||||||
|
{
|
||||||
|
ListIterator<String> iter = listIterator();
|
||||||
|
while (iter.hasNext())
|
||||||
|
{
|
||||||
|
|
||||||
|
String cc=iter.next();
|
||||||
|
if (replaceClass.equals(cc))
|
||||||
|
{
|
||||||
|
iter.set(configClass);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("replaceClass '"+replaceClass+"' not found in "+this);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1028,8 +1028,9 @@ public class WebAppContext extends ServletContextHandler implements WebAppClassL
|
||||||
if (_configurations.size()>0)
|
if (_configurations.size()>0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_configurationClasses.size()==0)
|
if (_configurationClasses.size()==0) {
|
||||||
_configurationClasses.addAll(Configuration.ClassList.serverDefault(getServer()));
|
_configurationClasses.addAll(Configuration.ClassList.serverDefault(getServer()));
|
||||||
|
}
|
||||||
for (String configClass : _configurationClasses)
|
for (String configClass : _configurationClasses)
|
||||||
_configurations.add((Configuration)Loader.loadClass(configClass).newInstance());
|
_configurations.add((Configuration)Loader.loadClass(configClass).newInstance());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue