Skip to content

Instantly share code, notes, and snippets.

@kkganesan
Forked from oc/Main.java
Created June 2, 2011 01:59
Show Gist options
  • Save kkganesan/1003779 to your computer and use it in GitHub Desktop.
Save kkganesan/1003779 to your computer and use it in GitHub Desktop.
jetty.port=7004
jetty.warFile=lib/app.war
jetty.contextPath=/
jetty.shutdownSecret=d41d8cd98f00b204e9800998ecf8427e
package no.muda.jetty;
import org.constretto.ConstrettoBuilder;
import org.constretto.ConstrettoConfiguration;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.core.io.DefaultResourceLoader;
import java.io.IOException;
public class Main {
private final int port;
private final String contextPath;
private final String warFile;
private final String shutdownSecret;
public static void main(String[] args) throws Exception {
Main sc = new Main();
if (args.length != 1)
sc.usage();
else if ("status".equals(args[0]))
sc.status();
else if ("stop".equals(args[0]))
sc.stop();
else if ("start".equals(args[0]))
sc.start();
else
sc.usage();
}
public Main() {
ConstrettoConfiguration config = new ConstrettoBuilder()
.createPropertiesStore()
.addResource(new DefaultResourceLoader().getResource("classpath:jetty.properties"))
.done()
.createSystemPropertiesStore()
.getConfiguration();
this.port = config.evaluateToInt("jetty.port");
this.contextPath = config.evaluateToString("jetty.contextPath");
this.warFile = config.evaluateToString("jetty.warFile");
this.shutdownSecret = config.evaluateToString("jetty.shutdownSecret");
}
private void stop() throws IOException {
ShutdownHandler.shutdown(port, shutdownSecret);
}
private void status() {
boolean status = StatusHandler.checkStatus(port);
System.out.println(status ? "running" : "not running");
System.exit(status ? 0 : -1);
}
private void start() throws IOException {
Server server = new Server(port);
String fileName = warFile.substring(warFile.lastIndexOf('/') + 1, warFile.length());
HandlerList handlers = new HandlerList();
handlers.addHandler(new WebAppContext(WarExtractor.extractWar(warFile, fileName), contextPath));
handlers.addHandler(new ShutdownHandler(server, shutdownSecret));
handlers.addHandler(new StatusHandler());
server.setHandler(handlers);
try {
server.start();
server.join();
} catch (Exception ignored) {
}
try {
server.start();
} catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
}
private void usage() {
System.out.println("Usage: java -jar <app.one-jar.jar> [start|stop|status]");
System.exit(-1);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>no.muda</groupId>
<artifactId>app-pkg</artifactId>
<name>App: Jetty Standalone Jar</name>
<properties>
<jetty.version>7.1.4.v20100610</jetty.version>
</properties>
<dependencies>
<dependency>
<groupId>no.muda</groupId>
<artifactId>app</artifactId>
<version>1.0.1</version>
<type>war</type>
</dependency>
<!-- jetty -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlet</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jsp-2.1</artifactId>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jsp-2.1-glassfish</artifactId>
<version>9.1.1.B60.25.p2</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.4</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.constretto</groupId>
<artifactId>constretto-api</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.constretto</groupId>
<artifactId>constretto-core</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
<build>
<finalName>app-pkg</finalName>
<plugins>
<plugin>
<groupId>org.dstovall</groupId>
<artifactId>onejar-maven-plugin</artifactId>
<version>1.4.3</version>
<executions>
<execution>
<configuration>
<mainClass>no.muda.jetty.Main</mainClass>
<onejarVersion>0.96</onejarVersion>
<attachToBuild>false</attachToBuild>
</configuration>
<goals>
<goal>one-jar</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<pluginRepositories>
<pluginRepository>
<id>onejar-maven-plugin.googlecode.com</id>
<url>http://onejar-maven-plugin.googlecode.com/svn/mavenrepo</url>
</pluginRepository>
</pluginRepositories>
</project>
package no.muda.jetty;
import org.eclipse.jetty.http.HttpException;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AbstractHandler;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Based on blogpost by Johannes Brodwall
*/
public class ShutdownHandler extends AbstractHandler {
private final Server server;
private final String secret;
public ShutdownHandler(Server server, String secret) throws MalformedURLException {
this.server = server;
this.secret = secret;
}
public void handle(String target, Request serverRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if (!target.equals("/shutdown"))
return;
if (!request.getMethod().equals("POST"))
throw new HttpException(HttpServletResponse.SC_BAD_REQUEST);
if (!secret.equals(request.getParameter("secret")))
throw new HttpException(HttpServletResponse.SC_UNAUTHORIZED);
try {
server.stop();
} catch (Exception ignored) {}
System.exit(0);
}
public static void shutdown(int port, String shutdownSecret) {
try {
URL url = new URL("http://127.0.0.1:" + port + "/shutdown?secret=" + shutdownSecret);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod("POST");
connection.getResponseCode();
} catch (IOException ignored) {
}
}
}
package no.muda.jetty;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.SocketException;
import java.net.URL;
import java.util.Map;
import java.util.TreeMap;
import javax.naming.InitialContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import org.apache.commons.io.IOUtils;
import org.eclipse.jetty.http.HttpException;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
/**
* Based on blogpost by Johannes Brodwall
*/
public class StatusHandler extends AbstractHandler {
public void handle(String target, Request serverRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
if (!target.equals("/status")) return;
if (!request.getMethod().equals("GET"))
throw new HttpException(HttpServletResponse.SC_BAD_REQUEST);
response.setContentType("text/plain");
Map<String, String> statusIndicators = getStatusIndicators();
for (Map.Entry<String, String> status : statusIndicators.entrySet()) {
response.getWriter().println(status.getKey() + "=" + status.getValue());
}
response.getWriter().close();
response.setStatus(HttpServletResponse.SC_OK);
HttpConnection.getCurrentConnection().getRequest().setHandled(true);
}
private Map<String,String> getStatusIndicators() {
Map<String, String> result = new TreeMap<String, String>();
result.put("server", "running");
result.put("jdbc/baz", getJdbcStatus("jdbc/baz"));
return result;
}
private String getJdbcStatus(String jdniName) {
try {
InitialContext context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup(jdniName);
dataSource.getConnection().close();
return "OK";
} catch (Exception e) {
return e.toString();
}
}
public static boolean checkStatus(int port) {
try {
URL url = new URL("http://localhost:" + port + "/status");
HttpURLConnection connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.getResponseCode();
System.out.println(IOUtils.toString((InputStream)connection.getContent()));
return true;
} catch (SocketException e) {
return false;
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
package no.muda.jetty;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.Validate;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.jar.JarFile;
import java.util.zip.ZipEntry;
/**
* Based on blogpost by Johannes Brodwall
*/
public class WarExtractor {
static String extractWar(String pathInJar, String localName) throws IOException {
Validate.notEmpty(pathInJar, "Path in jar cannot be empty or null");
Validate.notEmpty(localName, "LocalName cannot be empty or null");
JarFile jarFile = getCurrentJarFile();
File outputFile = new File(createTmpDir(localName), localName);
copyAndClose(jarFile.getInputStream(new ZipEntry(pathInJar)), outputFile);
return outputFile.getAbsolutePath();
}
private static void copyAndClose(InputStream input, File outputFile) throws IOException {
Validate.notNull(input, "InputStream cannot be null");
Validate.notNull(outputFile, "Output file cannot be null");
FileOutputStream output = new FileOutputStream(outputFile);
IOUtils.copy(input, output);
input.close();
output.close();
}
private static File createTmpDir(String localName) {
Validate.notEmpty(localName, "LocalName cannot be empty or null");
File tmpDir = new File(System.getProperty("java.io.tmpdir"));
File appDir = new File(new File(tmpDir, "jetty"), localName + "-" + System.currentTimeMillis());
if (!appDir.mkdirs()) {
throw new RuntimeException("Could not create " + appDir);
}
return appDir;
}
private static JarFile getCurrentJarFile() throws IOException {
String[] pathElements = System.getProperty("java.class.path").split(System.getProperty("path.separator"));
String thisFile = null;
for (String path : pathElements) {
if (path.endsWith("one-jar.jar")) {
thisFile = path;
break;
}
}
return new JarFile(thisFile);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment