Skip to main content


Eclipse Community Forums
Forum Search:

Search      Help    Register    Login    Home
Home » Modeling » TMF (Xtext) » Problem using XtextServlet in SpringBoot Application
Problem using XtextServlet in SpringBoot Application [message #1719826] Tue, 12 January 2016 11:28 Go to next message
Cornelius Mueller is currently offline Cornelius MuellerFriend
Messages: 1
Registered: January 2016
Junior Member
Hi,
i am trying to integrate the XtextServlet in my SpringBoot application for the web integration of my DSL.
During my request to the server i get an error from the XtextServlet:

java.lang.IllegalStateException: STREAMED
at org.eclipse.jetty.server.Request.getReader(Request.java:979) ~[jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at javax.servlet.ServletRequestWrapper.getReader(ServletRequestWrapper.java:266) ~[javax.servlet-api-3.1.0.jar:3.1.0]
at org.eclipse.xtext.web.servlet.HttpServiceContext.initializeParameters(HttpServiceContext.java:91) ~[org.eclipse.xtext.web.servlet-2.9.0.jar:na]
at org.eclipse.xtext.web.servlet.HttpServiceContext.<init>(HttpServiceContext.java:43) ~[org.eclipse.xtext.web.servlet-2.9.0.jar:na]
at org.eclipse.xtext.web.servlet.XtextServlet.getService(XtextServlet.java:216) ~[org.eclipse.xtext.web.servlet-2.9.0.jar:na]
at org.eclipse.xtext.web.servlet.XtextServlet.doPut(XtextServlet.java:136) ~[org.eclipse.xtext.web.servlet-2.9.0.jar:na]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:710) ~[javax.servlet-api-3.1.0.jar:3.1.0]
at org.eclipse.xtext.web.servlet.XtextServlet.service(XtextServlet.java:60) ~[org.eclipse.xtext.web.servlet-2.9.0.jar:na]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) ~[javax.servlet-api-3.1.0.jar:3.1.0]
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:812) ~[jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1669) ~[jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.websocket.server.WebSocketUpgradeFilter.doFilter(WebSocketUpgradeFilter.java:224) ~[websocket-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) ~[jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) ~[jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:84) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) ~[jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) ~[jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:121) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-4.2.4.RELEASE.jar:4.2.4.RELEASE]
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1652) ~[jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:585) [jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:577) [jetty-security-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:223) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1127) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:515) [jetty-servlet-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:185) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1061) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:97) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.Server.handle(Server.java:499) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:311) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:257) [jetty-server-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:544) [jetty-io-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:635) [jetty-util-9.2.14.v20151106.jar:9.2.14.v20151106]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:555) [jetty-util-9.2.14.v20151106.jar:9.2.14.v20151106]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_60]

There is an error in java.io.BufferedReader getReader() - if getInputStream() method has been called on this request.
getInputStream() is called before from the DispatcherServlet from SpringBoot.
Do you have an idea how to avoid this error or a hint for a correct Spring Boot implementation?
Thanks in advance!
(xtext version 2.9.0)

[Updated on: Wed, 13 January 2016 01:13]

Report message to a moderator

