├── .classpath ├── .gitignore ├── .project ├── .settings └── org.eclipse.jdt.core.prefs ├── README.markdown ├── pom.xml └── src ├── main └── java │ ├── META-INF │ └── webapp │ │ └── WEB-INF │ │ ├── application-context.xml │ │ ├── i18n │ │ └── messages.properties │ │ ├── views │ │ └── index.jsp │ │ ├── web-context.xml │ │ └── web.xml │ └── com │ └── sjl │ ├── Main.java │ ├── WebServer.java │ └── web │ └── Home.java └── test └── java └── com └── sjl ├── IDE.java └── JettyStartupIntegrationTest.java /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target 2 | var 3 | dependency-reduced-pom.xml 4 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | webapp 3 | NO_M2ECLIPSE_SUPPORT: Project files created with the maven-eclipse-plugin are not supported in M2Eclipse. 4 | 5 | 6 | 7 | org.eclipse.jdt.core.javabuilder 8 | 9 | 10 | 11 | org.eclipse.jdt.core.javanature 12 | 13 | -------------------------------------------------------------------------------- /.settings/org.eclipse.jdt.core.prefs: -------------------------------------------------------------------------------- 1 | #Sat Aug 25 09:00:03 BST 2012 2 | org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 3 | eclipse.preferences.version=1 4 | org.eclipse.jdt.core.compiler.source=1.6 5 | org.eclipse.jdt.core.compiler.compliance=1.6 6 | -------------------------------------------------------------------------------- /README.markdown: -------------------------------------------------------------------------------- 1 | A simple example project that sets up an embedded Jetty 9 with Spring-MVC, JSP and JSTL support. 2 | 3 | Further description [here](http://steveliles.github.com/). -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | com.sjl 6 | webapp 7 | 1.0-SNAPSHOT 8 | WebApp 9 | 10 | 11 | 12 | 13 | springsource-repo 14 | SpringSource Repository 15 | http://repo.springsource.org/release 16 | 17 | 18 | 19 | 20 | UTF-8 21 | 9.1.4.v20140401 22 | 9.1.4.v20140401 23 | 4.0.4.RELEASE 24 | 25 | 26 | 27 | 28 | 29 | org.apache.maven.plugins 30 | maven-surefire-plugin 31 | 2.17 32 | 33 | 40 | false 41 | 42 | 43 | 44 | org.apache.maven.plugins 45 | maven-source-plugin 46 | 3.0.1 47 | 48 | 49 | attach-sources 50 | verify 51 | 52 | jar-no-fork 53 | 54 | 55 | 56 | 57 | 58 | maven-compiler-plugin 59 | 3.6.1 60 | 61 | 1.6 62 | 1.6 63 | 64 | 65 | 66 | maven-eclipse-plugin 67 | 2.9 68 | 69 | true 70 | 71 | 72 | 73 | org.codehaus.mojo 74 | build-helper-maven-plugin 75 | 3.0.0 76 | 77 | 78 | add-resource 79 | generate-resources 80 | 81 | add-resource 82 | 83 | 84 | 85 | 86 | src/main/java/META-INF/webapp 87 | META-INF/webapp 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | org.apache.maven.plugins 96 | maven-shade-plugin 97 | 3.0.0 98 | 99 | 100 | 101 | shade 102 | 103 | 104 | 105 | 106 | *:* 107 | 108 | **/*.DSA 109 | **/*.RSA 110 | **/*.SF 111 | 112 | 113 | 114 | 115 | 116 | 117 | com.sjl.Main 118 | 119 | 120 | META-INF/spring.handlers 121 | 122 | 123 | META-INF/spring.schemas 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | org.springframework 138 | spring-context 139 | ${spring.version} 140 | 141 | 142 | org.springframework 143 | spring-webmvc 144 | ${spring.version} 145 | 146 | 147 | 148 | 149 | org.eclipse.jetty 150 | jetty-server 151 | ${jetty.version} 152 | 153 | 154 | org.eclipse.jetty 155 | jetty-servlet 156 | ${jetty.version} 157 | 158 | 159 | org.eclipse.jetty 160 | jetty-webapp 161 | ${jetty.version} 162 | 163 | 164 | org.eclipse.jetty 165 | jetty-servlets 166 | ${jetty.version} 167 | 168 | 169 | 170 | 171 | org.eclipse.jetty 172 | jetty-jsp 173 | ${jetty.jsp.version} 174 | 175 | 176 | javax.servlet 177 | jstl 178 | 1.2 179 | provided 180 | 181 | 182 | junit 183 | junit 184 | 4.11 185 | test 186 | 187 | 188 | commons-io 189 | commons-io 190 | 2.4 191 | test 192 | 193 | 194 | 195 | 196 | 197 | -------------------------------------------------------------------------------- /src/main/java/META-INF/webapp/WEB-INF/application-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/META-INF/webapp/WEB-INF/i18n/messages.properties: -------------------------------------------------------------------------------- 1 | hello=Hi -------------------------------------------------------------------------------- /src/main/java/META-INF/webapp/WEB-INF/views/index.jsp: -------------------------------------------------------------------------------- 1 | <%@taglib prefix="spring" uri="http://www.springframework.org/tags"%> 2 | 3 | 4 |

