* Issue #5162 CDI embedded integration improvements Clean up CDI integration and documentation to better support embedded usage. + made listener public + added utility class for SCIs * Issue #5162 CDI embedded integration improvements Clean up CDI integration and documentation to better support embedded usage. + moved EmbeddedWeldTest to jetty-embedded * fix javadoc Signed-off-by: Greg Wilkins <gregw@webtide.com> * Issue #5162 CDI embedded integration improvements ventilated text * fix test pom Signed-off-by: Greg Wilkins <gregw@webtide.com> * Fixed javadoc * Fixed javadoc * Issue #5162 CDI embedded integration improvements Moved tests to jetty-cdi to avoid consequences to other tests in embedded * trailing new line Signed-off-by: Greg Wilkins <gregw@webtide.com> * updates from review Signed-off-by: Greg Wilkins <gregw@webtide.com> * Feedback from review
This commit is contained in:
parent
2826df2048
commit
7ecf42e3f8
|
@ -32,6 +32,12 @@
|
|||
<version>${project.version}</version>
|
||||
<scope>compile</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.weld.servlet</groupId>
|
||||
<artifactId>weld-servlet-core</artifactId>
|
||||
<version>${weld.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<build>
|
||||
<plugins>
|
||||
|
|
|
@ -24,7 +24,7 @@ import org.eclipse.jetty.servlet.ServletContextHandler;
|
|||
/**
|
||||
* A DecoratingListener that listens for "org.eclipse.jetty.cdi.decorator"
|
||||
*/
|
||||
class CdiDecoratingListener extends DecoratingListener
|
||||
public class CdiDecoratingListener extends DecoratingListener
|
||||
{
|
||||
public static final String MODE = "CdiDecoratingListener";
|
||||
public static final String ATTRIBUTE = "org.eclipse.jetty.cdi.decorator";
|
||||
|
@ -32,5 +32,6 @@ class CdiDecoratingListener extends DecoratingListener
|
|||
public CdiDecoratingListener(ServletContextHandler contextHandler)
|
||||
{
|
||||
super(contextHandler, ATTRIBUTE);
|
||||
contextHandler.setAttribute(CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE, MODE);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,8 +86,6 @@ public class CdiServletContainerInitializer implements ServletContainerInitializ
|
|||
default:
|
||||
throw new IllegalStateException(mode);
|
||||
}
|
||||
|
||||
context.setAttribute(CDI_INTEGRATION_ATTRIBUTE, mode);
|
||||
LOG.info(mode + " enabled in " + ctx);
|
||||
}
|
||||
catch (UnsupportedOperationException | ClassNotFoundException e)
|
||||
|
|
|
@ -21,8 +21,12 @@ package org.eclipse.jetty.cdi;
|
|||
import java.lang.invoke.MethodHandle;
|
||||
import java.lang.invoke.MethodHandles;
|
||||
import java.lang.invoke.MethodType;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.util.Decorator;
|
||||
|
@ -61,11 +65,15 @@ public class CdiSpiDecorator implements Decorator
|
|||
private final MethodHandle _inject;
|
||||
private final MethodHandle _dispose;
|
||||
private final MethodHandle _release;
|
||||
private final Set<String> _undecorated = new HashSet<>(Collections.singletonList("org.jboss.weld.environment.servlet.Listener"));
|
||||
|
||||
public CdiSpiDecorator(ServletContextHandler context) throws UnsupportedOperationException
|
||||
{
|
||||
_context = context;
|
||||
context.setAttribute(CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE, MODE);
|
||||
ClassLoader classLoader = _context.getClassLoader();
|
||||
if (classLoader == null)
|
||||
classLoader = this.getClass().getClassLoader();
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -92,6 +100,54 @@ public class CdiSpiDecorator implements Decorator
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a class can be decorated.
|
||||
* The default implementation checks the set from {@link #getUndecoratable()}
|
||||
* on the class and all it's super classes.
|
||||
* @param clazz The class to check
|
||||
* @return True if the class and all it's super classes can be decorated
|
||||
*/
|
||||
protected boolean isDecoratable(Class<?> clazz)
|
||||
{
|
||||
if (Object.class == clazz)
|
||||
return true;
|
||||
if (getUndecoratable().contains(clazz.getName()))
|
||||
return false;
|
||||
return isDecoratable(clazz.getSuperclass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the set of classes that will not be decorated. The default set includes the listener from Weld that will itself
|
||||
* setup decoration.
|
||||
* @return The modifiable set of class names that will not be decorated (ie {@link #isDecoratable(Class)} will return false.
|
||||
* @see #isDecoratable(Class)
|
||||
*/
|
||||
public Set<String> getUndecoratable()
|
||||
{
|
||||
return _undecorated;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param classnames The set of class names that will not be decorated.
|
||||
* @see #isDecoratable(Class)
|
||||
*/
|
||||
public void setUndecoratable(Set<String> classnames)
|
||||
{
|
||||
_undecorated.clear();
|
||||
if (classnames != null)
|
||||
_undecorated.addAll(classnames);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param classname A class name that will be added to the undecoratable classes set.
|
||||
* @see #getUndecoratable()
|
||||
* @see #isDecoratable(Class)
|
||||
*/
|
||||
public void addUndecoratable(String... classname)
|
||||
{
|
||||
_undecorated.addAll(Arrays.asList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Decorate an object.
|
||||
* <p>The signature of this method must match what is introspected for by the
|
||||
|
@ -108,7 +164,8 @@ public class CdiSpiDecorator implements Decorator
|
|||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("decorate {} in {}", o, _context);
|
||||
|
||||
_decorated.put(o, new Decorated(o));
|
||||
if (isDecoratable(o.getClass()))
|
||||
_decorated.put(o, new Decorated(o));
|
||||
}
|
||||
catch (Throwable th)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,332 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.embedded;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.EnumSet;
|
||||
import javax.enterprise.inject.Produces;
|
||||
import javax.enterprise.inject.spi.BeanManager;
|
||||
import javax.enterprise.inject.spi.InjectionPoint;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterChain;
|
||||
import javax.servlet.FilterConfig;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.ServletResponse;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.eclipse.jetty.annotations.AnnotationConfiguration;
|
||||
import org.eclipse.jetty.cdi.CdiServletContainerInitializer;
|
||||
import org.eclipse.jetty.server.LocalConnector;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.servlet.ListenerHolder;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.webapp.Configuration;
|
||||
import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.params.ParameterizedTest;
|
||||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
|
||||
public class EmbeddedWeldTest
|
||||
{
|
||||
public static Server createServerWithServletContext(String mode)
|
||||
{
|
||||
Server server = new Server();
|
||||
server.addConnector(new LocalConnector(server));
|
||||
ServletContextHandler context = new ServletContextHandler();
|
||||
context.setContextPath("/");
|
||||
context.setResourceBase("src/test/resources/weldtest");
|
||||
server.setHandler(context);
|
||||
|
||||
// Setup context
|
||||
context.addFilter(MyFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
context.addServlet(GreetingsServlet.class, "/");
|
||||
context.getServletHandler().addListener(new ListenerHolder(MyContextListener.class));
|
||||
|
||||
// Setup Jetty weld integration
|
||||
switch (mode)
|
||||
{
|
||||
case "none" : // Do nothing, let weld work it out.
|
||||
// Expect:INFO: WELD-ENV-001201: Jetty 7.2+ detected, CDI injection will be available in Servlets and Filters. Injection into Listeners is not supported.
|
||||
context.getServletHandler().addListener(new ListenerHolder(org.jboss.weld.environment.servlet.Listener.class));
|
||||
break;
|
||||
|
||||
case "DecoratingListener+Listener":
|
||||
// Expect:INFO: WELD-ENV-001212: Jetty CdiDecoratingListener support detected, CDI injection will be available in Listeners, Servlets and Filters.
|
||||
context.addEventListener(new org.eclipse.jetty.webapp.DecoratingListener(context));
|
||||
context.getServletHandler().addListener(new ListenerHolder(org.jboss.weld.environment.servlet.Listener.class));
|
||||
break;
|
||||
|
||||
case "CdiDecoratingListener+Listener":
|
||||
// Expect:INFO: WELD-ENV-001212: Jetty CdiDecoratingListener support detected, CDI injection will be available in Listeners, Servlets and Filters.
|
||||
context.addEventListener(new org.eclipse.jetty.cdi.CdiDecoratingListener(context));
|
||||
context.addEventListener(new org.jboss.weld.environment.servlet.Listener());
|
||||
break;
|
||||
|
||||
case "CdiSpiDecorator+Listener":
|
||||
// Expect:INFO: WELD-ENV-001213: Jetty CDI SPI support detected, CDI injection will be available in Listeners, Servlets and Filters.
|
||||
context.getObjectFactory().addDecorator(new org.eclipse.jetty.cdi.CdiSpiDecorator(context));
|
||||
context.getServletHandler().addListener(new ListenerHolder(org.jboss.weld.environment.servlet.Listener.class));
|
||||
break;
|
||||
|
||||
case "CdiServletContainerInitializer+Listener":
|
||||
// Expect:INFO: WELD-ENV-001213: Jetty CDI SPI support detected, CDI injection will be available in Listeners, Servlets and Filters.
|
||||
context.addBean(new ServletContextHandler.Initializer(context, new org.eclipse.jetty.cdi.CdiServletContainerInitializer()));
|
||||
context.addEventListener(new org.jboss.weld.environment.servlet.Listener());
|
||||
break;
|
||||
|
||||
case "CdiServletContainerInitializer(CdiDecoratingListener)+Listener":
|
||||
// Expect:INFO: WELD-ENV-001212: Jetty CdiDecoratingListener support detected, CDI injection will be available in Listeners, Servlets and Filters
|
||||
context.setInitParameter(org.eclipse.jetty.cdi.CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE, org.eclipse.jetty.cdi.CdiDecoratingListener.MODE);
|
||||
context.addBean(new ServletContextHandler.Initializer(context, new org.eclipse.jetty.cdi.CdiServletContainerInitializer()));
|
||||
context.addEventListener(new org.jboss.weld.environment.servlet.Listener());
|
||||
break;
|
||||
|
||||
case "CdiServletContainerInitializer+EnhancedListener":
|
||||
// Expect:INFO: WELD-ENV-001213: Jetty CDI SPI support detected, CDI injection will be available in Listeners, Servlets and Filters.
|
||||
context.addBean(new ServletContextHandler.Initializer(context, new org.eclipse.jetty.cdi.CdiServletContainerInitializer()));
|
||||
context.addBean(new ServletContextHandler.Initializer(context, new org.jboss.weld.environment.servlet.EnhancedListener()));
|
||||
break;
|
||||
|
||||
case "CdiServletContainerInitializer(CdiDecoratingListener)+EnhancedListener":
|
||||
// Expect:INFO: WELD-ENV-001212: Jetty CdiDecoratingListener support detected, CDI injection will be available in Listeners, Servlets and Filters
|
||||
context.setInitParameter(org.eclipse.jetty.cdi.CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE, org.eclipse.jetty.cdi.CdiDecoratingListener.MODE);
|
||||
context.addBean(new ServletContextHandler.Initializer(context, new org.eclipse.jetty.cdi.CdiServletContainerInitializer()));
|
||||
context.addBean(new ServletContextHandler.Initializer(context, new org.jboss.weld.environment.servlet.EnhancedListener()));
|
||||
break;
|
||||
|
||||
case "EnhancedListener+CdiServletContainerInitializer(CdiDecoratingListener)":
|
||||
// Expect:INFO: WELD-ENV-001212: Jetty CdiDecoratingListener support detected, CDI injection will be available in Listeners, Servlets and Filters
|
||||
context.setInitParameter(org.eclipse.jetty.cdi.CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE, org.eclipse.jetty.cdi.CdiDecoratingListener.MODE);
|
||||
context.addBean(new ServletContextHandler.Initializer(context, new org.jboss.weld.environment.servlet.EnhancedListener()));
|
||||
context.addBean(new ServletContextHandler.Initializer(context, new org.eclipse.jetty.cdi.CdiServletContainerInitializer()));
|
||||
break;
|
||||
}
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
@ParameterizedTest()
|
||||
@ValueSource(strings =
|
||||
{
|
||||
"none",
|
||||
"DecoratingListener+Listener",
|
||||
"CdiDecoratingListener+Listener",
|
||||
"CdiSpiDecorator+Listener",
|
||||
"CdiServletContainerInitializer+Listener",
|
||||
"CdiServletContainerInitializer(CdiDecoratingListener)+Listener",
|
||||
"CdiServletContainerInitializer+EnhancedListener",
|
||||
"CdiServletContainerInitializer(CdiDecoratingListener)+EnhancedListener"
|
||||
})
|
||||
public void testServletContext(String mode) throws Exception
|
||||
{
|
||||
Server server = createServerWithServletContext(mode);
|
||||
server.start();
|
||||
LocalConnector connector = server.getBean(LocalConnector.class);
|
||||
String response = connector.getResponse("GET / HTTP/1.0\r\n\r\n");
|
||||
assertThat(response, containsString("HTTP/1.1 200 OK"));
|
||||
assertThat(response, containsString("Hello GreetingsServlet filtered by Weld BeanManager "));
|
||||
assertThat(response, containsString("Beans from Weld BeanManager "));
|
||||
if (mode.contains("EnhancedListener"))
|
||||
assertThat(response, containsString("Listener saw Weld BeanManager"));
|
||||
else
|
||||
assertThat(response, containsString("Listener saw null"));
|
||||
|
||||
assertThat(response, containsString("Beans from Weld BeanManager for "));
|
||||
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebappContext() throws Exception
|
||||
{
|
||||
Server server = new Server(8080);
|
||||
server.addConnector(new LocalConnector(server));
|
||||
WebAppContext webapp = new WebAppContext();
|
||||
webapp.setContextPath("/");
|
||||
webapp.setResourceBase("src/test/resources/weldtest");
|
||||
server.setHandler(webapp);
|
||||
|
||||
webapp.setInitParameter(org.eclipse.jetty.cdi.CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE, org.eclipse.jetty.cdi.CdiDecoratingListener.MODE);
|
||||
webapp.addBean(new ServletContextHandler.Initializer(webapp, new org.eclipse.jetty.cdi.CdiServletContainerInitializer()));
|
||||
webapp.addBean(new ServletContextHandler.Initializer(webapp, new org.jboss.weld.environment.servlet.EnhancedListener()));
|
||||
|
||||
webapp.getServerClasspathPattern().add("-org.eclipse.jetty.embedded.");
|
||||
webapp.getSystemClasspathPattern().add("org.eclipse.jetty.embedded.");
|
||||
|
||||
webapp.addServlet(GreetingsServlet.class, "/");
|
||||
webapp.addFilter(MyFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
webapp.getServletHandler().addListener(new ListenerHolder(MyContextListener.class));
|
||||
|
||||
server.start();
|
||||
|
||||
LocalConnector connector = server.getBean(LocalConnector.class);
|
||||
String response = connector.getResponse("GET / HTTP/1.0\r\n\r\n");
|
||||
assertThat(response, containsString("HTTP/1.1 200 OK"));
|
||||
assertThat(response, containsString("Hello GreetingsServlet filtered by Weld BeanManager "));
|
||||
assertThat(response, containsString("Beans from Weld BeanManager "));
|
||||
assertThat(response, containsString("Listener saw Weld BeanManager"));
|
||||
server.stop();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWebappContextDiscovered() throws Exception
|
||||
{
|
||||
Server server = new Server(8080);
|
||||
server.addConnector(new LocalConnector(server));
|
||||
WebAppContext webapp = new WebAppContext();
|
||||
webapp.setContextPath("/");
|
||||
webapp.setResourceBase("src/test/resources/weldtest");
|
||||
server.setHandler(webapp);
|
||||
|
||||
// Need the AnnotationConfiguration to detect SCIs
|
||||
Configuration.ClassList.setServerDefault(server).addBefore(JettyWebXmlConfiguration.class.getName(),
|
||||
AnnotationConfiguration.class.getName());
|
||||
|
||||
// Need to expose our SCI. This is ugly could be made better in jetty-10 with a CdiConfiguration
|
||||
webapp.getServerClasspathPattern().add("-" + CdiServletContainerInitializer.class.getName());
|
||||
webapp.getSystemClasspathPattern().add(CdiServletContainerInitializer.class.getName());
|
||||
|
||||
// This is ugly but needed for maven for testing in a overlaid war pom
|
||||
webapp.getServerClasspathPattern().add("-org.eclipse.jetty.embedded.");
|
||||
webapp.getSystemClasspathPattern().add("org.eclipse.jetty.embedded.");
|
||||
|
||||
webapp.getServletHandler().addListener(new ListenerHolder(MyContextListener.class));
|
||||
webapp.addFilter(MyFilter.class, "/*", EnumSet.of(DispatcherType.REQUEST));
|
||||
webapp.addServlet(GreetingsServlet.class, "/");
|
||||
|
||||
server.start();
|
||||
|
||||
LocalConnector connector = server.getBean(LocalConnector.class);
|
||||
String response = connector.getResponse("GET / HTTP/1.0\r\n\r\n");
|
||||
System.err.println(response);
|
||||
assertThat(response, containsString("HTTP/1.1 200 OK"));
|
||||
assertThat(response, containsString("Hello GreetingsServlet filtered by Weld BeanManager "));
|
||||
assertThat(response, containsString("Beans from Weld BeanManager "));
|
||||
assertThat(response, containsString("Listener saw Weld BeanManager"));
|
||||
server.stop();
|
||||
|
||||
}
|
||||
|
||||
public static class MyContextListener implements ServletContextListener
|
||||
{
|
||||
@Inject
|
||||
BeanManager manager;
|
||||
|
||||
@Override
|
||||
public void contextInitialized(ServletContextEvent sce)
|
||||
{
|
||||
sce.getServletContext().setAttribute("listener", manager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void contextDestroyed(ServletContextEvent sce)
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyFilter implements Filter
|
||||
{
|
||||
@Inject
|
||||
BeanManager manager;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig filterConfig) throws ServletException
|
||||
{
|
||||
if (manager == null)
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
|
||||
{
|
||||
// copy attribute from MyListener to see if it was decorated.
|
||||
request.setAttribute("filter", manager);
|
||||
chain.doFilter(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public static class GreetingsServlet extends HttpServlet
|
||||
{
|
||||
@Inject
|
||||
@Named("friendly")
|
||||
public Greetings greetings;
|
||||
|
||||
@Inject
|
||||
BeanManager manager;
|
||||
|
||||
@Override
|
||||
public void init()
|
||||
{
|
||||
if (manager == null)
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
|
||||
{
|
||||
resp.setContentType("text/plain");
|
||||
resp.getWriter().print(greetings == null ? "NULL" : greetings.getGreeting());
|
||||
resp.getWriter().print(" filtered by ");
|
||||
resp.getWriter().println(req.getAttribute("filter"));
|
||||
resp.getWriter().println("Beans from " + manager);
|
||||
resp.getWriter().println("Listener saw " + req.getServletContext().getAttribute("listener"));
|
||||
}
|
||||
}
|
||||
|
||||
public interface Greetings
|
||||
{
|
||||
String getGreeting();
|
||||
}
|
||||
|
||||
public static class FriendlyGreetings
|
||||
{
|
||||
@Produces
|
||||
@Named("friendly")
|
||||
public Greetings friendly(InjectionPoint ip)
|
||||
{
|
||||
return () -> "Hello " + ip.getMember().getDeclaringClass().getSimpleName();
|
||||
}
|
||||
|
||||
@Produces
|
||||
@Named("old")
|
||||
public Greetings old()
|
||||
{
|
||||
return () -> "Salutations!";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
|
||||
http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all">
|
||||
</beans>
|
|
@ -0,0 +1,119 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
|
||||
// ========================================================================
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
[[framework-cdi]]
|
||||
=== CDI
|
||||
|
||||
Contexts and Dependency Injection for Java EE (http://www.cdi-spec.org/[CDI]) is a standard implemented by frameworks such as http://seamframework.org/Weld[Weld] and https://openwebbeans.apache.org/[Apache OpenWebBeans].
|
||||
This is a common way to assemble and configure webapplications by a process often referred to as 'decoration'.
|
||||
|
||||
Jetty integration of CDI frameworks allows CDI to be used to inject the Filters, Servlets and Listeners created within a Servlet Context.
|
||||
There are two approaches to integration:
|
||||
|
||||
* CDI implementation can integrate with Jetty.
|
||||
This requires the CDI implementation to have Jetty specific code.
|
||||
Since Jetty-9.4.20 a loosely bound mechanism has been available for CDI implementations to extends the Jetty `DecoratedObjectFactory` without hard API dependencies.
|
||||
Prior to that, CDI implementations directly called jetty APIs that need to be explicitly exposed to the webapp.
|
||||
|
||||
* Alternately, Jetty can integrate with CDI implementations by using standard CDI SPIs.
|
||||
|
||||
==== Jetty CDI Modules
|
||||
|
||||
The Jetty distribution come with several CDI modules.
|
||||
These modules do not provide CDI, but instead enable one of more integration mechanisms.
|
||||
|
||||
===== Jetty `cdi` Module
|
||||
The `cdi` module supports either two modes of CDI integration which can be selected either by the "org.eclipse.jetty.cdi" context init parameter or the "org.eclipse.jetty.cdi" server attribute (which is initialised from the "jetty.cdi.mode" start property).
|
||||
Supported modes are:
|
||||
|
||||
* `CdiSpiDecorator` Jetty will call the CDI SPI within the webapp to decorate objects (default).
|
||||
|
||||
* `CdiDecoratingLister` The webapp may register a decorator on the context attribute "org.eclipse.jetty.cdi.decorator".
|
||||
-------------------------
|
||||
cd $JETTY_BASE
|
||||
java -jar $JETTY_HOME/start.jar --add-to-start=cdi
|
||||
-------------------------
|
||||
|
||||
===== Jetty `cdi-decorate` Module
|
||||
This module depends on the `cdi` module and sets the default mode to `CdiDecoratingListener`.
|
||||
This is the preferred mode for Weld integration.
|
||||
-------------------------
|
||||
cd $JETTY_BASE
|
||||
java -jar $JETTY_HOME/start.jar --add-to-start=cdi-decorate
|
||||
-------------------------
|
||||
|
||||
===== Jetty `cdi-spi` Module
|
||||
This module depends on the `cdi` module and sets the default mode to `CdiSpiDecorator`.
|
||||
This is the preferred mode for Open Web Beans integration.
|
||||
-------------------------
|
||||
cd $JETTY_BASE
|
||||
java -jar $JETTY_HOME/start.jar --add-to-start=cdi-spi
|
||||
-------------------------
|
||||
|
||||
===== Jetty `cdi2` Module
|
||||
This module supports the *deprecated* technique of exposing private Jetty decorate APIs to the CDI implementation in the webapp.
|
||||
|
||||
-------------------------
|
||||
cd $JETTY_BASE
|
||||
java -jar $JETTY_HOME/start.jar --add-to-start=cdi2
|
||||
-------------------------
|
||||
|
||||
This module is equivalent to directly modifying the class path configuration with a `jetty-web.xml` like:
|
||||
|
||||
[source.XML, xml]
|
||||
-------------------------------------------------------------
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.util.Decorator</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.util.DecoratedObjectFactory</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.server.handler.ContextHandler.</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.server.handler.ContextHandler</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.servlet.ServletContextHandler</Arg>
|
||||
</Call>
|
||||
</Configure>
|
||||
-------------------------------------------------------------
|
||||
|
||||
____
|
||||
[TIP]
|
||||
The `cdi2` module or directly modifying the web application classpath will not work for Jetty 10.0.0 and later.
|
||||
It should only be used for versions prior to Jetty 9.4.20 and/or Weld 3.1.2.Final
|
||||
____
|
||||
|
||||
|
||||
[[cdi-embedded]]
|
||||
==== Embedded Jetty with CDI
|
||||
When starting embedded Jetty programmatically from the `main` method, to use CDI it may be
|
||||
necessary:
|
||||
|
||||
* enable a Jetty CDI integration mode
|
||||
|
||||
* and/or enable a CDI frame integration.
|
||||
|
||||
However, depending on the exact configuration of the embedded server, either or both steps may not be required as `ServletContainerInitializer`s may be discovered.
|
||||
|
||||
The details for embedding CDI is explained in the link:#weld-embedded[Embedded Jetty with Weld] section, which can also be adapted to other CDI frameworks.
|
|
@ -19,7 +19,8 @@
|
|||
[[frameworks]]
|
||||
== Frameworks
|
||||
|
||||
include::cdi.adoc[]
|
||||
include::weld.adoc[]
|
||||
include::spring-usage.adoc[]
|
||||
include::osgi.adoc[]
|
||||
include::weld.adoc[]
|
||||
include::metro.adoc[]
|
||||
|
|
|
@ -26,124 +26,64 @@ It is easily configured with Jetty 9.
|
|||
==== Weld Setup
|
||||
|
||||
The easiest way to configure weld is within the Jetty distribution itself.
|
||||
This can be accomplished either by enabling one of the startup link:#startup-modules[modules] for Weld, or by creating/editing a `jetty-web.xml` descriptor (see also https://www.eclipse.org/jetty/documentation/current/jetty-web-xml-config.html[Jetty XML Reference]).
|
||||
This can be accomplished either by enabling one of the startup link:#startup-modules[modules] described in link:#framework-cdi[CDI Framework]:
|
||||
|
||||
===== Jetty Weld Modules
|
||||
|
||||
====== Jetty `cdi-decorate` Module
|
||||
|
||||
Since Jetty 9.4.20 and Weld 3.1.2.Final, the Weld/Jetty integration uses the jetty `cdi-decorate` module.
|
||||
To activate this module in Jetty the `cdi-decorate` module needs activated on the command line, which can be done as follows:
|
||||
* the `cdi-decorate` module is the preferred Weld integration.
|
||||
The activation of this module by Weld can be confirmed by the following Weld log:
|
||||
[source, screen, subs="{sub-order}"]
|
||||
....
|
||||
INFO: WELD-ENV-001212: Jetty CdiDecoratingListener support detected, CDI injection will be available in Listeners, Servlets and Filters.
|
||||
....
|
||||
* the `cdi-spi` module works with Weld, but may restrict some non standard features.
|
||||
The activation of this module by Weld can be confirmed by the following Weld log:
|
||||
[source, screen, subs="{sub-order}"]
|
||||
....
|
||||
INFO: WELD-ENV-001213: Jetty CDI SPI support detected, CDI injection will be available in Listeners, Servlets and Filters.
|
||||
....
|
||||
* the deprecated `cdi2` module works with Weld prior to 3.1.2.Final.
|
||||
The activation of this module by Weld can be confirmed by the following Weld log:
|
||||
[source, screen, subs="{sub-order}"]
|
||||
....
|
||||
INFO: WELD-ENV-001201: Jetty 7.2+ detected, CDI injection will be available in Servlets and Filters. Injection into Listeners is not supported.
|
||||
....
|
||||
|
||||
To activate the preferred `cdi-decorate` module use:
|
||||
-------------------------
|
||||
cd $JETTY_BASE
|
||||
java -jar $JETTY_HOME/start.jar --add-to-start=cdi-decorate
|
||||
-------------------------
|
||||
|
||||
====== Jetty `cdi2` Module
|
||||
|
||||
For versions prior to Jetty 9.4.20 and Weld 3.1.2, the Weld/Jetty integration required some internal Jetty APIs to be made visible to the web application.
|
||||
This can be done using the deprecated `cdi2` module either by activating the `cdi2` module:
|
||||
|
||||
-------------------------
|
||||
cd $JETTY_BASE
|
||||
java -jar $JETTY_HOME/start.jar --add-to-start=cdi2
|
||||
-------------------------
|
||||
|
||||
|
||||
===== Jetty-Web XML
|
||||
|
||||
|
||||
[source.XML, xml]
|
||||
-------------------------------------------------------------
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.util.Decorator</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.util.DecoratedObjectFactory</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.server.handler.ContextHandler.</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.server.handler.ContextHandler</Arg>
|
||||
</Call>
|
||||
<Call name="prependServerClass">
|
||||
<Arg>-org.eclipse.jetty.servlet.ServletContextHandler</Arg>
|
||||
</Call>
|
||||
</Configure>
|
||||
-------------------------------------------------------------
|
||||
|
||||
____
|
||||
[TIP]
|
||||
Directly modifying the web application classpath via `jetty-web.xml` will not work for Jetty 10.0.0 and later.
|
||||
For use with the jetty-maven-plugin, the best idea is to make the org.jboss.weld.servlet:weld-servlet and jetty-cdi artifacts _plugin_ dependencies (__not__ a webapp dependency).
|
||||
____
|
||||
|
||||
===== Jetty `cdi-spi` Module
|
||||
Since Jetty 9.4.20 the Jetty `cdi-spi` module has been available that integrates any compliant CDI implementation by directly calling the CDI SPI.
|
||||
Since Weld support specific Jetty integration, it is not recommended to use this module with Weld.
|
||||
|
||||
When you start up your Jetty distribution with the webapp you should see output similar to the following (providing your logging is the default configuration):
|
||||
|
||||
[source, screen, subs="{sub-order}"]
|
||||
....
|
||||
2015-06-18 12:13:54.924:INFO::main: Logging initialized @485ms
|
||||
2015-06-18 12:13:55.231:INFO:oejs.Server:main: jetty-{VERSION}
|
||||
2015-06-18 12:13:55.264:INFO:oejdp.ScanningAppProvider:main: Deployment monitor [file:///tmp/cdi-demo/webapps/] at interval 1
|
||||
2015-06-18 12:13:55.607:WARN:oeja.AnnotationConfiguration:main: ServletContainerInitializers: detected. Class hierarchy: empty
|
||||
Jun 18, 2015 12:13:55 PM org.jboss.weld.environment.servlet.EnhancedListener onStartup
|
||||
INFO: WELD-ENV-001008: Initialize Weld using ServletContainerInitializer
|
||||
Jun 18, 2015 12:13:55 PM org.jboss.weld.bootstrap.WeldStartup <clinit>
|
||||
INFO: WELD-000900: 2.2.9 (Final)
|
||||
Jun 18, 2015 12:13:55 PM org.jboss.weld.environment.servlet.deployment.WebAppBeanArchiveScanner scan
|
||||
WARN: WELD-ENV-001004: Found both WEB-INF/beans.xml and WEB-INF/classes/META-INF/beans.xml. It's not portable to use both locations at the same time. Weld is going to use file:/tmp/jetty-0.0.0.0-8080-cdi-webapp.war-_cdi-webapp-any-8161614308407422636.dir/webapp/WEB-INF/beans.xml.
|
||||
Jun 18, 2015 12:13:55 PM org.jboss.weld.bootstrap.WeldStartup startContainer
|
||||
INFO: WELD-000101: Transactional services not available. Injection of @Inject UserTransaction not available. Transactional observers will be invoked synchronously.
|
||||
Jun 18, 2015 12:13:55 PM org.jboss.weld.interceptor.util.InterceptionTypeRegistry <clinit>
|
||||
WARN: WELD-001700: Interceptor annotation class javax.ejb.PostActivate not found, interception based on it is not enabled
|
||||
Jun 18, 2015 12:13:55 PM org.jboss.weld.interceptor.util.InterceptionTypeRegistry <clinit>
|
||||
WARN: WELD-001700: Interceptor annotation class javax.ejb.PrePassivate not found, interception based on it is not enabled
|
||||
Jun 18, 2015 12:13:56 PM org.jboss.weld.bootstrap.MissingDependenciesRegistry handleResourceLoadingException
|
||||
Jun 18, 2015 12:13:56 PM org.jboss.weld.environment.servlet.WeldServletLifecycle findContainer
|
||||
INFO: WELD-ENV-001002: Container detection skipped - custom container class loaded: org.jboss.weld.environment.jetty.JettyContainer.
|
||||
Jun 18, 2015 12:13:56 PM org.jboss.weld.environment.jetty.JettyContainer initialize
|
||||
INFO: WELD-ENV-001200: Jetty 7.2+ detected, CDI injection will be available in Servlets and Filters. Injection into Listeners should work on Jetty 9.1.1 and newer.
|
||||
Jun 18, 2015 12:13:56 PM org.jboss.weld.environment.servlet.Listener contextInitialized
|
||||
INFO: WELD-ENV-001006: org.jboss.weld.environment.servlet.EnhancedListener used for ServletContext notifications
|
||||
Jun 18, 2015 12:13:56 PM org.jboss.weld.environment.servlet.EnhancedListener contextInitialized
|
||||
INFO: WELD-ENV-001009: org.jboss.weld.environment.servlet.Listener used for ServletRequest and HttpSession notifications
|
||||
2015-06-18 12:13:56.535:INFO:oejsh.ContextHandler:main: Started o.e.j.w.WebAppContext@6574b225{/cdi-webapp,file:///tmp/jetty-0.0.0.0-8080-cdi-webapp.war-_cdi-webapp-any-8161614308407422636.dir/webapp/,AVAILABLE}{/cdi-webapp.war}
|
||||
2015-06-18 12:13:56.554:INFO:oejs.ServerConnector:main: Started ServerConnector@7112f81c{HTTP/1.1,[http/1.1]}{0.0.0.0:8080}
|
||||
2015-06-18 12:13:56.587:INFO:oejus.SslContextFactory:main: x509={jetty.eclipse.org=jetty} wild={} alias=null for SslContextFactory@3214ee6(file:///tmp/cdi-demo/etc/keystore,file:///tmp/cdi-demo/etc/keystore)
|
||||
2015-06-18 12:13:56.821:INFO:oejs.ServerConnector:main: Started ServerConnector@69176a9b{SSL,[ssl, http/1.1]}{0.0.0.0:8443}
|
||||
2015-06-18 12:13:56.822:INFO:oejs.Server:main: Started @2383ms
|
||||
|
||||
....
|
||||
|
||||
For use with the jetty-maven-plugin, the best idea is to make the org.jboss.weld.servlet:weld-servlet artifact a _plugin_ dependency (__not__ a webapp dependency).
|
||||
|
||||
[[weld-embedded]]
|
||||
==== Embedded Jetty
|
||||
==== Weld with Embedded Jetty
|
||||
|
||||
When starting embedded Jetty programmatically from the `main` method it is necessary to register Weld's listener:
|
||||
When starting embedded Jetty programmatically from the `main` method it is necessary to:
|
||||
|
||||
* enable a jetty CDI integration mode by registering a `Listener` or `ServletContainerInitializer`
|
||||
|
||||
* enable Weld by registering either its `Listener` or `ServletContainerInitializer`
|
||||
|
||||
===== Using a `ServletContextHandler`
|
||||
|
||||
Embedded usage often uses a `ServletContextHandler` which is the base class of `WebappContext` and lacks the features of "web.xml" configuration and must be configured directly.
|
||||
The examples in this section based on a server and context set up as follows:
|
||||
|
||||
[source.JAVA, java]
|
||||
----
|
||||
public class Main {
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Server jetty = new Server(8080);
|
||||
WebAppContext context = new WebAppContext();
|
||||
ServletContextHandler context = new ServletContextHandler();
|
||||
context.setContextPath("/");
|
||||
context.setResourceBase("src/main/resources");
|
||||
jetty.setHandler(context);
|
||||
server.setHandler(context);
|
||||
|
||||
context.addServlet(HelloWorldServlet.class, "/*");
|
||||
|
||||
context.addEventListener(new DecoratingListener()); # <1>
|
||||
context.addEventListener(new Listener()); # <2>
|
||||
/* CDI enabling goes here. See options below */
|
||||
|
||||
jetty.start();
|
||||
jetty.join();
|
||||
|
@ -159,7 +99,102 @@ public class Main {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
<1> Jetty's `org.eclipse.jetty.webapp.DecoratingListener` registered programmatically (since Jetty-9.4.20)
|
||||
<2> Weld's `org.jboss.weld.environment.servlet.Listener` registered programmatically
|
||||
----
|
||||
|
||||
====== Initialize Weld with `ServletContainerInitializers`
|
||||
The best way to initialize both Jetty Weld integration is to use their respective `ServletContainerInitializers`:
|
||||
[source.JAVA, java]
|
||||
----
|
||||
import org.eclipse.jetty.cdi.CdiServletContainerInitializer;
|
||||
import org.eclipse.jetty.cdi.CdiDecoratingListener;
|
||||
import org.jboss.weld.environment.servlet.EnhancedListener;
|
||||
// ...
|
||||
context.setInitParameter(
|
||||
CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE,
|
||||
CdiDecoratingListener.MODE);
|
||||
context.addBean(new ServletContextHandler.Initializer(context,
|
||||
new EnhancedListener()));
|
||||
context.addBean(new ServletContextHandler.Initializer(context,
|
||||
new CdiServletContainerInitializer()));
|
||||
----
|
||||
This code uses the `ServletContextHandler.Initializer` utility class added in Jetty-9.4.30.
|
||||
Prior to that the same effect can be achieved with a custom implementation of `ServletContextHandler.ServletContainerInitializerCaller`.
|
||||
|
||||
====== Initialize Weld with Listeners
|
||||
Jetty Weld integration can also be initialized by directly adding the listeners required:
|
||||
[source.JAVA, java]
|
||||
----
|
||||
import org.eclipse.jetty.cdi.CdiDecoratingListener;
|
||||
import org.jboss.weld.environment.servlet.Listener;
|
||||
// ...
|
||||
context.addEventListener(new CdiDecoratingListener(context));
|
||||
context.addEventListener(new Listener());
|
||||
----
|
||||
|
||||
====== Other Weld initializations
|
||||
When running embedded without a context classloader, it is not actually required to initialize Jetty at all.
|
||||
If just Weld is initialized then it will disover the Jetty APIs and use the deprecated integration:
|
||||
[source.JAVA, java]
|
||||
----
|
||||
import org.jboss.weld.environment.servlet.Listener;
|
||||
// ...
|
||||
context.addEventListener(new Listener());
|
||||
----
|
||||
However, this results in only a partially functional integration and the following warning:
|
||||
----
|
||||
INFO: WELD-ENV-001201: Jetty 7.2+ detected, CDI injection will be available in Servlets and Filters. Injection into Listeners is not supported.
|
||||
----
|
||||
|
||||
Jetty can also be initialized by adding the `org.eclipse.jetty.webapp.DecoratingListener` listener instead of the `org.eclipse.jetty.cdi.CdiDecoratingListener`.
|
||||
However, this introduces a needless dependency on `jetty-webapp` and is not the preferred method.
|
||||
|
||||
====== Initialize Weld with `WebappContext`
|
||||
Some embedded usage still makes use of the `WebappContext` class for the convention-over-configuration benefits.
|
||||
The methods described for `ServletContextHandler` will work for `WebappContext`:
|
||||
|
||||
[source.JAVA, java]
|
||||
----
|
||||
import org.eclipse.jetty.cdi.CdiServletContainerInitializer;
|
||||
import org.eclipse.jetty.cdi.CdiDecoratingListener;
|
||||
import org.jboss.weld.environment.servlet.EnhancedListener;
|
||||
// ...
|
||||
Server server = new Server(8080);
|
||||
WebAppContext webapp = new WebAppContext();
|
||||
webapp.setContextPath("/");
|
||||
server.setHandler(webapp);
|
||||
|
||||
webapp.setInitParameter(
|
||||
CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE,
|
||||
CdiDecoratingListener.MODE);
|
||||
webapp.addBean(new ServletContextHandler.Initializer(webapp,
|
||||
new CdiServletContainerInitializer()));
|
||||
webapp.addBean(new ServletContextHandler.Initializer(webapp,
|
||||
new EnhancedListener()));
|
||||
|
||||
// ...
|
||||
----
|
||||
|
||||
Alternately the webapp can be configured to discover the SCIs:
|
||||
|
||||
[source.JAVA, java]
|
||||
----
|
||||
Server server = new Server(8080);
|
||||
WebAppContext webapp = new WebAppContext();
|
||||
webapp.setContextPath("/");
|
||||
server.setHandler(webapp);
|
||||
|
||||
webapp.setInitParameter(
|
||||
CdiServletContainerInitializer.CDI_INTEGRATION_ATTRIBUTE,
|
||||
CdiDecoratingListener.MODE);
|
||||
|
||||
// Need the AnnotationConfiguration to detect SCIs
|
||||
Configuration.ClassList.setServerDefault(server).addBefore(
|
||||
JettyWebXmlConfiguration.class.getName(),
|
||||
AnnotationConfiguration.class.getName());
|
||||
|
||||
// Need to expose our SCI class.
|
||||
webapp.getServerClasspathPattern().add("-" + CdiServletContainerInitializer.class.getName());
|
||||
webapp.getSystemClasspathPattern().add(CdiServletContainerInitializer.class.getName());
|
||||
|
||||
// ...
|
||||
----
|
|
@ -124,9 +124,6 @@ public class ContainerInitializer
|
|||
{
|
||||
Set<Class<?>> classes = new HashSet<Class<?>>();
|
||||
|
||||
ClassLoader oldLoader = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(context.getClassLoader());
|
||||
|
||||
try
|
||||
{
|
||||
for (String s : _applicableTypeNames)
|
||||
|
@ -147,7 +144,6 @@ public class ContainerInitializer
|
|||
finally
|
||||
{
|
||||
context.getServletContext().setExtendedListenerTypes(false);
|
||||
Thread.currentThread().setContextClassLoader(oldLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,6 +34,7 @@ import javax.servlet.Filter;
|
|||
import javax.servlet.FilterRegistration;
|
||||
import javax.servlet.RequestDispatcher;
|
||||
import javax.servlet.Servlet;
|
||||
import javax.servlet.ServletContainerInitializer;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletContextEvent;
|
||||
import javax.servlet.ServletContextListener;
|
||||
|
@ -68,6 +69,7 @@ import org.eclipse.jetty.util.DeprecationWarning;
|
|||
import org.eclipse.jetty.util.StringUtil;
|
||||
import org.eclipse.jetty.util.annotation.ManagedAttribute;
|
||||
import org.eclipse.jetty.util.annotation.ManagedObject;
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
@ -336,9 +338,15 @@ public class ServletContextHandler extends ContextHandler
|
|||
@Override
|
||||
protected void startContext() throws Exception
|
||||
{
|
||||
ServletContainerInitializerCaller sciBean = getBean(ServletContainerInitializerCaller.class);
|
||||
if (sciBean != null)
|
||||
sciBean.start();
|
||||
for (ServletContainerInitializerCaller sci : getBeans(ServletContainerInitializerCaller.class))
|
||||
{
|
||||
if (sci.isStopped())
|
||||
{
|
||||
sci.start();
|
||||
if (isAuto(sci))
|
||||
manage(sci);
|
||||
}
|
||||
}
|
||||
|
||||
if (_servletHandler != null)
|
||||
{
|
||||
|
@ -749,13 +757,13 @@ public class ServletContextHandler extends ContextHandler
|
|||
|
||||
public static class JspPropertyGroup implements JspPropertyGroupDescriptor
|
||||
{
|
||||
private List<String> _urlPatterns = new ArrayList<>();
|
||||
private final List<String> _urlPatterns = new ArrayList<>();
|
||||
private String _elIgnored;
|
||||
private String _pageEncoding;
|
||||
private String _scriptingInvalid;
|
||||
private String _isXml;
|
||||
private List<String> _includePreludes = new ArrayList<>();
|
||||
private List<String> _includeCodas = new ArrayList<>();
|
||||
private final List<String> _includePreludes = new ArrayList<>();
|
||||
private final List<String> _includeCodas = new ArrayList<>();
|
||||
private String _deferredSyntaxAllowedAsLiteral;
|
||||
private String _trimDirectiveWhitespaces;
|
||||
private String _defaultContentType;
|
||||
|
@ -1001,8 +1009,8 @@ public class ServletContextHandler extends ContextHandler
|
|||
|
||||
public static class JspConfig implements JspConfigDescriptor
|
||||
{
|
||||
private List<TaglibDescriptor> _taglibs = new ArrayList<>();
|
||||
private List<JspPropertyGroupDescriptor> _jspPropertyGroups = new ArrayList<>();
|
||||
private final List<TaglibDescriptor> _taglibs = new ArrayList<>();
|
||||
private final List<JspPropertyGroupDescriptor> _jspPropertyGroups = new ArrayList<>();
|
||||
|
||||
public JspConfig()
|
||||
{
|
||||
|
@ -1474,7 +1482,7 @@ public class ServletContextHandler extends ContextHandler
|
|||
*/
|
||||
private static class LegacyDecorator implements Decorator
|
||||
{
|
||||
private org.eclipse.jetty.util.Decorator decorator;
|
||||
private final org.eclipse.jetty.util.Decorator decorator;
|
||||
|
||||
public LegacyDecorator(org.eclipse.jetty.util.Decorator decorator)
|
||||
{
|
||||
|
@ -1493,4 +1501,43 @@ public class ServletContextHandler extends ContextHandler
|
|||
decorator.destroy(o);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A utility class to hold a {@link ServletContainerInitializer} and implement the
|
||||
* {@link ServletContainerInitializerCaller} interface so that the SCI is correctly
|
||||
* started if an instance of this class is added as a bean to a {@link ServletContextHandler}.
|
||||
*/
|
||||
public static class Initializer extends AbstractLifeCycle implements ServletContainerInitializerCaller
|
||||
{
|
||||
private final ServletContextHandler _context;
|
||||
private final ServletContainerInitializer _sci;
|
||||
private final Set<Class<?>> _classes;
|
||||
|
||||
public Initializer(ServletContextHandler context, ServletContainerInitializer sci, Set<Class<?>> classes)
|
||||
{
|
||||
_context = context;
|
||||
_sci = sci;
|
||||
_classes = classes;
|
||||
}
|
||||
|
||||
public Initializer(ServletContextHandler context, ServletContainerInitializer sci)
|
||||
{
|
||||
this(context, sci, Collections.emptySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
boolean oldExtended = _context.getServletContext().isExtendedListenerTypes();
|
||||
try
|
||||
{
|
||||
_context.getServletContext().setExtendedListenerTypes(true);
|
||||
_sci.onStartup(_classes, _context.getServletContext());
|
||||
}
|
||||
finally
|
||||
{
|
||||
_context.getServletContext().setExtendedListenerTypes(oldExtended);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,6 @@ import java.util.Collection;
|
|||
*/
|
||||
public interface Container
|
||||
{
|
||||
|
||||
/**
|
||||
* Add a bean. If the bean is-a {@link Listener}, then also do an implicit {@link #addEventListener(Listener)}.
|
||||
*
|
||||
|
@ -35,7 +34,7 @@ public interface Container
|
|||
boolean addBean(Object o);
|
||||
|
||||
/**
|
||||
* @return the list of beans known to this aggregate
|
||||
* @return the collection of beans known to this aggregate, in the order they were added.
|
||||
* @see #getBean(Class)
|
||||
*/
|
||||
Collection<Object> getBeans();
|
||||
|
@ -43,7 +42,7 @@ public interface Container
|
|||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @param <T> the Bean type
|
||||
* @return a list of beans of the given class (or subclass)
|
||||
* @return a list of beans of the given class (or subclass), in the order they were added.
|
||||
* @see #getBeans()
|
||||
* @see #getContainedBeans(Class)
|
||||
*/
|
||||
|
@ -52,7 +51,7 @@ public interface Container
|
|||
/**
|
||||
* @param clazz the class of the bean
|
||||
* @param <T> the Bean type
|
||||
* @return the first bean of a specific class (or subclass), or null if no such bean exist
|
||||
* @return the first bean (in order added) of a specific class (or subclass), or null if no such bean exist
|
||||
*/
|
||||
<T> T getBean(Class<T> clazz);
|
||||
|
||||
|
@ -138,7 +137,8 @@ public interface Container
|
|||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @param <T> the Bean type
|
||||
* @return the list of beans of the given class from the entire Container hierarchy
|
||||
* @return the list of beans of the given class from the entire Container hierarchy. The order is primarily depth first
|
||||
* and secondarily added order.
|
||||
*/
|
||||
<T> Collection<T> getContainedBeans(Class<T> clazz);
|
||||
}
|
||||
|
|
|
@ -915,11 +915,6 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @param <T> the Bean type
|
||||
* @return the list of beans of the given class from the entire Container hierarchy
|
||||
*/
|
||||
@Override
|
||||
public <T> Collection<T> getContainedBeans(Class<T> clazz)
|
||||
{
|
||||
|
@ -928,11 +923,6 @@ public class ContainerLifeCycle extends AbstractLifeCycle implements Container,
|
|||
return beans;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clazz the class of the beans
|
||||
* @param <T> the Bean type
|
||||
* @param beans the collection to add beans of the given class from the entire Container hierarchy
|
||||
*/
|
||||
protected <T> void getContainedBeans(Class<T> clazz, Collection<T> beans)
|
||||
{
|
||||
beans.addAll(getBeans(clazz));
|
||||
|
|
|
@ -61,7 +61,7 @@ public class CDITests extends AbstractDistributionTest
|
|||
Arguments.of("weld", "cdi2", null),
|
||||
Arguments.of("weld", "cdi-spi", null), // Weld >= 3.1.2
|
||||
Arguments.of("weld", "decorate", null), // Weld >= 3.1.2
|
||||
// TODO Arguments.of("weld", "cdi-decorate", null), // Weld >= 3.1.3
|
||||
Arguments.of("weld", "cdi-decorate", null), // Weld >= 3.1.3
|
||||
|
||||
// -- Apache OpenWebBeans --
|
||||
Arguments.of("owb", "cdi-spi", null),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<beans xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="
|
||||
http://xmlns.jcp.org/xml/ns/javaee
|
||||
http://xmlns.jcp.org/xml/ns/javaee/beans_1_1.xsd" bean-discovery-mode="all">
|
||||
</beans>
|
||||
</beans>
|
||||
|
|
Loading…
Reference in New Issue