diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/invoker.properties b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/invoker.properties new file mode 100644 index 00000000000..df6cbf2d0bc --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/invoker.properties @@ -0,0 +1,2 @@ +invoker.goals = test -fae +invoker.debug = true diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/pom.xml b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/pom.xml new file mode 100644 index 00000000000..d2e2883e186 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/pom.xml @@ -0,0 +1,50 @@ + + + 4.0.0 + + + org.eclipse.jetty.its.jetty-run-distro-mojo-it + jetty-simple-project + 0.0.1-SNAPSHOT + + + jetty-simple-base + jar + + Jetty :: Simple :: Base + + + + + javax.servlet + javax.servlet-api + jar + provided + + + + org.slf4j + slf4j-api + + + + commons-io + commons-io + + + + org.eclipse.jetty.toolchain + jetty-perf-helper + 1.0.5 + + + + com.fasterxml.jackson.core + jackson-databind + 2.8.1 + + + + + diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java new file mode 100644 index 00000000000..a40c09f329b --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/HelloServlet.java @@ -0,0 +1,51 @@ +// +// ======================================================================== +// 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.its.jetty_run_mojo_it; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +/** + * + */ +@WebServlet("/hello") +public class HelloServlet + extends HttpServlet +{ + + public HelloServlet() + { + System.err.println("HELLOSERVLET CONTSTRUCTED AT "+System.currentTimeMillis()); + } + @Override + protected void doGet( HttpServletRequest req, HttpServletResponse resp ) + throws ServletException, IOException + { + System.err.println("HELLOSERVLET HIT AT "+System.currentTimeMillis()); + + String who = req.getParameter( "name" ); + + resp.getWriter().write( "hello " + (who == null ? "unknown" : who) ); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java new file mode 100644 index 00000000000..b84020dd177 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/java/org/eclipse/jetty/its/jetty_run_mojo_it/PingServlet.java @@ -0,0 +1,46 @@ +// +// ======================================================================== +// 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.its.jetty_run_mojo_it; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class PingServlet + extends HttpServlet +{ + + public PingServlet() + { + System.err.println("PINGSERVLET LOADED at"+System.currentTimeMillis()); + } + @Override + protected void doGet( HttpServletRequest req, HttpServletResponse resp ) + throws ServletException, IOException + { + System.err.println("PINGSERVLET HIT at"+System.currentTimeMillis()); + String who = req.getParameter( "name" ); + + resp.getWriter().write( "pong " + (who == null ? "unknown" : who) ); + } +} diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml new file mode 100644 index 00000000000..abf22ef0c43 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-base/src/main/resources/META-INF/web-fragment.xml @@ -0,0 +1,33 @@ + + + + + FragmentA + + + + + + + Ping + org.eclipse.jetty.its.jetty_run_mojo_it.PingServlet + 1 + + extra1123 + + + extra2345 + + + + + Ping + /ping + + + + \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml new file mode 100644 index 00000000000..4f0c91adb5a --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/pom.xml @@ -0,0 +1,142 @@ + + + 4.0.0 + + + org.eclipse.jetty.its.jetty-run-distro-mojo-it + jetty-simple-project + 0.0.1-SNAPSHOT + + + jetty-simple-webapp + war + + Jetty :: Simple :: Webapp + + + @jetty.runPort@ + @jetty.jvmArgs@ + + + + + + org.eclipse.jetty.its.jetty-run-distro-mojo-it + jetty-simple-base + + + + org.eclipse.jetty + jetty-servlet + provided + + + + org.eclipse.jetty + jetty-client + @project.version@ + test + + + + junit + junit + 4.12 + test + + + + + + + + + org.apache.maven.plugins + maven-war-plugin + ${maven-war-plugin-version} + + false + + + + + + + org.apache.maven.plugins + maven-surefire-plugin + 2.20 + + + @jetty.runPort@ + + + + + org.eclipse.jetty + jetty-maven-plugin + + @jetty.stopPort@ + @jetty.stopKey@ + + + + start-jetty + test-compile + + run-distro + + + + jetty.server.dumpAfterStart=true + jetty.http.port=@jetty.runPort@ + + false + + jsp + jstl + + + + + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + + + copy-resources-jetty + generate-resources + + copy-resources + + + ${project.build.directory}/config + + + ${basedir}/src/config/ + true + + **/** + + + + + + + + + + + + diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/config/jetty.xml b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/config/jetty.xml new file mode 100644 index 00000000000..a057f0664eb --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/config/jetty.xml @@ -0,0 +1,33 @@ + + + + + + https + + 32768 + 8192 + 8192 + 512 + + + + + + + + + + + + + + + + + + 30000 + + + + \ No newline at end of file diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000000..2a5ac4b71bf --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,7 @@ + + + Jetty Simple Webapp run-mojo-it + diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/test/java/org/eclipse/jetty/its/jetty_run_mojo_it/TestHelloServlet.java b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/test/java/org/eclipse/jetty/its/jetty_run_mojo_it/TestHelloServlet.java new file mode 100644 index 00000000000..a91d0003dd4 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/jetty-simple-webapp/src/test/java/org/eclipse/jetty/its/jetty_run_mojo_it/TestHelloServlet.java @@ -0,0 +1,65 @@ +// +// ======================================================================== +// 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.its.jetty_run_mojo_it; + +import org.eclipse.jetty.client.HttpClient; +import org.junit.Assert; +import org.junit.Test; + +/** + * + */ +public class TestHelloServlet +{ + + public TestHelloServlet() + { + System.err.println("CONSTRUCTED TESTHELLOSERVLET"); + } + + @Test + public void hello_servlet() + throws Exception + { +System.err.println("IN HELLOSERVLET, PORT="+Integer.getInteger( "jetty.runPort" )); + int port = Integer.getInteger( "jetty.runPort" ); + System.out.println( "port used:" + port ); + HttpClient httpClient = new HttpClient(); + try + { + httpClient.start(); + + String response = httpClient.GET( "http://localhost:" + port + "/hello?name=beer" ).getContentAsString(); + + System.out.println( "httpResponse hello annotation servlet:" + response ); + + Assert.assertEquals( "hello beer", response.trim() ); + + response = httpClient.GET( "http://localhost:" + port + "/ping?name=beer" ).getContentAsString(); + + System.out.println( "httpResponse ping fragment servlet:" + response ); + + Assert.assertEquals( "pong beer", response.trim() ); + } + finally + { + httpClient.stop(); + } + } +} diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/pom.xml b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/pom.xml new file mode 100644 index 00000000000..84ebb04a284 --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/pom.xml @@ -0,0 +1,89 @@ + + + 4.0.0 + + org.eclipse.jetty.its.jetty-run-distro-mojo-it + jetty-simple-project + 0.0.1-SNAPSHOT + pom + + Jetty :: Simple + + + UTF-8 + UTF-8 + 1.8 + 3.0.0 + @project.version@ + + + + jetty-simple-base + jetty-simple-webapp + + + + + + org.eclipse.jetty.its.jetty-run-distro-mojo-it + jetty-simple-base + ${project.version} + + + + javax.servlet + javax.servlet-api + 3.1.0 + jar + provided + + + + org.slf4j + slf4j-api + 1.7.21 + + + + commons-io + commons-io + 2.5 + + + + org.eclipse.jetty + jetty-servlet + ${jetty.version} + + + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.5.1 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.1 + + + org.eclipse.jetty + jetty-maven-plugin + ${jetty.version} + + + + + + diff --git a/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/postbuild.groovy b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/postbuild.groovy new file mode 100644 index 00000000000..8a524044e2a --- /dev/null +++ b/jetty-maven-plugin/src/it/jetty-run-distro-mojo-it/postbuild.groovy @@ -0,0 +1,13 @@ + + +System.out.println( "running postbuild.groovy port " + jettyStopPort + ", key:" + jettyStopKey ) + +int port = Integer.parseInt( jettyStopPort ) + +Socket s=new Socket(InetAddress.getByName("127.0.0.1"),port ) +s.setSoLinger(false, 0) + +OutputStream out=s.getOutputStream() +out.write(( jettyStopKey +"\r\nforcestop\r\n").getBytes()) +out.flush() +s.close() \ No newline at end of file diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java index 85c459bb712..30258a11deb 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyRunDistro.java @@ -24,6 +24,9 @@ import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.LineNumberReader; +import java.io.PrintWriter; import java.net.URI; import java.nio.file.FileAlreadyExistsException; import java.nio.file.FileVisitOption; @@ -36,6 +39,9 @@ import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; import java.util.EnumSet; import java.util.List; +import java.util.Locale; +import java.util.Random; +import java.util.concurrent.TimeUnit; import org.apache.maven.artifact.Artifact; import org.apache.maven.artifact.repository.ArtifactRepository; @@ -50,6 +56,7 @@ 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.StringUtil; import org.eclipse.jetty.util.TypeUtil; import org.eclipse.jetty.util.resource.JarResource; import org.eclipse.jetty.util.resource.Resource; @@ -108,6 +115,11 @@ public class JettyRunDistro extends JettyRunMojo */ private String[] modules; + /** + * Arbitrary jvm args to pass to the forked process + * @parameter property="jetty.jvmArgs" + */ + private String jvmArgs; /** * Optional list of jetty properties to put on the command line @@ -145,16 +157,34 @@ public class JettyRunDistro extends JettyRunMojo /** + * Whether to wait for the child to finish or not. * @parameter default-value="true" */ private boolean waitForChild; + /** + * How many times to check to see if the + * child has started successfully. + * + * @parameter default-value="10" + */ + private int maxChildChecks; + + /** + * How long to wait between each + * poll of the child startup state. + * + * @parameter default-value="100" + */ + private long maxChildCheckInterval; private File targetBase; private List libExtJars; + private Random random; + private Path tokenFile; // IDEAS: @@ -167,6 +197,7 @@ public class JettyRunDistro extends JettyRunMojo @Override public void execute() throws MojoExecutionException, MojoFailureException { + random = new Random(); List pdeps = plugin.getPlugin().getDependencies(); if (pdeps != null && !pdeps.isEmpty()) { @@ -218,7 +249,6 @@ public class JettyRunDistro extends JettyRunMojo //create the command to run the new process ProcessBuilder command = configureCommand(); - if (waitForChild) { @@ -226,14 +256,28 @@ public class JettyRunDistro extends JettyRunMojo } else { - command.redirectErrorStream(true); command.redirectOutput(new File(target, "jetty.out")); + command.redirectErrorStream(true); } Process process = command.start(); if (waitForChild) + //keep executing until the child dies process.waitFor(); + else + { + //just wait until the child has started successfully + int attempts = maxChildChecks; + while (!Files.exists(tokenFile) && attempts > 0) + { + Thread.currentThread().sleep(maxChildCheckInterval); + --attempts; + } + if (attempts <=0 ) + getLog().info("Couldn't verify success of child startup"); + } + } catch (Exception e) { @@ -389,6 +433,13 @@ public class JettyRunDistro extends JettyRunMojo IO.copy(mavenModStream, fileStream); } + //copy in the jetty-maven.xml file + try (InputStream jettyMavenStream = getClass().getClassLoader().getResourceAsStream("jetty-maven.xml"); + FileOutputStream fileStream = new FileOutputStream(etcPath.resolve("jetty-maven.xml").toFile())) + { + IO.copy(jettyMavenStream, fileStream); + } + //if there were plugin dependencies, copy them into lib/ext if (libExtJars != null && !libExtJars.isEmpty()) { @@ -429,15 +480,27 @@ public class JettyRunDistro extends JettyRunMojo * @return */ public ProcessBuilder configureCommand() + throws Exception { List 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); + if (jvmArgs != null) + { + String[] args = jvmArgs.split(" "); + for (String a:args) + { + if (!StringUtil.isBlank(a)) + cmd.add(a.trim()); + } + } + StringBuilder tmp = new StringBuilder(); tmp.append("--module="); tmp.append("server,http,webapp,deploy"); @@ -446,24 +509,23 @@ public class JettyRunDistro extends JettyRunMojo for (String m:modules) { if (tmp.indexOf(m) < 0) - tmp.append(","+m); + 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()); - + cmd.add(p); } + + tokenFile = target.toPath().resolve(createToken()+".txt"); + cmd.add("jetty.token.file="+tokenFile.toAbsolutePath().toString()); ProcessBuilder builder = new ProcessBuilder(cmd); builder.directory(targetBase); @@ -510,5 +572,11 @@ public class JettyRunDistro extends JettyRunMojo { //do nothing } + + private String createToken () + { + return Long.toString(random.nextLong()^System.currentTimeMillis(), 36).toUpperCase(Locale.ENGLISH); + } + } diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerListener.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerListener.java new file mode 100644 index 00000000000..cfaa3a243b9 --- /dev/null +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/ServerListener.java @@ -0,0 +1,105 @@ +// +// ======================================================================== +// 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 org.eclipse.jetty.util.component.LifeCycle; +import org.eclipse.jetty.util.resource.Resource; + +/** + * ServerListener + * + * Listener to create a file that signals that the startup is completed. + * Used by the JettyRunDistro maven goal to determine that the child + * process is started, and that jetty is ready. + */ +public class ServerListener implements LifeCycle.Listener +{ + + private String _tokenFile; + + public void setTokenFile(String file) + { + _tokenFile = file; + } + + + public String getTokenFile () + { + return _tokenFile; + } + /** + * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleStarting(org.eclipse.jetty.util.component.LifeCycle) + */ + @Override + public void lifeCycleStarting(LifeCycle event) + { + + } + + /** + * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleStarted(org.eclipse.jetty.util.component.LifeCycle) + */ + @Override + public void lifeCycleStarted(LifeCycle event) + { + if (_tokenFile != null) + { + try + { + Resource r = Resource.newResource(_tokenFile); + r.getFile().createNewFile(); + } + catch (Exception e) + { + throw new IllegalStateException(e); + } + } + + } + + /** + * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleFailure(org.eclipse.jetty.util.component.LifeCycle, java.lang.Throwable) + */ + @Override + public void lifeCycleFailure(LifeCycle event, Throwable cause) + { + + } + + /** + * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleStopping(org.eclipse.jetty.util.component.LifeCycle) + */ + @Override + public void lifeCycleStopping(LifeCycle event) + { + + } + + /** + * @see org.eclipse.jetty.util.component.LifeCycle.Listener#lifeCycleStopped(org.eclipse.jetty.util.component.LifeCycle) + */ + @Override + public void lifeCycleStopped(LifeCycle event) + { + + } + + +} diff --git a/jetty-maven-plugin/src/main/resources/jetty-maven.xml b/jetty-maven-plugin/src/main/resources/jetty-maven.xml new file mode 100644 index 00000000000..5c107d8dd59 --- /dev/null +++ b/jetty-maven-plugin/src/main/resources/jetty-maven.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/jetty-maven-plugin/src/main/resources/maven.mod b/jetty-maven-plugin/src/main/resources/maven.mod index 1b700fef621..ee54ce0ebbb 100644 --- a/jetty-maven-plugin/src/main/resources/maven.mod +++ b/jetty-maven-plugin/src/main/resources/maven.mod @@ -8,3 +8,6 @@ annotations [lib] lib/maven/**.jar + +[xml] +etc/jetty-maven.xml diff --git a/jetty-maven-plugin/src/main/resources/maven.xml b/jetty-maven-plugin/src/main/resources/maven.xml index 55c60af5342..b4d9ab88c5b 100644 --- a/jetty-maven-plugin/src/main/resources/maven.xml +++ b/jetty-maven-plugin/src/main/resources/maven.xml @@ -11,7 +11,6 @@ - /etc/maven.props