Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWinston Prakash2012-02-03 03:39:02 -0500
committerWinston Prakash2012-02-03 03:39:02 -0500
commit4ac40d5139bb2d5763f700ac416c3873317fe6f2 (patch)
tree7030a3fdc8cb1a081dc3ccfa964a4a08e6a6c376
parent620fef9435dfc1aeb5ef825eaf8657286be46cdf (diff)
downloadorg.eclipse.hudson.core-4ac40d5139bb2d5763f700ac416c3873317fe6f2.tar.gz
org.eclipse.hudson.core-4ac40d5139bb2d5763f700ac416c3873317fe6f2.tar.xz
org.eclipse.hudson.core-4ac40d5139bb2d5763f700ac416c3873317fe6f2.zip
Instead of unpacking all the classes of jetty jars in to the war root, keep them as jars in a libs folder and load the classes from them using a URL class loader.
-rw-r--r--hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/jetty/JettyLauncher.java90
-rwxr-xr-xhudson-jetty-war-executable/src/main/java/org/eclipse/hudson/war/Executable.java159
-rwxr-xr-xhudson-jetty-war-executable/src/main/java/org/eclipse/hudson/war/executable/StartJetty.java119
-rw-r--r--hudson-war/pom.xml63
4 files changed, 290 insertions, 141 deletions
diff --git a/hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/jetty/JettyLauncher.java b/hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/jetty/JettyLauncher.java
new file mode 100644
index 00000000..940b4cdc
--- /dev/null
+++ b/hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/jetty/JettyLauncher.java
@@ -0,0 +1,90 @@
+/**
+ * *****************************************************************************
+ *
+ * Copyright (c) 2012 Oracle Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Winston Prakash
+ *
+ *******************************************************************************/
+
+package org.eclipse.hudson.jetty;
+
+import java.io.File;
+import java.net.URL;
+import org.mortbay.jetty.Server;
+import org.mortbay.jetty.bio.SocketConnector;
+import org.mortbay.jetty.webapp.WebAppContext;
+
+/**
+ * Jetty Utility to launch the Jetty Server
+ * @author Winston Prakash
+ */
+public class JettyLauncher {
+
+ public static void start(String[] args, URL warUrl) throws Exception {
+
+ int port = 8080;
+
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("--httpPort=")) {
+ String portStr = args[i].substring("--httpPort=".length());
+ port = Integer.parseInt(portStr);
+ }
+ }
+
+ Server server = new Server(port);
+ SocketConnector connector = new SocketConnector();
+
+ WebAppContext context = new WebAppContext();
+
+ File tempDir = new File(getHomeDir(), "war");
+ tempDir.mkdirs();
+ context.setTempDirectory(tempDir);
+
+ context.setContextPath("/");
+ context.setDescriptor(warUrl.toExternalForm() + "/WEB-INF/web.xml");
+ context.setServer(server);
+ context.setWar(warUrl.toExternalForm());
+
+ // This is used by Windows Service Installer in Hudson Management
+ System.out.println("War - " + warUrl.getPath());
+ System.setProperty("executable-war", warUrl.getPath());
+
+ server.addHandler(context);
+ server.start();
+ server.join();
+ }
+
+ /**
+ * Get the home directory for Hudson.
+ */
+ private static File getHomeDir() {
+
+ // Check HUDSON_HOME system property
+ String hudsonHomeProperty = System.getProperty("HUDSON_HOME");
+ if (hudsonHomeProperty != null) {
+ return new File(hudsonHomeProperty.trim());
+ }
+
+ // Check if the environment variable is et
+ try {
+ String hudsonHomeEnv = System.getenv("HUDSON_HOME");
+ if (hudsonHomeEnv != null) {
+ return new File(hudsonHomeEnv.trim()).getAbsoluteFile();
+ }
+ } catch (Throwable _) {
+ // Some JDK could throw error if HUDSON_HOME is not set.
+ // Ignore and fall through
+ }
+
+ // Default hudson home
+ return new File(new File(System.getProperty("user.home")), ".hudson");
+ }
+}
diff --git a/hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/war/Executable.java b/hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/war/Executable.java
new file mode 100755
index 00000000..158259ec
--- /dev/null
+++ b/hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/war/Executable.java
@@ -0,0 +1,159 @@
+package org.eclipse.hudson.war;
+
+/**
+ * *****************************************************************************
+ *
+ * Copyright (c) 2012 Oracle Corporation.
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ *
+ * Winston Prakash
+ *
+ ******************************************************************************
+ */
+import java.io.*;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.security.ProtectionDomain;
+import java.util.ArrayList;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.jar.JarEntry;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+/**
+ * Simple boot class to make the war executable
+ *
+ * @author Winston Prakash
+ */
+public class Executable {
+
+ private String[] jettyJars = {
+ "libs/jetty.jar",
+ "libs/jetty-util.jar",
+ "libs/jetty-servlet-api.jar",
+ "libs/hudson-jetty-war-executable.jar"
+ };
+
+ public static void main(String[] args) throws Exception {
+
+ for (int i = 0; i < args.length; i++) {
+ if (args[i].startsWith("--version")) {
+ System.out.println("Hudson Continuous Integration Server" + getVersion());
+ System.exit(0);
+ } else if (args[i].startsWith("--usage")) {
+ String usageStr = "Hudson Continuous Integration Server " + getVersion() + "\n"
+ + "Usage: java -jar hudson.war [--option=value] [--option=value] ... \n"
+ + "\n"
+ + "Options:\n"
+ + " --httpPort=<value> HTTP listening port. Default value is 8080\n"
+ + " --version Show Hudson version and quit\n";
+ System.out.println(usageStr);
+ System.exit(0);
+ }
+ }
+
+ Executable jettyLauncher = new Executable();
+ jettyLauncher.launchJetty(args);
+ }
+
+ private void launchJetty(String[] args) throws Exception {
+ ProtectionDomain protectionDomain = Executable.class.getProtectionDomain();
+ URL warUrl = protectionDomain.getCodeSource().getLocation();
+
+ List<URL> jarUrls = extractJettyJarsFromWar(warUrl.getPath());
+
+ ClassLoader urlClassLoader = new URLClassLoader(jarUrls.toArray(new URL[jarUrls.size()]));
+ Thread.currentThread().setContextClassLoader(urlClassLoader);
+
+ Class jettyUtil = urlClassLoader.loadClass("org.eclipse.hudson.jetty.JettyLauncher");
+ Method mainMethod = jettyUtil.getMethod("start", new Class[]{String[].class, URL.class});
+ mainMethod.invoke(null, new Object[]{args, warUrl});
+ }
+
+ /**
+ * Find the Hudson version from war manifest
+ *
+ * @return
+ * @throws IOException
+ */
+ private static String getVersion() throws IOException {
+ Enumeration manifests = Executable.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
+ while (manifests.hasMoreElements()) {
+ URL manifestUrl = (URL) manifests.nextElement();
+ Manifest manifest = new Manifest(manifestUrl.openStream());
+ String hudsonVersion = manifest.getMainAttributes().getValue("Hudson-Version");
+ if (hudsonVersion != null) {
+ return hudsonVersion;
+ }
+ }
+ return "Unknown Version";
+ }
+
+ /**
+ * Extract the Jetty Jars from the war
+ *
+ * @throws IOException
+ */
+ private List<URL> extractJettyJarsFromWar(String warPath) throws IOException {
+
+ System.out.println(warPath);
+
+ JarFile jarFile = new JarFile(warPath);
+
+
+
+ List<URL> jarUrls = new ArrayList<URL>();
+
+ InputStream inStream = null;
+
+ try {
+
+ for (String entryPath : jettyJars) {
+
+ File tmpFile;
+ try {
+ tmpFile = File.createTempFile(entryPath.replaceAll("/", "_"), "hudson");
+ } catch (IOException e) {
+ String tmpdir = System.getProperty("java.io.tmpdir");
+ throw new IOException("Failed to extract " + entryPath + " to " + tmpdir, e);
+ }
+ JarEntry jarEntry = jarFile.getJarEntry(entryPath);
+ inStream = jarFile.getInputStream(jarEntry);
+
+ OutputStream outStream = new FileOutputStream(tmpFile);
+ try {
+ byte[] buffer = new byte[8192];
+ int readLength;
+ while ((readLength = inStream.read(buffer)) > 0) {
+ outStream.write(buffer, 0, readLength);
+ }
+ } catch (Exception exc) {
+ exc.printStackTrace();
+ } finally {
+ outStream.close();
+ }
+
+ tmpFile.deleteOnExit();
+ System.out.println("Extracted " + entryPath + " to " + tmpFile);
+ jarUrls.add(tmpFile.toURI().toURL());
+ }
+
+ } catch (Exception exc) {
+ exc.printStackTrace();
+ } finally {
+ if (inStream != null) {
+ inStream.close();
+ }
+ }
+
+ return jarUrls;
+ }
+}
diff --git a/hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/war/executable/StartJetty.java b/hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/war/executable/StartJetty.java
deleted file mode 100755
index 40a53ecc..00000000
--- a/hudson-jetty-war-executable/src/main/java/org/eclipse/hudson/war/executable/StartJetty.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*******************************************************************************
- *
- * Copyright (c) 2004-2011 Oracle Corporation.
- *
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *
- * Winston Prakash
- *
- *
- *******************************************************************************/
-package org.eclipse.hudson.war.executable;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URL;
-import java.security.ProtectionDomain;
-import java.util.Enumeration;
-import java.util.jar.Manifest;
-import org.mortbay.jetty.Server;
-import org.mortbay.jetty.bio.SocketConnector;
-import org.mortbay.jetty.webapp.WebAppContext;
-
-/**
- * Simple boot class to make the war executable
- * @author Winston Prakash
- */
-public class StartJetty {
-
- public static void main(String[] args) throws Exception {
- int port = 8080;
- for (int i = 0; i < args.length; i++) {
- if (args[i].startsWith("--httpPort=")) {
- String portStr = args[i].substring("--httpPort=".length());
- port = Integer.parseInt(portStr);
- }else if (args[i].startsWith("--version")) {
- System.out.println("Hudson Continuous Integration Server" + getVersion());
- System.exit(0);
- }else if (args[i].startsWith("--usage")) {
- String usageStr = "Hudson Continuous Integration Server " + getVersion() + "\n" +
- "Usage: java -jar hudson.war [--option=value] [--option=value] ... \n" +
- "\n" +
- "Options:\n" +
- " --httpPort=<value> HTTP listening port. Default value is 8080\n" +
- " --version Show Hudson version and quit\n";
- System.out.println(usageStr);
- System.exit(0);
- }
- }
-
- Server server = new Server(port);
- SocketConnector connector = new SocketConnector();
-
- ProtectionDomain protectionDomain = StartJetty.class.getProtectionDomain();
- URL location = protectionDomain.getCodeSource().getLocation();
-
- WebAppContext context = new WebAppContext();
-
- File tempDir = new File(getHomeDir(), "war");
- tempDir.mkdirs();
- context.setTempDirectory(tempDir);
-
- context.setContextPath("/");
- context.setDescriptor(location.toExternalForm() + "/WEB-INF/web.xml");
- context.setServer(server);
- context.setWar(location.toExternalForm());
-
- // This is used by Windows Service Installer in Hudson Management
- System.out.println("War location - " + location.getPath());
- System.setProperty("executable-war", location.getPath());
-
- server.addHandler(context);
- server.start();
- server.join();
- }
-
- /**
- * Get the home directory for Hudson.
- */
- private static File getHomeDir() {
-
- // Check HUDSON_HOME system property
- String hudsonHomeProperty = System.getProperty("HUDSON_HOME");
- if (hudsonHomeProperty != null) {
- return new File(hudsonHomeProperty.trim());
- }
-
- // Check if the environment variable is et
- try {
- String hudsonHomeEnv = System.getenv("HUDSON_HOME");
- if (hudsonHomeEnv != null) {
- return new File(hudsonHomeEnv.trim()).getAbsoluteFile();
- }
- } catch (Throwable _) {
- // Some JDK could throw error if HUDSON_HOME is not set.
- // Ignore and fall through
- }
-
- // Default hudson home
- return new File(new File(System.getProperty("user.home")), ".hudson");
- }
-
- private static String getVersion() throws IOException {
- Enumeration manifests = StartJetty.class.getClassLoader().getResources("META-INF/MANIFEST.MF");
- while (manifests.hasMoreElements()) {
- URL manifestUrl = (URL) manifests.nextElement();
- Manifest manifest = new Manifest(manifestUrl.openStream());
- String hudsonVersion = manifest.getMainAttributes().getValue("Hudson-Version");
- if (hudsonVersion != null) {
- return hudsonVersion;
- }
- }
- return "Unknown Version";
- }
-}
diff --git a/hudson-war/pom.xml b/hudson-war/pom.xml
index ebdc3446..f873cc67 100644
--- a/hudson-war/pom.xml
+++ b/hudson-war/pom.xml
@@ -50,13 +50,16 @@
<webResources>
<resource>
+ <directory>${project.build.directory}/classes</directory>
+ </resource>
+ <resource>
<directory>${project.build.directory}/generated-resources</directory>
</resource>
</webResources>
- <!-- Main Class to Start Jetty -->
+ <!-- Main bootstrap Class to make war executable -->
<archive>
<manifest>
- <mainClass>org.eclipse.hudson.war.executable.StartJetty</mainClass>
+ <mainClass>org.eclipse.hudson.war.Executable</mainClass>
</manifest>
<manifestEntries>
<Implementation-Version>${project.version}</Implementation-Version>
@@ -89,10 +92,12 @@
<goals>
<goal>unpack</goal>
</goals>
+
<configuration>
- <excludes>
- META-INF/*
- </excludes>
+ <!-- Copy only the bootstrap class -->
+ <includes>
+ **/Executable*
+ </includes>
<artifactItems>
<artifactItem>
@@ -104,42 +109,56 @@
<outputDirectory>target/generated-resources</outputDirectory>
</artifactItem>
- <!-- Jetty Classes -->
+ </artifactItems>
+ </configuration>
+ </execution>
+
+ <execution>
+ <id>copyResources</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>copy</goal>
+ </goals>
+ <configuration>
+ <artifactItems>
+
+ <!-- Jetty war executable libraries -->
+
+ <artifactItem>
+ <groupId>org.eclipse.hudson.main</groupId>
+ <artifactId>hudson-jetty-war-executable</artifactId>
+ <version>${project.version}</version>
+ <type>jar</type>
+ <overWrite>true</overWrite>
+ <outputDirectory>target/generated-resources/libs</outputDirectory>
+ <destFileName>hudson-jetty-war-executable.jar</destFileName>
+ </artifactItem>
+
<artifactItem>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty</artifactId>
<version>6.1.26</version>
<overWrite>true</overWrite>
- <outputDirectory>target/generated-resources</outputDirectory>
+ <outputDirectory>target/generated-resources/libs</outputDirectory>
+ <destFileName>jetty.jar</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-util</artifactId>
<version>6.1.26</version>
<overWrite>true</overWrite>
- <outputDirectory>target/generated-resources</outputDirectory>
+ <outputDirectory>target/generated-resources/libs</outputDirectory>
+ <destFileName>jetty-util.jar</destFileName>
</artifactItem>
<artifactItem>
<groupId>org.mortbay.jetty</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5-20081211</version>
<overWrite>true</overWrite>
- <outputDirectory>target/generated-resources</outputDirectory>
+ <outputDirectory>target/generated-resources/libs</outputDirectory>
+ <destFileName>jetty-servlet-api.jar</destFileName>
</artifactItem>
- </artifactItems>
- </configuration>
- </execution>
-
- <execution>
- <id>copyResources</id>
- <phase>generate-resources</phase>
- <goals>
- <goal>copy</goal>
- </goals>
- <configuration>
- <artifactItems>
-
<!-- dependencies that goes to WEB-INF for unusual usage -->
<artifactItem>

Back to the top