<div dir="ltr">Thanks for the reply, now I know I have more work to do. </div><div class="gmail_extra"><br><br><div class="gmail_quote">On Thu, Feb 6, 2014 at 12:33 AM, Stuart Douglas <span dir="ltr"><<a href="mailto:sdouglas@redhat.com" target="_blank">sdouglas@redhat.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div style="font-size:12pt;font-family:times new roman,new york,times,serif"><br><div><br></div><hr><blockquote style="padding-left:5px;font-size:12pt;font-style:normal;margin-left:5px;font-family:Helvetica,Arial,sans-serif;text-decoration:none;font-weight:normal;border-left:2px solid #1010ff">
<b>From: </b>"Mondain" <<a href="mailto:mondain@gmail.com" target="_blank">mondain@gmail.com</a>><br><b>To: </b><a href="mailto:undertow-dev@lists.jboss.org" target="_blank">undertow-dev@lists.jboss.org</a><br>
<b>Sent: </b>Thursday, 6 February, 2014 9:36:34 AM<br><b>Subject: </b>[undertow-dev] Embedding undertow into Red5<div class=""><br><div><br></div><div dir="ltr">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.</div>
</div></blockquote><div>Hi <span style="font-family:Helvetica,Arial,sans-serif">Mondain,</span></div><div><span style="font-family:Helvetica,Arial,sans-serif"><br></span></div><div><span style="font-family:Helvetica,Arial,sans-serif">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. </span></div>
<div><span style="font-family:Helvetica,Arial,sans-serif"><br></span></div><div><span style="font-family:Helvetica,Arial,sans-serif">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. </span></div>
<div><span style="font-family:Helvetica,Arial,sans-serif"><br></span></div><div><span style="font-family:Helvetica,Arial,sans-serif">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.</span></div>
<div><span style="font-family:Helvetica,Arial,sans-serif"><br></span></div><div><span style="font-family:Helvetica,Arial,sans-serif">Stuart</span></div><div><br></div><div><br></div><div><br></div><div><br></div><blockquote style="padding-left:5px;font-size:12pt;font-style:normal;margin-left:5px;font-family:Helvetica,Arial,sans-serif;text-decoration:none;font-weight:normal;border-left:2px solid #1010ff">
<div><div class="h5"><div dir="ltr"><div><br></div><div><div><span style="white-space:pre-wrap">                </span>//get a reference to the current threads classloader</div><div><span style="white-space:pre-wrap">                </span>final ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();</div>
<div><span style="white-space:pre-wrap">                </span>// root location for servlet container</div><div><span style="white-space:pre-wrap">                </span>String serverRoot = System.getProperty("red5.root");</div><div><span style="white-space:pre-wrap">                </span>String confRoot = System.getProperty("red5.config_root");</div>
<div><span style="white-space:pre-wrap">                </span>System.setProperty("UNDERTOW_HOME", serverRoot);</div><div><span style="white-space:pre-wrap">                </span>if (webappFolder == null) {</div><div><span style="white-space:pre-wrap">                        </span>// Use default webapps directory</div>
<div><span style="white-space:pre-wrap">                        </span>webappFolder = FileUtil.formatPath(System.getProperty("red5.root"), "/webapps");</div><div><span style="white-space:pre-wrap">                </span>}</div><div><span style="white-space:pre-wrap">                </span>System.setProperty("red5.webapp.root", webappFolder);</div>
<div><span style="white-space:pre-wrap">                </span>// scan the sub directories to determine our context paths</div><div><span style="white-space:pre-wrap">                </span>buildContextPathList(webappFolder);</div><div><span style="white-space:pre-wrap">                </span>try {</div>
<div><span style="white-space:pre-wrap">                        </span>// create our servlet container</div><div><span style="white-space:pre-wrap">        </span> container = ServletContainer.Factory.newInstance();</div><div><span style="white-space:pre-wrap">                        </span>// create a root path handler</div>
<div><span style="white-space:pre-wrap">                        </span>final PathHandler rootHandler = new PathHandler();</div><div><span style="white-space:pre-wrap">                        </span>// create one server and use it everywhere</div><div><span style="white-space:pre-wrap">                        </span>Undertow.Builder builder = Undertow.builder();</div>
<div><span style="white-space:pre-wrap">                        </span>// loop through connectors adding listeners to the builder</div><div><span style="white-space:pre-wrap">                        </span>for (UndertowConnector undertowConnector : connectors) {</div>
<div><span style="white-space:pre-wrap">                                </span>InetSocketAddress addr = undertowConnector.getSocketAddress();</div><div><span style="white-space:pre-wrap">                                </span>builder.addListener(addr.getPort(), addr.getHostName(), (undertowConnector.isSecure() ? ListenerType.HTTPS : ListenerType.HTTP));</div>
<div><span style="white-space:pre-wrap">                        </span>}</div><div><span style="white-space:pre-wrap">                        </span>// loop the other contexts</div><div><span style="white-space:pre-wrap">                        </span>for (String contextPath : contextPaths) {</div>
<div><span style="white-space:pre-wrap">                                </span>// create a class loader for the context</div><div><span style="white-space:pre-wrap">                                </span>ClassLoader classLoader = buildWebClassLoader(originalClassLoader, webappFolder, contextPath);</div>
<div><span style="white-space:pre-wrap">                                </span>// create deployment info</div><div><span style="white-space:pre-wrap">                                </span>DeploymentInfo info = deployment()</div><div><span style="white-space:pre-wrap">                </span> .setClassLoader(classLoader)</div>
<div><span style="white-space:pre-wrap">                </span> .setContextPath(contextPath.equalsIgnoreCase("/ROOT") ? "/" : contextPath)</div><div><span style="white-space:pre-wrap">                </span> .setDefaultEncoding("UTF-8")</div>
<div><span style="white-space:pre-wrap">                </span> .setDeploymentName(contextPath.substring(1) + ".war")</div><div><span style="white-space:pre-wrap">                </span> .setUrlEncoding("UTF-8");</div>
<div><span style="white-space:pre-wrap">                                </span>// add the new deployment to the servlet container</div><div><span style="white-space:pre-wrap">                                </span>DeploymentManager manager = container.addDeployment(info);</div>
<div><span style="white-space:pre-wrap">                                </span>// deploy</div><div><span style="white-space:pre-wrap">                                </span>manager.deploy();</div><div><span style="white-space:pre-wrap">                                </span>// add path</div><div><span style="white-space:pre-wrap">        </span> rootHandler.addPrefixPath(info.getContextPath(), manager.start());</div>
<div><span style="white-space:pre-wrap">                                </span>// get deployment</div><div><span style="white-space:pre-wrap">                                </span>Deployment deployment = manager.getDeployment();</div><div><span style="white-space:pre-wrap">                                </span>// get servlet context</div>
<div><span style="white-space:pre-wrap">                                </span>final ServletContext servletContext = deployment.getServletContext();</div><div><span style="white-space:pre-wrap">                                </span>log.debug("Context initialized: {}", servletContext.getContextPath());</div>
<div><span style="white-space:pre-wrap">                                </span>try {</div><div><span style="white-space:pre-wrap">                                        </span>log.debug("Context: {}", servletContext);</div><div><span style="white-space:pre-wrap">                                        </span>final ClassLoader webClassLoader = info.getClassLoader();</div>
<div><span style="white-space:pre-wrap">                                        </span>log.debug("Webapp classloader: {}", webClassLoader);</div><div><span style="white-space:pre-wrap">                                        </span>// get the (spring) config file path</div><div><span style="white-space:pre-wrap">                                        </span>final String contextConfigLocation = servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONFIG_LOCATION_PARAM) == null ? defaultSpringConfigLocation</div>
<div><span style="white-space:pre-wrap">                                                        </span>: servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONFIG_LOCATION_PARAM);</div><div><span style="white-space:pre-wrap">                                        </span>log.debug("Spring context config location: {}", contextConfigLocation);</div>
<div><span style="white-space:pre-wrap">                                        </span>// get the (spring) parent context key</div><div><span style="white-space:pre-wrap">                                        </span>final String parentContextKey = servletContext.getInitParameter(org.springframework.web.context.ContextLoader.LOCATOR_FACTORY_KEY_PARAM) == null ? defaultParentContextKey</div>
<div><span style="white-space:pre-wrap">                                                        </span>: servletContext.getInitParameter(org.springframework.web.context.ContextLoader.LOCATOR_FACTORY_KEY_PARAM);</div><div><span style="white-space:pre-wrap">                                        </span>// set current threads classloader to the webapp classloader</div>
<div><span style="white-space:pre-wrap">                                        </span>Thread.currentThread().setContextClassLoader(webClassLoader);</div><div><span style="white-space:pre-wrap">                                        </span>// create a thread to speed-up application loading</div>
<div><span style="white-space:pre-wrap">                                        </span>Thread thread = new Thread("Launcher:" + servletContext.getContextPath()) {</div><div><span style="white-space:pre-wrap">                                                </span>public void run() {</div>
<div><span style="white-space:pre-wrap">                                                        </span>//set thread context classloader to web classloader</div><div><span style="white-space:pre-wrap">                                                        </span>Thread.currentThread().setContextClassLoader(webClassLoader);</div>
<div><span style="white-space:pre-wrap">                                                        </span>//get the web app's parent context</div><div><span style="white-space:pre-wrap">                                                        </span>ApplicationContext parentContext = null;</div><div><span style="white-space:pre-wrap">                                                        </span>if (applicationContext.containsBean(parentContextKey)) {</div>
<div><span style="white-space:pre-wrap">                                                                </span>parentContext = (ApplicationContext) applicationContext.getBean(parentContextKey);</div><div><span style="white-space:pre-wrap">                                                        </span>} else {</div><div><span style="white-space:pre-wrap">                                                                </span>log.warn("Parent context was not found: {}", parentContextKey);</div>
<div><span style="white-space:pre-wrap">                                                        </span>}</div><div><span style="white-space:pre-wrap">                                                        </span>// create a spring web application context</div><div><span style="white-space:pre-wrap">                                                        </span>final String contextClass = servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONTEXT_CLASS_PARAM) == null ? XmlWebApplicationContext.class</div>
<div><span style="white-space:pre-wrap">                                                                        </span>.getName() : servletContext.getInitParameter(org.springframework.web.context.ContextLoader.CONTEXT_CLASS_PARAM);</div><div><span style="white-space:pre-wrap">                                                        </span>// web app context (spring)</div>
<div><span style="white-space:pre-wrap">                                                        </span>ConfigurableWebApplicationContext appctx = null;</div><div><span style="white-space:pre-wrap">                                                        </span>try {</div><div><span style="white-space:pre-wrap">                                                                </span>Class<?> clazz = Class.forName(contextClass, true, webClassLoader);</div>
<div><span style="white-space:pre-wrap">                                                                </span>appctx = (ConfigurableWebApplicationContext) clazz.newInstance();</div><div><span style="white-space:pre-wrap">                                                                </span>// set the root webapp ctx attr on the each servlet context so spring can find it later</div>
<div><span style="white-space:pre-wrap">                                                                </span>servletContext.setAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE, appctx);</div><div><span style="white-space:pre-wrap">                                                                </span>appctx.setConfigLocations(new String[] { contextConfigLocation });</div>
<div><span style="white-space:pre-wrap">                                                                </span>appctx.setServletContext(servletContext);</div><div><span style="white-space:pre-wrap">                                                                </span>// set parent context or use current app context</div><div><span style="white-space:pre-wrap">                                                                </span>if (parentContext != null) {</div>
<div><span style="white-space:pre-wrap">                                                                        </span>appctx.setParent(parentContext);</div><div><span style="white-space:pre-wrap">                                                                </span>} else {</div><div><span style="white-space:pre-wrap">                                                                        </span>appctx.setParent(applicationContext);</div>
<div><span style="white-space:pre-wrap">                                                                </span>}</div><div><span style="white-space:pre-wrap">                                                                </span>// refresh the factory</div><div><span style="white-space:pre-wrap">                                                                </span>appctx.refresh();</div>
<div><span style="white-space:pre-wrap">                                                                </span>appctx.start();</div><div><span style="white-space:pre-wrap">                                                        </span>} catch (Throwable e) {</div><div><span style="white-space:pre-wrap">                                                                </span>throw new RuntimeException("Failed to load webapplication context class", e);</div>
<div><span style="white-space:pre-wrap">                                                        </span>}</div><div><span style="white-space:pre-wrap">                                                </span>}</div><div><span style="white-space:pre-wrap">                                        </span>};</div><div><span style="white-space:pre-wrap">                                        </span>thread.setDaemon(true);</div>
<div><span style="white-space:pre-wrap">                                        </span>thread.start();</div><div><span style="white-space:pre-wrap">                                </span>} catch (Throwable t) {</div><div><span style="white-space:pre-wrap">                                        </span>t.printStackTrace();</div>
<div><span style="white-space:pre-wrap">                                </span>} finally {</div><div><span style="white-space:pre-wrap">                                        </span>//reset the classloader</div><div><span style="white-space:pre-wrap">                                        </span>Thread.currentThread().setContextClassLoader(originalClassLoader);</div>
<div><span style="white-space:pre-wrap">                                </span>}</div><div><span style="white-space:pre-wrap">                        </span>}</div><div><span style="white-space:pre-wrap">                        </span>// Dump deployments list</div><div><span style="white-space:pre-wrap">                        </span>if (log.isDebugEnabled()) {</div>
<div><span style="white-space:pre-wrap">                                </span>for (String deployment : container.listDeployments()) {</div><div><span style="white-space:pre-wrap">                                        </span>log.debug("Container deployment: {}", deployment);</div>
<div><span style="white-space:pre-wrap">                                </span>}</div><div><span style="white-space:pre-wrap">                        </span>}</div><div><span style="white-space:pre-wrap">                        </span>// add a root handler</div><div><span style="white-space:pre-wrap">                        </span>builder.setHandler(rootHandler);</div>
<div><span style="white-space:pre-wrap">                        </span>// build the server instance</div><div><span style="white-space:pre-wrap">        </span> server = builder.build();</div><div><span style="white-space:pre-wrap">                        </span><a href="http://log.info" target="_blank">log.info</a>("Starting Undertow");</div>
<div><span style="white-space:pre-wrap">                        </span>server.start();</div><div><span style="white-space:pre-wrap">                </span>} catch (Exception e) {</div><div><span style="white-space:pre-wrap">                        </span>if (e instanceof BindException || e.getMessage().indexOf("BindException") != -1) {</div>
<div><span style="white-space:pre-wrap">                                </span>log.error("Error loading undertow, unable to bind connector. You may not have permission to use the selected port", e);</div><div><span style="white-space:pre-wrap">                        </span>} else {</div>
<div><span style="white-space:pre-wrap">                                </span>log.error("Error loading undertow", e);</div><div><span style="white-space:pre-wrap">                        </span>}</div><div><span style="white-space:pre-wrap">                </span>}</div><div>
<br></div><div><br></div><div><br></div><div>Regards,</div><div>Paul<br clear="all"><div><br></div>-- <br><a href="http://gregoire.org/" target="_blank">http://gregoire.org/</a><br><a href="http://code.google.com/p/red5/" target="_blank">http://code.google.com/p/red5/</a></div>
</div></div><br></div></div>_______________________________________________<br>undertow-dev mailing list<br><a href="mailto:undertow-dev@lists.jboss.org" target="_blank">undertow-dev@lists.jboss.org</a><br><a href="https://lists.jboss.org/mailman/listinfo/undertow-dev" target="_blank">https://lists.jboss.org/mailman/listinfo/undertow-dev</a></blockquote>
<br></div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br><a href="http://gregoire.org/" target="_blank">http://gregoire.org/</a><br><a href="http://code.google.com/p/red5/" target="_blank">http://code.google.com/p/red5/</a>
</div>