5 | 6 | -------------------------------------------------------------------------------- /src/main/java/META-INF/webapp/WEB-INF/web-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/main/java/META-INF/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | org.springframework.web.context.ContextLoaderListener 9 | 10 | 11 | 12 | contextConfigLocation 13 | 14 | /WEB-INF/application-context.xml 15 | 16 | 17 | 18 | 19 | 20 | Spring MVC Dispatcher Servlet 21 | org.springframework.web.servlet.DispatcherServlet 22 | 23 | contextConfigLocation 24 | /WEB-INF/web-context.xml 25 | 26 | 1 27 | 28 | 29 | 30 | Spring MVC Dispatcher Servlet 31 | / 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/java/com/sjl/Main.java: -------------------------------------------------------------------------------- 1 | package com.sjl; 2 | 3 | public class Main 4 | { 5 | public static void main(String... anArgs) throws Exception 6 | { 7 | new Main().start(); 8 | } 9 | 10 | private WebServer server; 11 | 12 | public Main() 13 | { 14 | server = new WebServer(8000); 15 | } 16 | 17 | public void start() throws Exception 18 | { 19 | server.start(); 20 | server.join(); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/main/java/com/sjl/WebServer.java: -------------------------------------------------------------------------------- 1 | package com.sjl; 2 | 3 | import java.io.File; 4 | import java.net.URL; 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | import org.eclipse.jetty.server.Handler; 9 | import org.eclipse.jetty.server.NCSARequestLog; 10 | import org.eclipse.jetty.server.NetworkTrafficServerConnector; 11 | import org.eclipse.jetty.server.RequestLog; 12 | import org.eclipse.jetty.server.Server; 13 | import org.eclipse.jetty.server.handler.HandlerCollection; 14 | import org.eclipse.jetty.server.handler.HandlerList; 15 | import org.eclipse.jetty.server.handler.RequestLogHandler; 16 | import org.eclipse.jetty.util.thread.QueuedThreadPool; 17 | import org.eclipse.jetty.util.thread.ThreadPool; 18 | import org.eclipse.jetty.webapp.WebAppContext; 19 | 20 | /** 21 | * Example WebServer class which sets up an embedded Jetty appropriately 22 | * whether running in an IDE or in "production" mode in a shaded jar. 23 | * 24 | * @author steve liles 25 | */ 26 | public class WebServer 27 | { 28 | // TODO: You should configure this appropriately for your environment 29 | private static final String LOG_PATH = "./var/logs/access/yyyy_mm_dd.request.log"; 30 | 31 | private static final String WEB_XML = "META-INF/webapp/WEB-INF/web.xml"; 32 | private static final String CLASS_ONLY_AVAILABLE_IN_IDE = "com.sjl.IDE"; 33 | private static final String PROJECT_RELATIVE_PATH_TO_WEBAPP = "src/main/java/META-INF/webapp"; 34 | 35 | private int localPort; 36 | 37 | public static interface WebContext 38 | { 39 | public File getWarPath(); 40 | public String getContextPath(); 41 | } 42 | 43 | 44 | private Server server; 45 | private int port; 46 | private String bindInterface; 47 | 48 | public WebServer(int aPort) 49 | { 50 | this(aPort, null); 51 | } 52 | 53 | public WebServer(int aPort, String aBindInterface) 54 | { 55 | port = aPort; 56 | bindInterface = aBindInterface; 57 | } 58 | 59 | public int getLocalPort() { 60 | return localPort; 61 | } 62 | 63 | public void start() throws Exception 64 | { 65 | server = new Server(createThreadPool()); 66 | 67 | NetworkTrafficServerConnector connector = createConnector(); 68 | server.addConnector(connector); 69 | 70 | server.setHandler(createHandlers()); 71 | server.setStopAtShutdown(true); 72 | 73 | server.start(); 74 | localPort = connector.getLocalPort(); 75 | } 76 | 77 | public void join() throws InterruptedException 78 | { 79 | server.join(); 80 | } 81 | 82 | public void stop() throws Exception 83 | { 84 | server.stop(); 85 | } 86 | 87 | private ThreadPool createThreadPool() 88 | { 89 | // TODO: You should configure these appropriately 90 | // for your environment - this is an example only 91 | QueuedThreadPool _threadPool = new QueuedThreadPool(); 92 | _threadPool.setMinThreads(10); 93 | _threadPool.setMaxThreads(100); 94 | return _threadPool; 95 | } 96 | 97 | private NetworkTrafficServerConnector createConnector() 98 | { 99 | NetworkTrafficServerConnector _connector = new NetworkTrafficServerConnector(server); 100 | _connector.setPort(port); 101 | _connector.setHost(bindInterface); 102 | return _connector; 103 | } 104 | 105 | private HandlerCollection createHandlers() 106 | { 107 | WebAppContext _ctx = new WebAppContext(); 108 | _ctx.setContextPath("/"); 109 | 110 | if(isRunningInShadedJar()) 111 | { 112 | _ctx.setWar(getShadedWarUrl()); 113 | } 114 | else 115 | { 116 | _ctx.setWar(PROJECT_RELATIVE_PATH_TO_WEBAPP); 117 | } 118 | 119 | List _handlers = new ArrayList(); 120 | 121 | _handlers.add(_ctx); 122 | 123 | HandlerList _contexts = new HandlerList(); 124 | _contexts.setHandlers(_handlers.toArray(new Handler[0])); 125 | 126 | RequestLogHandler _log = new RequestLogHandler(); 127 | _log.setRequestLog(createRequestLog()); 128 | 129 | HandlerCollection _result = new HandlerCollection(); 130 | _result.setHandlers(new Handler[] {_contexts, _log}); 131 | 132 | return _result; 133 | } 134 | 135 | private RequestLog createRequestLog() 136 | { 137 | NCSARequestLog _log = new NCSARequestLog(); 138 | 139 | File _logPath = new File(LOG_PATH); 140 | _logPath.getParentFile().mkdirs(); 141 | 142 | _log.setFilename(_logPath.getPath()); 143 | _log.setRetainDays(90); 144 | _log.setExtended(false); 145 | _log.setAppend(true); 146 | _log.setLogTimeZone("GMT"); 147 | _log.setLogLatency(true); 148 | return _log; 149 | } 150 | 151 | //--------------------------- 152 | // Discover the war path 153 | //--------------------------- 154 | 155 | private boolean isRunningInShadedJar() 156 | { 157 | try 158 | { 159 | Class.forName(CLASS_ONLY_AVAILABLE_IN_IDE); 160 | return false; 161 | } 162 | catch(ClassNotFoundException anExc) 163 | { 164 | return true; 165 | } 166 | } 167 | 168 | private URL getResource(String aResource) 169 | { 170 | return Thread.currentThread().getContextClassLoader().getResource(aResource); 171 | } 172 | 173 | private String getShadedWarUrl() 174 | { 175 | String _urlStr = getResource(WEB_XML).toString(); 176 | // Strip off "WEB-INF/web.xml" 177 | return _urlStr.substring(0, _urlStr.length() - 15); 178 | } 179 | } 180 | -------------------------------------------------------------------------------- /src/main/java/com/sjl/web/Home.java: -------------------------------------------------------------------------------- 1 | package com.sjl.web; 2 | 3 | import org.springframework.stereotype.*; 4 | import org.springframework.web.bind.annotation.*; 5 | import org.springframework.web.servlet.*; 6 | 7 | @Controller 8 | public class Home { 9 | 10 | @RequestMapping("/") 11 | public ModelAndView home() 12 | { 13 | return new ModelAndView("index"); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/test/java/com/sjl/IDE.java: -------------------------------------------------------------------------------- 1 | package com.sjl; 2 | 3 | public class IDE { 4 | // This class is a place-holder used to identify whether the 5 | // web-server is running in an IDE where the test class hierarchy 6 | // is available or in "production" mode (test classes removed) 7 | } 8 | -------------------------------------------------------------------------------- /src/test/java/com/sjl/JettyStartupIntegrationTest.java: -------------------------------------------------------------------------------- 1 | package com.sjl; 2 | 3 | import static org.hamcrest.CoreMatchers.containsString; 4 | import static org.junit.Assert.*; 5 | 6 | import java.io.InputStream; 7 | import java.net.URL; 8 | import java.net.URLConnection; 9 | 10 | import org.apache.commons.io.IOUtils; 11 | import org.junit.Test; 12 | 13 | public class JettyStartupIntegrationTest 14 | { 15 | 16 | @Test 17 | public void homePageReturnsStatusOk() throws Exception 18 | { 19 | WebServer server = new WebServer(0); 20 | 21 | server.start(); 22 | 23 | server.getLocalPort(); 24 | 25 | URL url = new URL("http", "localhost", server.getLocalPort(), "/"); 26 | URLConnection connection = url.openConnection(); 27 | 28 | connection.connect(); 29 | 30 | InputStream stream = null; 31 | try 32 | { 33 | stream = connection.getInputStream(); 34 | 35 | String htmlContents = IOUtils.toString(connection.getInputStream()); 36 | assertThat(htmlContents, containsString("

Hi

")); 37 | } finally { 38 | IOUtils.closeQuietly(stream); 39 | } 40 | } 41 | } 42 | --------------------------------------------------------------------------------