Skip to content

Commit b1e08ba

Browse files
authored
Issue #5020 Make servlets,filters,listeners beans again (#5028)
* Issue #5020 Make servlets,filters,listeners beans again Signed-off-by: Jan Bartel <[email protected]>
1 parent ca404f1 commit b1e08ba

File tree

4 files changed

+120
-8
lines changed

4 files changed

+120
-8
lines changed

jetty-servlet/src/main/java/org/eclipse/jetty/servlet/ServletHandler.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,12 @@ public ServletHandler()
133133
{
134134
}
135135

136+
@Override
137+
public boolean isDumpable(Object o)
138+
{
139+
return !(o instanceof Holder || o instanceof BaseHolder || o instanceof FilterMapping || o instanceof ServletMapping);
140+
}
141+
136142
@Override
137143
public void dump(Appendable out, String indent) throws IOException
138144
{
@@ -220,6 +226,13 @@ protected void start(LifeCycle l) throws Exception
220226
if (!(l instanceof Holder))
221227
super.start(l);
222228
}
229+
230+
@Override
231+
protected void stop(LifeCycle l) throws Exception
232+
{
233+
if (!(l instanceof Holder))
234+
super.stop(l);
235+
}
223236

224237
@Override
225238
protected synchronized void doStop()
@@ -262,8 +275,10 @@ protected synchronized void doStop()
262275

263276
//Retain only filters and mappings that were added using jetty api (ie Source.EMBEDDED)
264277
FilterHolder[] fhs = (FilterHolder[])LazyList.toArray(filterHolders, FilterHolder.class);
278+
updateBeans(_filters, fhs);
265279
_filters = fhs;
266280
FilterMapping[] fms = (FilterMapping[])LazyList.toArray(filterMappings, FilterMapping.class);
281+
updateBeans(_filterMappings, fms);
267282
_filterMappings = fms;
268283

269284
_matchAfterIndex = (_filterMappings == null || _filterMappings.length == 0 ? -1 : _filterMappings.length - 1);
@@ -305,8 +320,10 @@ protected synchronized void doStop()
305320

306321
//Retain only Servlets and mappings added via jetty apis (ie Source.EMBEDDED)
307322
ServletHolder[] shs = (ServletHolder[])LazyList.toArray(servletHolders, ServletHolder.class);
323+
updateBeans(_servlets, shs);
308324
_servlets = shs;
309325
ServletMapping[] sms = (ServletMapping[])LazyList.toArray(servletMappings, ServletMapping.class);
326+
updateBeans(_servletMappings, sms);
310327
_servletMappings = sms;
311328

312329
if (_contextHandler != null)
@@ -331,6 +348,7 @@ protected synchronized void doStop()
331348
}
332349
}
333350
ListenerHolder[] listeners = (ListenerHolder[])LazyList.toArray(listenerHolders, ListenerHolder.class);
351+
updateBeans(_listeners, listeners);
334352
_listeners = listeners;
335353

336354
//will be regenerated on next start
@@ -814,7 +832,7 @@ public void setListeners(ListenerHolder[] listeners)
814832
{
815833
holder.setServletHandler(this);
816834
}
817-
835+
updateBeans(_listeners,listeners);
818836
_listeners = listeners;
819837
}
820838