Re: Problem using XtextServlet in SpringBoot Application [message #1720050 is a reply to message #1719826] Thu, 14 January 2016 07:16 Go to previous messageGo to next message
Sven Efftinge is currently offline Sven EfftingeFriend
Messages: 83
Registered: January 2016
Location: Kiel
Member

I fear we haven't tested it within SpringBoot so far.
Could you please file a ticket and if possible attach a project, so we can reproduce and debug?

Thanks,
Sven
Re: Problem using XtextServlet in SpringBoot Application [message #1746933 is a reply to message #1720050] Mon, 07 November 2016 19:08 Go to previous messageGo to next message
Anthony Mising name is currently offline Anthony Mising nameFriend
Messages: 4
Registered: November 2010
Junior Member
Hi,
I've been trying to get the same thing to work today. I got the same error as described. It looks like the servlet specification does not permit calling request.getReader() more than once.

It turns out that spring auto configures filters into the web context. One of the filters OrderedHttpPutFormContentFilter makes a call request.getReader() method causing the invalid state when the Xtext Servlet also subsequently makes the same call.

To get around this I've disabled the filters: OrderedHttpPutFormContentFilter and HiddenHttpMethodFilter.

Here is the code I used.

package org.xtext.example.mydsl.web;

import java.util.ArrayList;

import org.eclipse.jetty.annotations.AnnotationConfiguration;
import org.eclipse.jetty.webapp.AbstractConfiguration;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.context.embedded.ConfigurableEmbeddedServletContainer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.HiddenHttpMethodFilter;

@Component
public class SpringBootJetty implements BeanFactoryPostProcessor {

@Bean
public JettyEmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() {
JettyEmbeddedServletContainerFactory jettyContainer = new JettyEmbeddedServletContainerFactory();

jettyContainer.setPort(8080);

return jettyContainer;
}


@Bean
public FilterRegistrationBean registration1(OrderedHttpPutFormContentFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}

@Bean
public FilterRegistrationBean registration2(HiddenHttpMethodFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}

@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory bf)
throws BeansException {
// You can iterate through all the filters and disable.....
// DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) bf;
//
// Arrays.stream(beanFactory.getBeanNamesForType(javax.servlet.Filter.class))
// .forEach(name -> {
//
// BeanDefinition definition = BeanDefinitionBuilder
// .genericBeanDefinition(FilterRegistrationBean.class)
// .setScope(BeanDefinition.SCOPE_SINGLETON)
// .addConstructorArgReference(name)
// .addConstructorArgValue(new ServletRegistrationBean[]{})
// .addPropertyValue("enabled", false)
// .getBeanDefinition();
//
// beanFactory.registerBeanDefinition(name + "FilterRegistrationBean",
// definition);
// });
}


@Bean
public ServletRegistrationBean xtextServletRegistrationBean() {
ServletRegistrationBean bean = new ServletRegistrationBean(new MyDslServlet(), "/xtext-service/*");
bean.setName("XtextService");
bean.setOrder(ServletRegistrationBean.HIGHEST_PRECEDENCE);
bean.setOrder(100);
return bean;
}

}


Hope this gets you further on.

Cheers
Anthony

[Updated on: Mon, 07 November 2016 19:39]

Report message to a moderator

Re: Problem using XtextServlet in SpringBoot Application [message #1752918 is a reply to message #1746933] Mon, 30 January 2017 16:31 Go to previous messageGo to next message
Sandeep Joseph is currently offline Sandeep JosephFriend
Messages: 5
Registered: January 2017
Junior Member
Hello Anthony,

Thanks a lot for your answer. I ended up facing the same error, and your solution got me out of it. Looks like we are doing something very similar. I guess it would be cool if we could collaborate a bit and do some information exchange. Would you be interested?

@Cornelius: How about you?

Regards,
Sandeep Joseph
SAP SE
Re: Problem using XtextServlet in SpringBoot Application [message #1780966 is a reply to message #1752918] Tue, 30 January 2018 15:05 Go to previous messageGo to next message
Nicholas Loke is currently offline Nicholas LokeFriend
Messages: 1
Registered: January 2018
Junior Member
The problem is with xtext using application/x-www-form-urlencoded as the content type for the payload. This causes the springboot filter to read the stream and parse the data.

Even if you disable the filter, eventually you will still have a problem with app servers like Undertow parsing the payload on their HttpServerRequest implementation and putting into their own FormData representation causing the XTextServlet no longer able to read the payload and hence not behaving properly. In the scenario I just described, it will cause the fullText to be null and cause further error.

I suggest that Xtext Web to introduce their own proprietary Content-Type instead of using the standard application/x-www-form-urlencoded as content type. Thay way no generic filters or web server implementations will interfere. Of course the downside will be having to add the Xtext Content-Type to the web server as an allowed Content-Type
Re: Problem using XtextServlet in SpringBoot Application [message #1781045 is a reply to message #1780966] Wed, 31 January 2018 18:35 Go to previous messageGo to next message
Christian Dietrich is currently offline Christian DietrichFriend
Messages: 14665
Registered: July 2009
Senior Member
Please file bug at github.com/eclipse/Xtext-web
But I fear there is currently nobody willing to work on this
So you would have to come up with a patch yourself


Twitter : @chrdietrich
Blog : https://www.dietrich-it.de
Re: Problem using XtextServlet in SpringBoot Application [message #1793582 is a reply to message #1781045] Fri, 10 August 2018 13:39 Go to previous message
Mykola Makhin is currently offline Mykola MakhinFriend
Messages: 50
Registered: July 2018
Member
Perhaps one could circumvent the issue by putting another filter mapped to XtextServlet path that would cache input stream in memory and allow for multiple calls of getReader.
One can check this StackOverflow question to see how that can be implemented: https://stackoverflow.com/questions/4449096/how-to-read-request-getinputstream-multiple-times

The filter should be called before Spring's filters though.
Previous Topic:Context aware grammar help
Next Topic:How to multi selection in the xtext Content Assist
Goto Forum:
  


Current Time: Thu Apr 18 11:24:18 GMT 2024

Powered by FUDForum. Page generated in 0.02353 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top