-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit c46b3bb
Showing
11 changed files
with
712 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Maven | ||
/target/ | ||
|
||
# IntelliJ IDEA | ||
*.idea | ||
*.iml | ||
|
||
|
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
# Embbeded Jetty web application Batch Toolkit # | ||
|
||
This project shows how to build a WAR-less Java web application with Jetty. | ||
|
||
Only a single JVM is required to start the web app. No web container or JEE server is required. | ||
|
||
Instead of building a war file, an auto-executable JAR file is built with Maven (ie. jetty-webapp-1.0.0-SNAPSHOT.jar) | ||
|
||
This JAR contains all resources required by a web application: web.xml, index.jsp, images, js, css... | ||
The JettyServer class provides both a start and a stop method. Its main method starts the server. To stop it, you may use the Stop class. | ||
|
||
Thanks to the [Application Assembler Maven Plugin](http://mojo.codehaus.org/appassembler/appassembler-maven-plugin/) a start.sh and a stop.sh script are available. | ||
|
||
All JAR dependencies are available in a lib\ sub-directory. | ||
|
||
|
||
## Try it ## | ||
|
||
Download the code with git: | ||
```git clone git://github.com/arey/embedded-jetty-webapp.git``` | ||
|
||
Build and package the web application | ||
|
||
``` | ||
cd embedded-jetty-webapp | ||
mvn clean install | ||
``` | ||
|
||
Start the web application | ||
```target/appassembler/bin/start.sh &``` | ||
|
||
Stop the web application | ||
```target/appassembler/bin/stop.sh``` | ||
|
||
Browse to [http://localhost:8080/HelloWorld](http://localhost:8080/HelloWorld) | ||
|
||
Web port could be changed at startup: | ||
```target/appassembler/bin/start.sh 80 8090 &``` | ||
|
||
## Configuration rules ## | ||
|
||
Compared to the [Maven Standard Directory Layout](https://maven.apache.org/guides/introduction/introduction-to-the-standard-directory-layout.html) | ||
of a WAR, the web application sources is not put into the ```src/main/webapp``` but into the ```src/main/resources/webapp```. | ||
Thus the webapp resources are copied into the JAR in a webapp/ sub-directory. | ||
|
||
## Credits ## | ||
|
||
* Uses [Maven](http://maven.apache.org/) as a build tool | ||
* Uses [Maven Jetty plugin](https://github.com/eclipse/jetty.project) source code |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
application.name=Hello World |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
package com.javaetmoi.jetty; | ||
|
||
import javax.servlet.ServletException; | ||
import javax.servlet.http.HttpServlet; | ||
import javax.servlet.http.HttpServletRequest; | ||
import javax.servlet.http.HttpServletResponse; | ||
import java.io.IOException; | ||
import java.io.PrintWriter; | ||
|
||
public class HelloWorldServlet extends HttpServlet { | ||
|
||
public void doGet(HttpServletRequest request, | ||
HttpServletResponse response) throws ServletException, IOException { | ||
response.setContentType("text/html"); | ||
PrintWriter out = response.getWriter(); | ||
out.println("<h1>Hello World</h1>"); | ||
out.close(); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package com.javaetmoi.jetty; | ||
|
||
import org.eclipse.jetty.server.Server; | ||
import org.eclipse.jetty.webapp.WebAppContext; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.OutputStream; | ||
import java.net.ConnectException; | ||
import java.net.InetAddress; | ||
import java.net.Socket; | ||
import java.net.URL; | ||
|
||
/** | ||
* Starts with Jetty an auto-executable web application packaged into a JAR file. | ||
*/ | ||
public class JettyServer { | ||
|
||
public static final String WEBAPP_RESOURCES_LOCATION = "webapp"; | ||
static final int DEFAULT_PORT_STOP = 8090; | ||
static final String STOP_KEY = "stopKey"; | ||
private static final int DEFAULT_PORT_START = 8080; | ||
private static final Logger LOGGER = LoggerFactory.getLogger(JettyServer.class); | ||
private final int startPort; | ||
private final int stopPort; | ||
|
||
public JettyServer() { | ||
this(DEFAULT_PORT_START, DEFAULT_PORT_STOP); | ||
} | ||
|
||
public JettyServer(int startPort, int stopPort) { | ||
this.startPort = startPort; | ||
this.stopPort = stopPort; | ||
} | ||
|
||
/** | ||
* Stops a running web application powered with Jetty. | ||
* <p/> | ||
* <p/> | ||
* Default TCP port is used to communicate with Jetty. | ||
*/ | ||
static public void stop() { | ||
stop(DEFAULT_PORT_STOP); | ||
} | ||
|
||
/** | ||
* Stops a running web application powered with Jetty. | ||
* | ||
* @param stopPort TCP port used to communicate with Jetty. | ||
*/ | ||
static public void stop(Integer stopPort) { | ||
try { | ||
Socket s = new Socket(InetAddress.getByName("127.0.0.1"), stopPort); | ||
LOGGER.info("Jetty stopping..."); | ||
s.setSoLinger(false, 0); | ||
OutputStream out = s.getOutputStream(); | ||
out.write((JettyServer.STOP_KEY + "\r\nstop\r\n").getBytes()); | ||
out.flush(); | ||
s.close(); | ||
} catch (ConnectException e) { | ||
LOGGER.info("Jetty not running!"); | ||
} catch (Exception e) { | ||
LOGGER.error(e.getMessage(), e); | ||
} | ||
} | ||
|
||
/** | ||
* Start a Jetty web server with its webapp. | ||
* | ||
* @param args first argument is the web port, second argument is the port used to stop Jetty | ||
* @throws Exception | ||
*/ | ||
public static void main(String[] args) throws Exception { | ||
JettyServer jettyServer = null; | ||
if (args.length == 2) { | ||
jettyServer = new JettyServer(Integer.valueOf(args[0]), Integer.valueOf(args[1])); | ||
} else { | ||
jettyServer = new JettyServer(); | ||
} | ||
jettyServer.start(); | ||
} | ||
|
||
/** | ||
* Start a Jetty server then deploy a web application. | ||
* | ||
* @throws Exception If Jetty fails to start | ||
*/ | ||
public void start() throws Exception { | ||
Server server = new Server(startPort); | ||
WebAppContext root = new WebAppContext(); | ||
|
||
root.setContextPath("/"); | ||
root.setDescriptor(WEBAPP_RESOURCES_LOCATION + "/WEB-INF/web.xml"); | ||
|
||
URL webAppDir = Thread.currentThread().getContextClassLoader().getResource(WEBAPP_RESOURCES_LOCATION); | ||
if (webAppDir == null) { | ||
throw new RuntimeException(String.format("No %s directory was found into the JAR file", WEBAPP_RESOURCES_LOCATION)); | ||
} | ||
root.setResourceBase(webAppDir.toURI().toString()); | ||
root.setParentLoaderPriority(true); | ||
|
||
server.setHandler(root); | ||
|
||
server.start(); | ||
|
||
LOGGER.info("Jetty server started"); | ||
LOGGER.debug("Jetty web server port: {}", startPort); | ||
LOGGER.debug("Port to stop Jetty with {}: {}", STOP_KEY, stopPort); | ||
|
||
Monitor monitor = new Monitor(stopPort, STOP_KEY, new Server[]{server}); | ||
monitor.start(); | ||
|
||
server.join(); | ||
|
||
LOGGER.info("Jetty server exited"); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
package com.javaetmoi.jetty; | ||
|
||
import org.eclipse.jetty.server.Server; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
import java.io.IOException; | ||
import java.io.InputStreamReader; | ||
import java.io.LineNumberReader; | ||
import java.net.InetAddress; | ||
import java.net.ServerSocket; | ||
import java.net.Socket; | ||
import java.net.UnknownHostException; | ||
|
||
/** | ||
* Listens for stop commands and causes jetty to stop by stopping the server instance. | ||
* | ||
* @see <a href="https://github.com/eclipse/jetty.project/tree/master/jetty-maven-plugin">https://github.com/eclipse/jetty.project/tree/master/jetty-maven-plugin</a> | ||
*/ | ||
public class Monitor extends Thread { | ||
|
||
private static Logger LOGGER = LoggerFactory.getLogger(Monitor.class); | ||
|
||
private String key; | ||
private Server[] servers; | ||
ServerSocket serverSocket; | ||
|
||
public Monitor(int port, String key, Server[] servers) throws UnknownHostException, IOException { | ||
if (port <= 0) | ||
throw new IllegalStateException("Bad stop PORT"); | ||
if (key == null) | ||
throw new IllegalStateException("Bad stop key"); | ||
this.key = key; | ||
this.servers = servers; | ||
setDaemon(true); | ||
setName("StopJettyMonitor"); | ||
serverSocket = new ServerSocket(port, 1, InetAddress.getByName("127.0.0.1")); | ||
serverSocket.setReuseAddress(true); | ||
} | ||
|
||
public void run() { | ||
while (serverSocket != null) { | ||
Socket socket = null; | ||
try { | ||
socket = serverSocket.accept(); | ||
socket.setSoLinger(false, 0); | ||
LineNumberReader lin = new LineNumberReader(new InputStreamReader( | ||
socket.getInputStream())); | ||
String key = lin.readLine(); | ||
if (!this.key.equals(key)) | ||
continue; | ||
String cmd = lin.readLine(); | ||
if ("stop".equals(cmd)) { | ||
try { | ||
socket.close(); | ||
} catch (Exception e) { | ||
LOGGER.debug(e.getMessage(), e); | ||
} | ||
try { | ||
socket.close(); | ||
} catch (Exception e) { | ||
LOGGER.debug(e.getMessage(), e); | ||
} | ||
try { | ||
serverSocket.close(); | ||
} catch (Exception e) { | ||
LOGGER.debug(e.getMessage(), e); | ||
} | ||
serverSocket = null; | ||
|
||
for (int i = 0; servers != null && i < servers.length; i++) { | ||
try { | ||
LOGGER.info("Stopping server " + i); | ||
servers[i].stop(); | ||
} catch (Exception e) { | ||
LOGGER.error(e.getMessage(), e); | ||
} | ||
} | ||
|
||
} else | ||
LOGGER.info("Unsupported monitor operation"); | ||
} catch (Exception e) { | ||
LOGGER.error(e.getMessage(), e); | ||
} finally { | ||
if (socket != null) { | ||
try { | ||
socket.close(); | ||
} catch (Exception e) { | ||
LOGGER.debug(e.getMessage(), e); | ||
} | ||
} | ||
socket = null; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
package com.javaetmoi.jetty; | ||
|
||
public class Stop { | ||
|
||
public static void main(String[] args) throws Exception { | ||
if (args.length == 1) { | ||
JettyServer.stop(Integer.valueOf(args[0])); | ||
} else { | ||
JettyServer.stop(); | ||
} | ||
|
||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<configuration> | ||
|
||
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> | ||
<encoder> | ||
<pattern>%d{HH:mm:ss.SSS} [%level] [%thread] %msg%n</pattern> | ||
</encoder> | ||
</appender> | ||
|
||
<logger name="com.javaetmoi.jetty" level="DEBUG"/> | ||
|
||
<root level="INFO"> | ||
<appender-ref ref="STDOUT"/> | ||
</root> | ||
|
||
</configuration> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<?xml version="1.0" encoding="ISO-8859-1"?> | ||
<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
xsi:schemaLocation=" | ||
http://java.sun.com/xml/ns/j2ee | ||
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd" version="2.4"> | ||
|
||
<servlet> | ||
<servlet-name>HelloWorldServlet</servlet-name> | ||
<servlet-class>com.javaetmoi.jetty.HelloWorldServlet</servlet-class> | ||
</servlet> | ||
|
||
<servlet-mapping> | ||
<servlet-name>HelloWorldServlet</servlet-name> | ||
<url-pattern>/HelloWorld</url-pattern> | ||
</servlet-mapping> | ||
|
||
<welcome-file-list> | ||
<welcome-file>index.jsp</welcome-file> | ||
</welcome-file-list> | ||
|
||
</web-app> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
<html> | ||
<body> | ||
Index page | ||
</body> | ||
</html> |