@@ -1516,6 +1534,7 @@ public void setFilterChainsCached(boolean filterChainsCached)
15161534
*/
15171535
public void setFilterMappings(FilterMapping[] filterMappings)
15181536
{
1537+
updateBeans(_filterMappings,filterMappings);
15191538
_filterMappings = filterMappings;
15201539
if (isStarted())
15211540
updateMappings();
@@ -1529,7 +1548,7 @@ public synchronized void setFilters(FilterHolder[] holders)
15291548
{
15301549
holder.setServletHandler(this);
15311550
}
1532-
1551+
updateBeans(_filters,holders);
15331552
_filters = holders;
15341553
updateNameMappings();
15351554
invalidateChainsCache();
@@ -1540,6 +1559,7 @@ public synchronized void setFilters(FilterHolder[] holders)
15401559
*/
15411560
public void setServletMappings(ServletMapping[] servletMappings)
15421561
{
1562+
updateBeans(_servletMappings,servletMappings);
15431563
_servletMappings = servletMappings;
15441564
if (isStarted())
15451565
updateMappings();
@@ -1558,7 +1578,7 @@ public synchronized void setServlets(ServletHolder[] holders)
15581578
{
15591579
holder.setServletHandler(this);
15601580
}
1561-
1581+
updateBeans(_servlets,holders);
15621582
_servlets = holders;
15631583
updateNameMappings();
15641584
invalidateChainsCache();

jetty-servlet/src/test/java/org/eclipse/jetty/servlet/ServletHandlerTest.java

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,15 @@
1818

1919
package org.eclipse.jetty.servlet;
2020

21+
import java.util.ArrayList;
2122
import java.util.EnumSet;
23+
import java.util.List;
2224
import javax.servlet.DispatcherType;
25+
import javax.servlet.http.HttpSessionEvent;
26+
import javax.servlet.http.HttpSessionListener;
2327

2428
import org.eclipse.jetty.http.pathmap.MappedResource;
29+
import org.eclipse.jetty.util.component.Container;
2530
import org.junit.jupiter.api.BeforeEach;
2631
import org.junit.jupiter.api.Test;
2732

@@ -657,4 +662,72 @@ public void testAddFilterWithMappingAPI() throws Exception
657662
assertTrue(fh3 == mappings[5].getFilterHolder()); //isMatchAfter = true;
658663
assertTrue(pf == mappings[6].getFilterHolder()); //isMatchAfter = true;
659664
}
665+
666+
@Test
667+
public void testFiltersServletsListenersAsBeans() throws Exception
668+
{
669+
ServletContextHandler context = new ServletContextHandler();
670+
671+
ServletHandler handler = context.getServletHandler();
672+
673+
//test that filters, servlets and listeners are added as beans
674+
//and thus reported in a Container.Listener
675+
List<Object> addResults = new ArrayList<>();
676+
List<Object> removeResults = new ArrayList<>();
677+
handler.addEventListener(new Container.Listener()
678+
{
679+
@Override
680+
public void beanAdded(Container parent, Object child)
681+
{
682+
addResults.add(child);
683+
}
684+
685+
@Override
686+
public void beanRemoved(Container parent, Object child)
687+
{
688+
removeResults.add(child);
689+
}
690+
691+
});
692+
693+
handler.addFilter(fh1);
694+
handler.addServlet(sh1);
695+
ListenerHolder lh1 = new ListenerHolder(new Source(Source.Origin.DESCRIPTOR, "foo.xml"));
696+
lh1.setInstance(new HttpSessionListener()
697+
{
698+
@Override
699+
public void sessionDestroyed(HttpSessionEvent se)
700+
{
701+
}
702+
703+
@Override
704+
public void sessionCreated(HttpSessionEvent se)
705+
{
706+
}
707+
});
708+
handler.addListener(lh1);
709+
710+
assertTrue(addResults.contains(fh1));
711+
assertTrue(addResults.contains(sh1));
712+
assertTrue(addResults.contains(lh1));
713+
714+
//test that servlets, filters and listeners are dumped, but
715+
//not as beans
716+
String dump = handler.dump();
717+
dump = dump.substring(0, dump.indexOf("key:"));
718+
719+
assertFalse(dump.contains("+-")); //not dumped as beans
720+
assertFalse(dump.contains("+=")); //not dumped as managed beans
721+
assertFalse(dump.contains("+~")); //not dumped as unmanaged beans
722+
assertFalse(dump.contains("+?")); //not dumped as auto beans
723+
724+
handler.setFilters(null);
725+
handler.setServlets(null);
726+
handler.setListeners(null);
727+
728+
//check they're removed as beans
729+
assertTrue(removeResults.contains(fh1));
730+
assertTrue(removeResults.contains(sh1));
731+
assertTrue(removeResults.contains(lh1));
732+
}
660733
}

jetty-util/src/main/java/org/eclipse/jetty/util/component/ContainerLifeCycle.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@
7575
* </pre>
7676
*/
7777
@ManagedObject("Implementation of Container and LifeCycle")
78-
public class ContainerLifeCycle extends AbstractLifeCycle implements Container, Destroyable, Dumpable
78+
public class ContainerLifeCycle extends AbstractLifeCycle implements Container, Destroyable, Dumpable.DumpableContainer
7979
{
8080
private static final Logger LOG = Log.getLogger(ContainerLifeCycle.class);
8181
private final List<Bean> _beans = new CopyOnWriteArrayList<>();

jetty-util/src/main/java/org/eclipse/jetty/util/component/Dumpable.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -145,9 +145,9 @@ else if (o instanceof Map)
145145
static void dumpObjects(Appendable out, String indent, Object object, Object... extraChildren) throws IOException
146146
{
147147
dumpObject(out, object);
148-
148+
149149
int extras = extraChildren == null ? 0 : extraChildren.length;
150-
150+
151151
if (object instanceof Stream)
152152
object = ((Stream)object).toArray();
153153
if (object instanceof Array)
@@ -181,14 +181,18 @@ else if (object instanceof Map)
181181
dumpObjects(out, nextIndent, item);
182182
}
183183
}
184-
184+
185185
static void dumpContainer(Appendable out, String indent, Container object, boolean last) throws IOException
186186
{
187187
Container container = object;
188188
ContainerLifeCycle containerLifeCycle = container instanceof ContainerLifeCycle ? (ContainerLifeCycle)container : null;
189189
for (Iterator<Object> i = container.getBeans().iterator(); i.hasNext(); )
190190
{
191191
Object bean = i.next();
192+
193+
if (container instanceof DumpableContainer && !((DumpableContainer)container).isDumpable(bean))
194+
continue; //won't be dumped as a child bean
195+
192196
String nextIndent = indent + ((i.hasNext() || !last) ? "| " : " ");
193197
if (bean instanceof LifeCycle)
194198
{
@@ -229,7 +233,7 @@ else if (containerLifeCycle != null && containerLifeCycle.isUnmanaged(bean))
229233
}
230234
}
231235
}
232-
236+
233237
static void dumpIterable(Appendable out, String indent, Iterable<?> iterable, boolean last) throws IOException
234238
{
235239
for (Iterator i = iterable.iterator(); i.hasNext(); )
@@ -267,4 +271,19 @@ static Dumpable named(String name, Object object)
267271
Dumpable.dumpObjects(out, indent, object);
268272
};
269273
}
274+
275+
/**
276+
* DumpableContainer
277+
*
278+
* A Dumpable that is a container of beans can implement this
279+
* interface to allow it to refine which of its beans can be
280+
* dumped.
281+
*/
282+
public interface DumpableContainer extends Dumpable
283+
{
284+
default boolean isDumpable(Object o)
285+
{
286+
return true;
287+
}
288+
}
270289
}

0 commit comments

Comments
 (0)