1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.springframework.osgi.web.deployer.jetty;
18
19 import java.io.File;
20 import java.io.IOException;
21
22 import org.mortbay.jetty.Server;
23 import org.mortbay.jetty.handler.ContextHandlerCollection;
24 import org.mortbay.jetty.handler.HandlerCollection;
25 import org.mortbay.jetty.webapp.WebAppContext;
26 import org.mortbay.resource.Resource;
27 import org.mortbay.util.IO;
28 import org.osgi.framework.Bundle;
29 import org.springframework.osgi.util.OsgiBundleUtils;
30 import org.springframework.osgi.util.OsgiStringUtils;
31 import org.springframework.osgi.web.deployer.OsgiWarDeploymentException;
32 import org.springframework.osgi.web.deployer.WarDeployment;
33 import org.springframework.osgi.web.deployer.WarDeploymentContext;
34 import org.springframework.osgi.web.deployer.internal.util.Utils;
35 import org.springframework.osgi.web.deployer.support.AbstractWarDeployer;
36 import org.springframework.util.Assert;
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54 public class JettyWarDeployer extends AbstractWarDeployer {
55
56
57
58 private static final String[] systemClasses = { "java.", "javax.servlet.", "javax.xml.", "org.mortbay." };
59
60
61
62 private static final String[] serverClasses = { "-org.mortbay.jetty.plus.jaas.", "org.mortbay.jetty." };
63
64
65 private Server serverService;
66
67
68
69
70
71
72
73
74
75
76
77
78 public void setServer(Object server) {
79 if (server != null) {
80 Assert.isInstanceOf(Server.class, server, "Invalid Jetty Server given:");
81 this.serverService = (Server) server;
82 }
83 }
84
85 public void afterPropertiesSet() throws Exception {
86 super.afterPropertiesSet();
87
88 if (serverService == null) {
89 log.info("No Jetty Server set; looking for one in the OSGi service registry...");
90 try {
91 serverService = (Server) Utils.createServerServiceProxy(getBundleContext(), Server.class, null);
92 log.info("Found service " + serverService);
93 }
94 catch (RuntimeException ex) {
95 log.error("No Jetty Server found, bailing out", ex);
96 throw ex;
97 }
98 }
99 }
100
101
102
103
104
105
106 protected WarDeployment createDeployment(Bundle bundle, String contextPath) throws Exception {
107 WebAppContext wac = createJettyWebContext(bundle, contextPath);
108
109 wac.setAttribute(WarDeploymentContext.OSGI_BUNDLE_CONTEXT_ATTRIBUTE, OsgiBundleUtils.getBundleContext(bundle));
110 JettyWarDeployment deployment = new JettyWarDeployment(new JettyContextUndeployer() {
111
112 public void undeploy(WebAppContext webAppCtx) throws OsgiWarDeploymentException {
113 stopWebAppContext(webAppCtx);
114 }
115 }, bundle, wac);
116
117 return deployment;
118 }
119
120 protected void startDeployment(WarDeployment deployment) throws Exception {
121 Assert.isInstanceOf(JettyWarDeployment.class, deployment, "Wrong type of deployment used");
122 startWebAppContext(((JettyWarDeployment) deployment).getWebAppContext());
123 }
124
125
126
127
128
129
130
131
132 private WebAppContext createJettyWebContext(Bundle bundle, String contextPath) throws Exception {
133
134 WebAppContext wac = new WebAppContext();
135
136
137
138
139 wac.setServer(serverService);
140
141 wac.setWar(OsgiStringUtils.nullSafeName(bundle));
142
143 wac.setContextPath(contextPath);
144
145 wac.setCopyWebDir(false);
146 wac.setExtractWAR(true);
147
148
149
150
151
152
153 Resource rootResource = getRootResource(bundle, wac);
154
155
156
157
158
159 wac.setBaseResource(rootResource);
160
161 wac.setWar(null);
162
163
164
165
166
167
168 wac.setSystemClasses(systemClasses);
169 wac.setServerClasses(serverClasses);
170
171
172 wac.setParentLoaderPriority(false);
173
174 wac.setClassLoader(Utils.createWebAppClassLoader(bundle, Server.class));
175
176 return wac;
177 }
178
179 private Resource getRootResource(Bundle bundle, WebAppContext wac) throws Exception {
180
181
182 File unpackFolder = unpackBundle(bundle, wac);
183
184 return Resource.newResource(unpackFolder.getCanonicalPath());
185
186
187
188
189
190
191 }
192
193
194
195
196
197
198
199 private void startWebAppContext(WebAppContext wac) throws Exception {
200 HandlerCollection contexts = getJettyContexts();
201
202
203 Thread current = Thread.currentThread();
204 ClassLoader old = current.getContextClassLoader();
205 try {
206 current.setContextClassLoader(wac.getClassLoader());
207 if (contexts != null) {
208 contexts.addHandler(wac);
209 }
210 wac.start();
211 if (contexts != null) {
212 contexts.start();
213 }
214 }
215 finally {
216 current.setContextClassLoader(old);
217 }
218 }
219
220
221
222
223
224
225
226 private void stopWebAppContext(WebAppContext wac) throws OsgiWarDeploymentException {
227
228 Resource rootResource = wac.getBaseResource();
229 String contextPath = wac.getContextPath();
230
231 String messageEnding = "context [" + contextPath + "] from server " + getServerInfo();
232
233 log.info("About to undeploy " + messageEnding);
234
235 HandlerCollection contexts = getJettyContexts();
236
237 Thread current = Thread.currentThread();
238 ClassLoader old = current.getContextClassLoader();
239 try {
240 current.setContextClassLoader(wac.getClassLoader());
241 wac.stop();
242 if (contexts != null) {
243 contexts.removeHandler(wac);
244 }
245 log.info("Context [" + contextPath + "] undeployed successfully from server " + getServerInfo());
246 }
247 catch (Exception ex) {
248 throw new OsgiWarDeploymentException("Cannot undeploy " + messageEnding, ex);
249 }
250 finally {
251 current.setContextClassLoader(old);
252
253
254 if (log.isDebugEnabled())
255 log.debug("Cleaning unpacked folder " + rootResource);
256 try {
257 IO.delete(rootResource.getFile());
258 }
259 catch (IOException ex) {
260
261
262 log.warn("Could not clean unpacked folder for " + messageEnding, ex);
263 }
264 }
265 }
266
267 private HandlerCollection getJettyContexts() {
268 HandlerCollection contexts = (HandlerCollection) serverService.getChildHandlerByClass(ContextHandlerCollection.class);
269 if (contexts == null)
270 contexts = (HandlerCollection) serverService.getChildHandlerByClass(HandlerCollection.class);
271
272 return contexts;
273 }
274
275 private File unpackBundle(Bundle bundle, WebAppContext wac) throws Exception {
276
277
278
279 File tmpFile = File.createTempFile("jetty-" + wac.getContextPath().substring(1), ".osgi");
280 tmpFile.delete();
281 tmpFile.mkdir();
282
283 if (log.isDebugEnabled())
284 log.debug("Unpacking bundle " + OsgiStringUtils.nullSafeNameAndSymName(bundle) + " to folder ["
285 + tmpFile.getCanonicalPath() + "] ...");
286 Utils.unpackBundle(bundle, tmpFile);
287
288 return tmpFile;
289 }
290
291 protected String getServerInfo() {
292 return "Jetty-" + Server.getVersion();
293 }
294 }