Thanks for the reply, now I know I have more work to do.
On Thu, Feb 6, 2014 at 12:33 AM, Stuart Douglas <sdouglas(a)redhat.com> wrote:
------------------------------
*From: *"Mondain" <mondain(a)gmail.com>
*To: *undertow-dev(a)lists.jboss.org
*Sent: *Thursday, 6 February, 2014 9:36:34 AM
*Subject: *[undertow-dev] Embedding undertow into Red5
I'm a core dev on the Red5 project and I would like to offer undertow as
an alternative to our current embedded tomcat server. I have read through
the examples, unit tests, and documentation regarding undertow. I have
coded and run my "plugin" implementation, but all I am getting are "Not
Found" responses in the browser. My suspicion is that the web.xml is not
being read in and / or parsed, but I'm not sure since I'm new with this
code base. Below you will see how I'm setting up and starting things; let
me know what I'm doing incorrectly.
Hi Mondain,
You are correct in your suspicion that Undertow is not parsing the
web.xml. Undertow provides an embedded Servlet implementation but it does
not implement the discovery/parsing parts, as this is left up to the
embedding application.
Basically instead of using web.xml you need to add servlets, filters etc
to the DeploymentInfo structure programatically. The main reason for this
is basically because Undertow is designed to integrate well into other
applications (especially Wildfly), and application servers generally
provide their own implementation of parsers, annotation processors etc.
With that said though at some point we will probably do a standalone
parser/annotation processor to make this work out of the box (probably by
just copying the relevant bits from wildfly and packaging them in their own
jar). This is a fairly low priority item at the moment though.
Stuart
//get a reference to the current threads classloader
final ClassLoader originalClassLoader =
Thread.currentThread().getContextClassLoader();
// root location for servlet container
String serverRoot = System.getProperty("red5.root");
String confRoot = System.getProperty("red5.config_root");
System.setProperty("UNDERTOW_HOME", serverRoot);
if (webappFolder == null) {
// Use default webapps directory
webappFolder = FileUtil.formatPath(System.getProperty("red5.root"),
"/webapps");
}
System.setProperty("red5.webapp.root", webappFolder);
// scan the sub directories to determine our context paths
buildContextPathList(webappFolder);
try {
// create our servlet container
container = ServletContainer.Factory.newInstance();
// create a root path handler
final PathHandler rootHandler = new PathHandler();
// create one server and use it everywhere
Undertow.Builder builder = Undertow.builder();
// loop through connectors adding listeners to the builder
for (UndertowConnector undertowConnector : connectors) {
InetSocketAddress addr = undertowConnector.getSocketAddress();
builder.addListener(addr.getPort(), addr.getHostName(),
(undertowConnector.isSecure() ? ListenerType.HTTPS : ListenerType.HTTP));
}
// loop the other contexts
for (String contextPath : contextPaths) {
// create a class loader for the context
ClassLoader classLoader = buildWebClassLoader(originalClassLoader,
webappFolder, contextPath);
// create deployment info
DeploymentInfo info = deployment()
.setClassLoader(classLoader)
.setContextPath(contextPath.equalsIgnoreCase("/ROOT") ?
"/" : contextPath)
.setDefaultEncoding("UTF-8")
.setDeploymentName(contextPath.substring(1) + ".war")
.setUrlEncoding("UTF-8");
// add the new deployment to the servlet container
DeploymentManager manager = container.addDeployment(info);
// deploy
manager.deploy();
// add path
rootHandler.addPrefixPath(info.getContextPath(),
manager.start());
// get deployment
Deployment deployment = manager.getDeployment();
// get servlet context
final ServletContext servletContext = deployment.getServletContext();
log.debug("Context initialized: {}", servletContext.getContextPath());
try {
log.debug("Context: {}", servletContext);
final ClassLoader webClassLoader = info.getClassLoader();
log.debug("Webapp classloader: {}", webClassLoader);
// get the (spring) config file path
final String contextConfigLocation =
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONFIG_LOCATION_PARAM)
== null ? defaultSpringConfigLocation
:
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONFIG_LOCATION_PARAM);
log.debug("Spring context config location: {}", contextConfigLocation);
// get the (spring) parent context key
final String parentContextKey =
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.LOCATOR_FACTORY_KEY_PARAM)
== null ? defaultParentContextKey
:
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.LOCATOR_FACTORY_KEY_PARAM);
// set current threads classloader to the webapp classloader
Thread.currentThread().setContextClassLoader(webClassLoader);
// create a thread to speed-up application loading
Thread thread = new Thread("Launcher:" +
servletContext.getContextPath()) {
public void run() {
//set thread context classloader to web classloader
Thread.currentThread().setContextClassLoader(webClassLoader);
//get the web app's parent context
ApplicationContext parentContext = null;
if (applicationContext.containsBean(parentContextKey)) {
parentContext = (ApplicationContext)
applicationContext.getBean(parentContextKey);
} else {
log.warn("Parent context was not found: {}", parentContextKey);
}
// create a spring web application context
final String contextClass =
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONTEXT_CLASS_PARAM)
== null ? XmlWebApplicationContext.class
.getName() :
servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONTEXT_CLASS_PARAM);
// web app context (spring)
ConfigurableWebApplicationContext appctx = null;
try {
Class<?> clazz = Class.forName(contextClass, true, webClassLoader);
appctx = (ConfigurableWebApplicationContext) clazz.newInstance();
// set the root webapp ctx attr on the each servlet context so spring can
find it later
servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,
appctx);
appctx.setConfigLocations(new String[] { contextConfigLocation });
appctx.setServletContext(servletContext);
// set parent context or use current app context
if (parentContext != null) {
appctx.setParent(parentContext);
} else {
appctx.setParent(applicationContext);
}
// refresh the factory
appctx.refresh();
appctx.start();
} catch (Throwable e) {
throw new RuntimeException("Failed to load webapplication context class",
e);
}
}
};
thread.setDaemon(true);
thread.start();
} catch (Throwable t) {
t.printStackTrace();
} finally {
//reset the classloader
Thread.currentThread().setContextClassLoader(originalClassLoader);
}
}
// Dump deployments list
if (log.isDebugEnabled()) {
for (String deployment : container.listDeployments()) {
log.debug("Container deployment: {}", deployment);
}
}
// add a root handler
builder.setHandler(rootHandler);
// build the server instance
server = builder.build();
log.info("Starting Undertow");
server.start();
} catch (Exception e) {
if (e instanceof BindException || e.getMessage().indexOf("BindException")
!= -1) {
log.error("Error loading undertow, unable to bind connector. You may not
have permission to use the selected port", e);
} else {
log.error("Error loading undertow", e);
}
}
Regards,
Paul
--
http://gregoire.org/
http://code.google.com/p/red5/
_______________________________________________
undertow-dev mailing list
undertow-dev(a)lists.jboss.org
https://lists.jboss.org/mailman/listinfo/undertow-dev