├── .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 |
--------------------------------------------------------------------------------