we recently upgraded our jetty version. when we did this both of our legacy gui war files, which no one has modified in some time, stopped working correctly. I believe I hunted the root cause to the proxy (used to proxy to a restful interface on another port), any call to the proxy throws the exception:
IllegalStateException: !asyncSupported
I'm not sure why this would occure with 1.9 but not with the old jetty. I can't build the war file currently, it was a mess that only one developer could ever build, but I trid unzipping it with jetty -x and ading to the servlet section of the web.xml file this:
<async-supported>true</async-supported>
and then rezipping it with jar c command. that didn't seem to help, though now i get exceptions in my jetty log fhile while before they would only show in the browser.
can anyone tell me what to do to activate async support and/or why the switch in jetty would cause this?
Ah, the evolution of the spec ...
Jetty 7 was Servlet 2.5 (no async there)
Jetty 8 was Servlet 3.0 (async introduced) - spec was vague on what was default, so Jetty defaulted to async-supported == true
Jetty 9 is Servlet 3.1 (even more async) - the spec was clarified, and jetty chose its default poorly. The default according to the spec is async-supported == false
That's why you didn't have to specify async-supported in the past, but now you do.
Bug about this bugs.eclipse.org/410893
Commit: 9bf7870c7c8a209f2660f63c14dd4acb62b07533
My exception is the same to you. then I put "<async-supported>true</async-supported>" append to every servlet and filter. it work well.
For excample
<filter>
<filter-name>continuation</filter-name>
<filter-class>org.eclipse.jetty.continuation.ContinuationFilter</filter-class>
<async-supported>true</async-supported>
</filter>
<servlet>
<servlet-name>cometd</servlet-name>
<servlet-class>org.cometd.annotation.AnnotationCometdServlet</servlet-class>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
the other hand. if you used jetty9.x. you'd better update your comet jar to version 3.0.x or later. I hope it will help you.
I can't (yet) put this as a comment, but I'd like to add: If you are having this trouble and have added the async-supported tag as appropriate (or are using Jetty 8), make sure your filters also support async or are not used with the servlet in question.
For Java based config you may use
#javax.servlet.annotation.WebServlet(name = "HelloWorld",urlPatterns = { "/MyServlet" },asyncSupported =true)
Related
Environment
Spring 4.3 (no Spring Boot!), JDK 8/11, Tomcat 8.5.x, Vaadin 19/20-SNAPSHOT
I have a legacy webapp running another servlet-api-driven web framework at http://app.com. I want to add a path that adds a Vaadin-driven UI to this application - let's say at http://app.com/vaaadin-app . I'm using the newly developed official Gradle plugin. (Both Vaadin and non-Vaadin web applications should be run from single WAR, effectively sharing single classloader for shared state access, so no proxy/rewrite/etc solutions will help here).
Problem
After adding dependencies the Vaadin app is properly built and war created. Yet as soon as I call http://app.com (not http://app.com/vaadin-app) it looks like Vaadin servlet/whatever is taking over all requests. It looks like it is automatically initialized by (I guess) servlet 3.0 annotations.
Question
How can I enable Vaadin only for http://app.com/vaadin-app and keep it away from altering requests not directed there? I know with Vaadin 8 it was possible to achieve this with:
<servlet>
<servlet-name>vaadinServlet</servlet-name>
<servlet-class>com.vaadin.server.VaadinServlet</servlet-class>
<init-param>
<param-name>UI</param-name>
<param-value>app.vaadin.additem.AddItemUI</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>vaadinServlet</servlet-name>
<url-pattern>/vaadin-app/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>vaadinServlet</servlet-name>
<url-pattern>/VAADIN/*</url-pattern>
</servlet-mapping>
In other words: how to prevent Vaadin 19/20 from spawning itself automatically for /* but to serve application only when user hits the /vaadin-app/* servlet path???
I think in case of maven plugin there was the "disable.automatic.servlet.registration" option to achieve this? But I don't see anything like this in case of Gradle plugin.
Thanks!
The servlet registration in Vaadin should have nothing related to Gradle, so applying the generic instructions should work. The automatic servlet registration is omitted if you define a VaadinServlet manually (extend it and map the servlet to your location of choice using #WebServlet).
Check this part of the documentation for more details: https://vaadin.com/docs/latest/flow/advanced/application-lifecycle/#automatic-servlet-registration
We recently upgraded to Spring 5.1.3 and Hateoas 0.25 and started facing problems with the generated links.
Say our domain is xyz.com and all requests that come to any subsystem via the load-balancer are forwarded to the main system where the hateoas links generated had links with xyz.com domain.
However, after the upgrade, the hateoas links generated for such requests now have the internal hostname eg. host5678.internaldomain.com.
I came across an issue logged for this at: https://github.com/spring-projects/spring-hateoas/issues/753 where it provided an interim solution via https://stackoverflow.com/a/53269319 which recommends using FilterRegistrationBean
It appears that FilterRegistrationBean is available as part of Spring Boot which we don't use so that solution is out of the question.
So I tried adding a new filter ForwardedHeaderFilter directly in the application web.xml. However, this creates problems with redirect URLs with HTTPS getting converted to HTTP.
The other solution mentioned was to upgrade to 0.25.1 and use Spring property server.use-forward-headers=true. Upgrade is done but I couldn't find XML equivalent of this property as we are using Spring XML for configuration.
Any help with this regards would be sincerely appreciated.
Found the answer after going through the source and trying some different combinations.
The issues mentioned in the question have been fixed in the Hateoas release 0.25.1 so one part of the solution was to upgrade Hateoas to 0.25.1.
The other part is inspired from the SO link given in the question but it didn't work as is, in my case since that is applicable for Spring Boot only. Since we don't use Spring Boot but we have a traditional web application running with a J2EE container, the solution is to include the ForwardedHeaderFilter as part of the web application's web.xml as follows:
<filter>
<filter-name>forwardedHeaderFilter</filter-name>
<filter-class>org.springframework.web.filter.ForwardedHeaderFilter</filter-class>
<init-param>
<param-name>relativeRedirects</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>forwardedHeaderFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
After some time spent with servlets and JSPs now i'm trying to learn something about JSF. I've learned the basics, made a couple of simple examples, have a basic ideea of the 'workflow' but I still can't understand what's with the javax.faces.webapp.FacesServlet thing.
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
I know that "Faces Servlet" it's just an 'internal' name just for the XML and that it gets bind with a class, in this case: javax.faces.webapp.FacesServlet. But where is this class anyway?! I'm using Eclipse, created a new Dynamic Project, GlassFish 4.0 as Server, JSF 2.0 as Configuration (selected no library) and neither did I import any jar. How can it be working? And when I try to run the same thing with JBoss I must import a javax.faces-2.2.2.jar file.
Ok, the library might be already included in GlassFish since it works but... will I face any problems if I try to deploy my app on another server? Like JBoss or Websphere.
In a nutshell: what are the prerequisites when working with JSF technology :)
Thank you.
javax.faces.webapp.FacesServlet is a class that implements Servlet interface. In order to be recognized in your application, you should add it in the web.xml as a <servlet>. This is basically done in this configuration:
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Now, we can refer to this class in the web.xml file using the Faces Servlet name. Next thing do to is define the URL that will be handled by this servlet. This is done in this configuration:
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
So, any GET or POST request to this application server that ends with jsf suffix will be handled by Faces Servlet. You can use other URL patterns for the servlet mapping. This is better explained here: JSF Facelets: Sometimes I see the URL is .jsf and sometimes .xhtml. Why?
will I face any problems if I try to deploy my app on another server? Like JBoss or Websphere?
If the application server is a Java EE 5 compliant server, then you will have access to this servlet by using Mojarra implementation in form of JSF 1.2. For Java EE 6 compliant servers this will be in Mojarra implementation in for of JSF 2.x (check the notes of the application server to know the exact version). Currently, with GlassFish 4, you get Mojarra for JSF 2.2.
In case the application server is not a Java EE compliant server e.g. Tomcat, you must add the libraries manually in WEB-INF/lib folder of your web application. Which libraries to add? Depending on the JSF version and its requirements (read further).
what are the prerequisites when working with JSF technology?
This is covered in StackOverflow JSF wiki. Taken from there:
Minimum requirements
JSF 1.0 and 1.1 requires a minimum of Servlet 2.4 / JSP 2.0 and Java 1.4.
JSF 1.2 works on Servlet 2.4, but requires a minimum of JSP/EL 2.1 which goes hand in hand with Servlet 2.5, so it after all requires Servlet 2.5. If you replace JSP 2.1 by Facelets 1.x as default view technology, then you can use JSF 1.2 on Servlet 2.4. It requires a minimum of Java 1.5.
JSF 2.0 which uses by default Facelets 2.x requires a minimum of EL 2.1 which goes hand in hand with Servlet 2.5, so it requires after all Servlet 2.5. If you supply your own EL 2.1 API/impl, then you can in theory run JSF 2.0 on Servlet 2.4. It requires a minimum of Java 1.5.
JSF 2.1 uses some Servlet 3.0 specific features, but is backwards compatible with Servlet 2.5. Those Servlet 3.0 features are optional.
JSF 2.2 requires a minimum of Servlet 3.0, because of the new file upload component which is internally using the standard Servlet 3.0 API without the need for 3rd party libraries. It requires a minimum of Java 1.6.
Examples of Servlet 2.4 containers are Tomcat 5.5.x, JBoss AS 4.x and Sun Java Application Server.
Examples of Servlet 2.5 containers are Tomcat 6.0.x, JBoss AS 5.x and GlassFish 2.x.
Examples of Servlet 3.0 containers are Tomcat 7.0.x, JBoss AS 6.x and 7.x and GlassFish 3.x.
Examples of Servlet 3.1 containers are Tomcat 8.0.x, WildFly 8.x, and GlassFish 4.x.
I have a web application deployed as war file in weblogic 10.3.3. Now I want to make this application clusterable. For this I'm using the HttpClusterServlet from Weblogic as a load balancer. According to the documentation I can put this servlet configuration into the web.xml
<servlet>
<servlet-name>HttpClusterServlet</servlet-name>
<servlet-class>weblogic.servlet.proxy.HttpClusterServlet</servlet-class>
<init-param>
<param-name>WebLogicCluster</param-name>
<param-value>server-1:7122|server-1:7123</param-value>
</init-param>
</servlet>
The problem is that this configuration is hard wired at build time and can't be reconfigured at runtime. For instance I would like to be able to add 5 more servers dynamically. I had several ideas to solve that problem:
Extend the weblogic.servlet.proxy.HttpClusterServlet with an own servlet implentation. This is not possible, the class is final.
Use a servlet filter to reconfigure the servlet. The servlet is not accessible anymore through ServletContext().getServlet(String) since Java Servlet API 2.1, with no direct replacement.
Reflection might be an option, but I couldn't figure out a reliable way to access the configuration
All of my attempts to reconfigure this init-param externally failed so far. I'm open to any solutions.
This might help How to externalize web.xml servlet init-param? Spring DelegatingFilterProxy for Servlets? Even if your not using Spring it wouldn't be too hard to port that servlet to another IoC container.
Following an issue reported on this question, a solution was found:
req.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true);
This seems a bit strange and is not really 'portable' code (it won't hurt, but...). It seems specific to Tomcat 7. I am using Tomcat 7.0.14 as delivered by NetBeans 7.0.1.
I could not find documentation indicating it is necessary to enable async request processing in servlet 3.0 with a catalina attribute. I could not find documentation indicating something special was necessary at the Tomcat configuration level too.
Is there a way to avoid having to set ASYNC_SUPPORTED=true in each request to enable async servlet 3.0 processing in Tomcat 7?
A couple of things to check first:
Make sure any filters that operate on the request also support async (as addressed in one of the answers to the question you referenced).
Make sure you're using a Servlet 3.0 web.xml - for example:
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0"
metadata-complete="true">
Try upgrading.
Bug 53623 fixed in 7.0.30.
"Enable remaining valves for Servlet 3 asynchronous processing support." (fixed in 7.0.16)
Check the Tomcat 7 ChangeLog for complete details.
Also, if you want to use async, then you'll need to make sure that all of the filters and valves in the chain (as well as the servlet, of course) all support async. This is likely the problem in the original question, as well as with your case, here.
I found that org.apache.catalina.ASYNC_SUPPORTED=true is only needed when you from one normal-servlet/jsp (internally) forward to an async-servlet!
Example: In my index.jsp, I embed <jsp:forward page="/path/AsyncServlet" />
I promise the AsyncServlet works fine on both Tomcat7 and Glassfish3, when I directly trigger it from browser!
However when I trigger it by index.jsp:
Tomcat7 reports 500 for "Not supported"
Glassfish3 reports 500 for "Request is within the scope of a filter or servlet that does not support asynchronous operations"
If I embed <% request.setAttribute("org.apache.catalina.ASYNC_SUPPORTED", true); %> before <jsp:forward> in index.jsp, Tomcat7 goes OK, but Glassfish3 still is BAD!
So I found a solution for both Tomcat7 and Glassfish3 (without SYNC_SUPPORTED!):
Just EXACTLY attach followings in web.xml:
<servlet>
<servlet-name>indexPage</servlet-name>
<jsp-file>/index.jsp</jsp-file>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>indexPage</servlet-name>
<url-pattern>/index.jsp</url-pattern>
</servlet-mapping>
Conclusion (for me):
You can NOT forward from a normal-servlet/jsp/filter to an async-one! Since the async-request feature MUST be preset!
So the common solution for a servlet/jsp/filter which needs to forward to an async-servlet is:
Use <servlet>/<async-supported>true or #WebServlet(asyncSupported = true) for a pre-processed servlet;
Use <servlet>/<async-supported>true for a pre-processed jsp
Use <filter>/<async-supported>true or #WebFilter(asyncSupported = true) for a pre-processed filter;
Hope this may help a little bit!