1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.eclipse.jetty.osgi.nested;
20
21 import java.lang.reflect.Method;
22
23 import javax.servlet.http.HttpServlet;
24
25 import org.eclipse.jetty.nested.NestedConnector;
26 import org.eclipse.jetty.util.component.AbstractLifeCycle.AbstractLifeCycleListener;
27 import org.eclipse.jetty.util.component.LifeCycle;
28 import org.osgi.framework.FrameworkUtil;
29
30
31
32
33
34
35
36
37
38
39 public class NestedConnectorListener extends AbstractLifeCycleListener
40 {
41
42
43
44
45
46 private String bridgeServletClassName = "org.eclipse.equinox.servletbridge.BridgeServlet";
47
48
49
50
51
52 private String registerServletDelegateMethodName = "registerServletDelegate";
53
54
55
56
57
58 private String unregisterServletDelegateMethodName = "unregisterServletDelegate";
59
60
61
62
63
64 private NestedConnectorServletDelegate _servletDelegate;
65
66
67
68
69 private NestedConnector nestedConnector;
70
71
72
73
74
75
76 public void setBridgeServletClassName(String bridgeServletClassName)
77 {
78 this.bridgeServletClassName = bridgeServletClassName;
79 }
80
81 public String getBridgeServletClassName()
82 {
83 return this.bridgeServletClassName;
84 }
85
86 public String getRegisterServletDelegateMethodName()
87 {
88 return this.registerServletDelegateMethodName;
89 }
90
91 public String getUnregisterServletDelegateMethodName()
92 {
93 return this.unregisterServletDelegateMethodName;
94 }
95
96
97
98
99
100 public void setRegisterServletDelegateMethodName(String registerServletDelegateMethodName)
101 {
102 this.registerServletDelegateMethodName = registerServletDelegateMethodName;
103 }
104
105
106
107
108
109 public void setUnregisterServletDelegateMethodName(String unregisterServletDelegateMethodName)
110 {
111 this.unregisterServletDelegateMethodName = unregisterServletDelegateMethodName;
112 }
113
114
115
116
117 public void setNestedConnector(NestedConnector nestedConnector)
118 {
119 this.nestedConnector = nestedConnector;
120 }
121
122
123
124
125 public NestedConnector getNestedConnector()
126 {
127 return this.nestedConnector;
128 }
129
130 @Override
131 public void lifeCycleStarted(LifeCycle event)
132 {
133 try
134 {
135 registerWithBridgeServlet();
136 }
137 catch (Exception e)
138 {
139 if (e instanceof RuntimeException) { throw (RuntimeException) e; }
140 throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", e);
141 }
142 }
143
144 @Override
145 public void lifeCycleStopping(LifeCycle event)
146 {
147 try
148 {
149 unregisterWithBridgeServlet();
150 }
151 catch (Exception e)
152 {
153 if (e instanceof RuntimeException) { throw (RuntimeException) e; }
154 throw new RuntimeException("Unable to unregister the servlet delegate into the BridgeServlet.", e);
155 }
156 }
157
158
159
160
161 protected void registerWithBridgeServlet() throws Exception
162 {
163 _servletDelegate = new NestedConnectorServletDelegate(getNestedConnector());
164 try
165 {
166 invokeStaticMethod(getBridgeServletClassName(), getRegisterServletDelegateMethodName(), new Class[] { HttpServlet.class }, _servletDelegate);
167 }
168 catch (Throwable t)
169 {
170 _servletDelegate.destroy();
171 _servletDelegate = null;
172 if (t instanceof Exception) { throw (Exception) t; }
173 throw new RuntimeException("Unable to register the servlet delegate into the BridgeServlet.", t);
174 }
175 }
176
177
178
179
180 protected void unregisterWithBridgeServlet() throws Exception
181 {
182 if (_servletDelegate != null)
183 {
184 try
185 {
186 invokeStaticMethod(getBridgeServletClassName(), getUnregisterServletDelegateMethodName(), new Class[] { HttpServlet.class }, _servletDelegate);
187 }
188 catch (Throwable t)
189 {
190 if (t instanceof Exception) { throw (Exception) t; }
191 throw new RuntimeException("Unable to unregister the servlet delegate from the BridgeServlet.", t);
192 }
193 finally
194 {
195 _servletDelegate.destroy();
196 _servletDelegate = null;
197 }
198 }
199 }
200
201
202
203
204
205
206
207
208 private static void invokeStaticMethod(String clName, String methName, Class[] argType, Object... args) throws Exception
209 {
210 Method m = getMethod(clName, methName, argType);
211 m.invoke(null, args);
212 }
213
214
215
216
217
218
219
220
221
222 private static Method getMethod(String clName, String methName, Class... argType) throws Exception
223 {
224 Class bridgeServletClass = FrameworkUtil.class.getClassLoader().loadClass(clName);
225 return getMethod(bridgeServletClass, methName, argType);
226 }
227
228 private static Method getMethod(Class cl, String methName, Class... argType) throws Exception
229 {
230 Method meth = null;
231 try
232 {
233 meth = cl.getMethod(methName, argType);
234 return meth;
235 }
236 catch (Exception e)
237 {
238 for (Method m : cl.getMethods())
239 {
240 if (m.getName().equals(methName) && m.getParameterTypes().length == argType.length)
241 {
242 int i = 0;
243 for (Class p : m.getParameterTypes())
244 {
245 Class ap = argType[i];
246 if (p.getName().equals(ap.getName()) && !p.equals(ap))
247 {
248 throw new IllegalStateException("The method \"" + m.toGenericString()
249 + "\" was found. but the parameter class "
250 + p.getName()
251 + " is not the same "
252 + " inside OSGi classloader ("
253 + ap.getClassLoader()
254 + ") and inside the "
255 + cl.getName()
256 + " classloader ("
257 + p.getClassLoader()
258 + ")."
259 + " Are the ExtensionBundles correctly defined?");
260
261 }
262 }
263 }
264 }
265 throw e;
266 }
267 }
268 }