403513 jetty:run goal cannot be executed twice during the maven build
This commit is contained in:
parent
63f2719938
commit
25f5e38e13
|
@ -40,7 +40,7 @@ import org.eclipse.jetty.util.thread.ShutdownThread;
|
|||
* <p>
|
||||
* Commands "stop" and "status" are currently supported.
|
||||
*/
|
||||
public class ShutdownMonitor extends Thread
|
||||
public class ShutdownMonitor
|
||||
{
|
||||
// Implementation of safe lazy init, using Initialization on Demand Holder technique.
|
||||
static class Holder
|
||||
|
@ -53,11 +53,164 @@ public class ShutdownMonitor extends Thread
|
|||
return Holder.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* ShutdownMonitorThread
|
||||
*
|
||||
* Thread for listening to STOP.PORT for command to stop Jetty.
|
||||
* If ShowndownMonitor.exitVm is true, then Sytem.exit will also be
|
||||
* called after the stop.
|
||||
*
|
||||
*/
|
||||
public class ShutdownMonitorThread extends Thread
|
||||
{
|
||||
|
||||
public ShutdownMonitorThread ()
|
||||
{
|
||||
setDaemon(true);
|
||||
setName("ShutdownMonitor");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (serverSocket == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (serverSocket != null)
|
||||
{
|
||||
Socket socket = null;
|
||||
try
|
||||
{
|
||||
socket = serverSocket.accept();
|
||||
|
||||
LineNumberReader lin = new LineNumberReader(new InputStreamReader(socket.getInputStream()));
|
||||
String receivedKey = lin.readLine();
|
||||
if (!key.equals(receivedKey))
|
||||
{
|
||||
System.err.println("Ignoring command with incorrect key");
|
||||
continue;
|
||||
}
|
||||
|
||||
OutputStream out = socket.getOutputStream();
|
||||
|
||||
String cmd = lin.readLine();
|
||||
debug("command=%s",cmd);
|
||||
if ("stop".equals(cmd))
|
||||
{
|
||||
// Graceful Shutdown
|
||||
debug("Issuing graceful shutdown..");
|
||||
ShutdownThread.getInstance().run();
|
||||
|
||||
// Reply to client
|
||||
debug("Informing client that we are stopped.");
|
||||
out.write("Stopped\r\n".getBytes(StringUtil.__UTF8));
|
||||
out.flush();
|
||||
|
||||
// Shutdown Monitor
|
||||
debug("Shutting down monitor");
|
||||
close(socket);
|
||||
socket = null;
|
||||
close(serverSocket);
|
||||
serverSocket = null;
|
||||
|
||||
if (exitVm)
|
||||
{
|
||||
// Kill JVM
|
||||
debug("Killing JVM");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
else if ("status".equals(cmd))
|
||||
{
|
||||
// Reply to client
|
||||
out.write("OK\r\n".getBytes(StringUtil.__UTF8));
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
debug(e);
|
||||
System.err.println(e.toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
close(socket);
|
||||
socket = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
if (isAlive())
|
||||
{
|
||||
System.err.printf("ShutdownMonitorThread already started");
|
||||
return; // cannot start it again
|
||||
}
|
||||
|
||||
startListenSocket();
|
||||
|
||||
if (serverSocket == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
System.err.println("Starting ShutdownMonitorThread");
|
||||
super.start();
|
||||
}
|
||||
|
||||
private void startListenSocket()
|
||||
{
|
||||
if (port < 0)
|
||||
{
|
||||
if (DEBUG)
|
||||
System.err.println("ShutdownMonitor not in use (port < 0): " + port);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
serverSocket = new ServerSocket(port,1,InetAddress.getByName("127.0.0.1"));
|
||||
if (port == 0)
|
||||
{
|
||||
// server assigned port in use
|
||||
port = serverSocket.getLocalPort();
|
||||
System.out.printf("STOP.PORT=%d%n",port);
|
||||
}
|
||||
|
||||
if (key == null)
|
||||
{
|
||||
// create random key
|
||||
key = Long.toString((long)(Long.MAX_VALUE * Math.random() + this.hashCode() + System.currentTimeMillis()),36);
|
||||
System.out.printf("STOP.KEY=%s%n",key);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
debug(e);
|
||||
System.err.println("Error binding monitor port " + port + ": " + e.toString());
|
||||
serverSocket = null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
// establish the port and key that are in use
|
||||
debug("STOP.PORT=%d",port);
|
||||
debug("STOP.KEY=%s",key);
|
||||
debug("%s",serverSocket);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean DEBUG;
|
||||
private int port;
|
||||
private String key;
|
||||
private boolean exitVm;
|
||||
private ServerSocket serverSocket;
|
||||
private ShutdownMonitorThread thread;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a ShutdownMonitor using configuration from the System properties.
|
||||
|
@ -149,77 +302,6 @@ public class ShutdownMonitor extends Thread
|
|||
return exitVm;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if (serverSocket == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
while (serverSocket != null)
|
||||
{
|
||||
Socket socket = null;
|
||||
try
|
||||
{
|
||||
socket = serverSocket.accept();
|
||||
|
||||
LineNumberReader lin = new LineNumberReader(new InputStreamReader(socket.getInputStream()));
|
||||
String key = lin.readLine();
|
||||
if (!this.key.equals(key))
|
||||
{
|
||||
System.err.println("Ignoring command with incorrect key");
|
||||
continue;
|
||||
}
|
||||
|
||||
OutputStream out = socket.getOutputStream();
|
||||
|
||||
String cmd = lin.readLine();
|
||||
debug("command=%s",cmd);
|
||||
if ("stop".equals(cmd))
|
||||
{
|
||||
// Graceful Shutdown
|
||||
debug("Issuing graceful shutdown..");
|
||||
ShutdownThread.getInstance().run();
|
||||
|
||||
// Reply to client
|
||||
debug("Informing client that we are stopped.");
|
||||
out.write("Stopped\r\n".getBytes(StringUtil.__UTF8));
|
||||
out.flush();
|
||||
|
||||
// Shutdown Monitor
|
||||
debug("Shutting down monitor");
|
||||
close(socket);
|
||||
socket = null;
|
||||
close(serverSocket);
|
||||
serverSocket = null;
|
||||
|
||||
if (exitVm)
|
||||
{
|
||||
// Kill JVM
|
||||
debug("Killing JVM");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
else if ("status".equals(cmd))
|
||||
{
|
||||
// Reply to client
|
||||
out.write("OK\r\n".getBytes(StringUtil.__UTF8));
|
||||
out.flush();
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
debug(e);
|
||||
System.err.println(e.toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
close(socket);
|
||||
socket = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setDebug(boolean flag)
|
||||
{
|
||||
|
@ -228,90 +310,71 @@ public class ShutdownMonitor extends Thread
|
|||
|
||||
public void setExitVm(boolean exitVm)
|
||||
{
|
||||
if (isAlive())
|
||||
synchronized (this)
|
||||
{
|
||||
throw new IllegalStateException("ShutdownMonitor already started");
|
||||
if (thread != null && thread.isAlive())
|
||||
{
|
||||
throw new IllegalStateException("ShutdownMonitorThread already started");
|
||||
}
|
||||
this.exitVm = exitVm;
|
||||
}
|
||||
this.exitVm = exitVm;
|
||||
}
|
||||
|
||||
public void setKey(String key)
|
||||
{
|
||||
if (isAlive())
|
||||
synchronized (this)
|
||||
{
|
||||
throw new IllegalStateException("ShutdownMonitor already started");
|
||||
if (thread != null && thread.isAlive())
|
||||
{
|
||||
throw new IllegalStateException("ShutdownMonitorThread already started");
|
||||
}
|
||||
this.key = key;
|
||||
}
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public void setPort(int port)
|
||||
{
|
||||
if (isAlive())
|
||||
synchronized (this)
|
||||
{
|
||||
throw new IllegalStateException("ShutdownMonitor already started");
|
||||
}
|
||||
this.port = port;
|
||||
}
|
||||
|
||||
public void start()
|
||||
{
|
||||
if (isAlive())
|
||||
{
|
||||
System.err.printf("ShutdownMonitor already started");
|
||||
return; // cannot start it again
|
||||
}
|
||||
startListenSocket();
|
||||
if (serverSocket == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
super.start();
|
||||
}
|
||||
|
||||
private void startListenSocket()
|
||||
{
|
||||
if (this.port < 0)
|
||||
{
|
||||
if (DEBUG)
|
||||
System.err.println("ShutdownMonitor not in use (port < 0): " + port);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
setDaemon(true);
|
||||
setName("ShutdownMonitor");
|
||||
|
||||
this.serverSocket = new ServerSocket(this.port,1,InetAddress.getByName("127.0.0.1"));
|
||||
if (this.port == 0)
|
||||
if (thread != null && thread.isAlive())
|
||||
{
|
||||
// server assigned port in use
|
||||
this.port = serverSocket.getLocalPort();
|
||||
System.out.printf("STOP.PORT=%d%n",this.port);
|
||||
throw new IllegalStateException("ShutdownMonitorThread already started");
|
||||
}
|
||||
|
||||
if (this.key == null)
|
||||
{
|
||||
// create random key
|
||||
this.key = Long.toString((long)(Long.MAX_VALUE * Math.random() + this.hashCode() + System.currentTimeMillis()),36);
|
||||
System.out.printf("STOP.KEY=%s%n",this.key);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
debug(e);
|
||||
System.err.println("Error binding monitor port " + this.port + ": " + e.toString());
|
||||
}
|
||||
finally
|
||||
{
|
||||
// establish the port and key that are in use
|
||||
debug("STOP.PORT=%d",this.port);
|
||||
debug("STOP.KEY=%s",this.key);
|
||||
debug("%s",serverSocket);
|
||||
this.port = port;
|
||||
}
|
||||
}
|
||||
|
||||
protected void start() throws Exception
|
||||
{
|
||||
ShutdownMonitorThread t = null;
|
||||
synchronized (this)
|
||||
{
|
||||
if (thread != null && thread.isAlive())
|
||||
{
|
||||
System.err.printf("ShutdownMonitorThread already started");
|
||||
return; // cannot start it again
|
||||
}
|
||||
|
||||
thread = new ShutdownMonitorThread();
|
||||
t = thread;
|
||||
}
|
||||
|
||||
if (t != null)
|
||||
t.start();
|
||||
}
|
||||
|
||||
|
||||
protected boolean isAlive ()
|
||||
{
|
||||
boolean result = false;
|
||||
synchronized (this)
|
||||
{
|
||||
result = (thread != null && thread.isAlive());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2013 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.server;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.LineNumberReader;
|
||||
import java.io.OutputStream;
|
||||
import java.net.InetAddress;
|
||||
import java.net.Socket;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* ShutdownMonitorTest
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class ShutdownMonitorTest
|
||||
{
|
||||
|
||||
|
||||
@Test
|
||||
public void testShutdown ()
|
||||
throws Exception
|
||||
{
|
||||
|
||||
//test port and key assignment
|
||||
ShutdownMonitor.getInstance().setPort(0);
|
||||
ShutdownMonitor.getInstance().setExitVm(false);
|
||||
ShutdownMonitor.getInstance().start();
|
||||
String key = ShutdownMonitor.getInstance().getKey();
|
||||
int port = ShutdownMonitor.getInstance().getPort();
|
||||
|
||||
//try starting a 2nd time (should be ignored)
|
||||
ShutdownMonitor.getInstance().start();
|
||||
|
||||
|
||||
stop(port,key,true);
|
||||
assertTrue(!ShutdownMonitor.getInstance().isAlive());
|
||||
|
||||
//should be able to change port and key because it is stopped
|
||||
ShutdownMonitor.getInstance().setPort(0);
|
||||
ShutdownMonitor.getInstance().setKey("foo");
|
||||
ShutdownMonitor.getInstance().start();
|
||||
|
||||
key = ShutdownMonitor.getInstance().getKey();
|
||||
port = ShutdownMonitor.getInstance().getPort();
|
||||
assertTrue(ShutdownMonitor.getInstance().isAlive());
|
||||
|
||||
stop(port,key,true);
|
||||
assertTrue(!ShutdownMonitor.getInstance().isAlive());
|
||||
}
|
||||
|
||||
|
||||
public void stop (int port, String key, boolean check)
|
||||
throws Exception
|
||||
{
|
||||
Socket s = null;
|
||||
|
||||
try
|
||||
{
|
||||
//send stop command
|
||||
s = new Socket(InetAddress.getByName("127.0.0.1"),port);
|
||||
|
||||
OutputStream out = s.getOutputStream();
|
||||
out.write((key + "\r\nstop\r\n").getBytes());
|
||||
out.flush();
|
||||
|
||||
if (check)
|
||||
{
|
||||
//wait a little
|
||||
Thread.currentThread().sleep(600);
|
||||
|
||||
//check for stop confirmation
|
||||
LineNumberReader lin = new LineNumberReader(new InputStreamReader(s.getInputStream()));
|
||||
String response;
|
||||
if ((response = lin.readLine()) != null)
|
||||
{
|
||||
assertEquals("Stopped", response);
|
||||
}
|
||||
else
|
||||
throw new IllegalStateException("No stop confirmation");
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (s != null) s.close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue