Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Infinite Loop in DefaultToSoyDataConverter when model contains BindingResult #60

Open
solidjb opened this issue May 19, 2015 · 2 comments

Comments

@solidjb
Copy link
Contributor

solidjb commented May 19, 2015

Spring can add a BindingResult object into the model for objects in the model that are not primitive or collections. Unfortunately if this happens, DefaultToSoyDataConverter blows the stack. When DefaultToSoyDataConverter creates a pojo map from the BindingResult objects, it adds an entry with the key 'model', and a value of the entire model which essentially starts the whole recursive stack over again. It eventually works its way through the model until it gets to the BindingResult again, infinite loop...

Here is a simple test case that reproduces this error. (I put it into pl.matisoft.soy.data.DefaultToSoyDataConverterTest)


    @Test
    public void testNestedObjectInfiniteLoopBug() throws Exception {
        ModelAndView mav = new ModelAndView("test-view");
        PojoTest nestedReference = new PojoTest();

        mav.addObject("top-level", nestedReference);
        mav.addObject("binding", new DirectFieldBindingResult(nestedReference, "nested"));

        Object results = objectToSoyDataConverter.toSoyCompatibleMap(mav);
    }

Running the above test produced the following results :


Tests run: 15, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.141 sec <<< FAILURE!
testNestedObjectInfiniteLoopBug(pl.matisoft.soy.data.DefaultToSoyDataConverterTest)  Time elapsed: 0.102 sec  <<< ERROR!
java.lang.StackOverflowError: null
    at java.lang.ReflectiveOperationException.(ReflectiveOperationException.java:89)
    at java.lang.reflect.InvocationTargetException.(InvocationTargetException.java:72)
    at sun.reflect.GeneratedMethodAccessor11.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.pojoToMap(DefaultToSoyDataConverter.java:145)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:126)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:102)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:129)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:102)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:129)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:102)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:129)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:102)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:129)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:102)
...
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:129)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:102)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:129)
    at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:102)


Results :

Tests in error: 
   » StackOverflow

Tests run: 131, Failures: 0, Errors: 1, Skipped: 0

I am not sure about the best way to deal with this. We could add explicit code to deal with BindingResults, but I am not sure that is the best solution...

@matiwinnetou
Copy link
Owner

I am aware of this, this is why I have this https://github.com/matiwinnetou/spring-soy-view/blob/master/spring-soy-view/src/main/java/pl/matisoft/soy/data/adjust/ModelAdjuster.java, this basically allows to filter out the model passed to DefaultToSoyDataConverter class.

@lilalinux
Copy link

lilalinux commented Aug 9, 2016

How do I fix that? It worked with POJOs, but since I'm using Spring Data JPA, it stackoverflows:

2016-08-09 04:39:23.388 [qtp1327127443-25] [DEBUG] o.s.w.s.DispatcherServlet - Could not complete request
org.springframework.web.util.NestedServletException: Handler processing failed; nested exception is java.lang.StackOverflowError
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:986) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:861) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) [javax.servlet-api-3.1.0.jar:3.1.0]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.1.RELEASE.jar:4.3.1.RELEASE]
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:751) [jetty-servlet-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:566) [jetty-servlet-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:143) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:578) [jetty-security-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:221) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1111) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:498) [jetty-servlet-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:183) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1045) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:141) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:199) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:109) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:98) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.Server.handle(Server.java:461) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.HttpChannel.handle(HttpChannel.java:284) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.server.HttpConnection.onFillable(HttpConnection.java:244) [jetty-server-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.io.AbstractConnection$2.run(AbstractConnection.java:534) [jetty-io-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:607) [jetty-util-9.2.1.v20140609.jar:9.2.1.v20140609]
at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:536) [jetty-util-9.2.1.v20140609.jar:9.2.1.v20140609]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_25]
Caused by: java.lang.StackOverflowError: null
at java.beans.WeakIdentityMap.get(WeakIdentityMap.java:56) ~[na:1.8.0_25]
at java.beans.ThreadGroupContext.getContext(ThreadGroupContext.java:57) ~[na:1.8.0_25]
at java.beans.Introspector.getBeanInfo(Introspector.java:167) ~[na:1.8.0_25]
at pl.matisoft.soy.data.DefaultToSoyDataConverter.pojoToMap(DefaultToSoyDataConverter.java:135) ~[spring-soy-view-1.25.4.jar:na]
at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:122) ~[spring-soy-view-1.25.4.jar:na]
at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:106) ~[spring-soy-view-1.25.4.jar:na]
at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:125) ~[spring-soy-view-1.25.4.jar:na]
at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:125) ~[spring-soy-view-1.25.4.jar:na]
at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:106) ~[spring-soy-view-1.25.4.jar:na]
at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:125) ~[spring-soy-view-1.25.4.jar:na]
at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:125) ~[spring-soy-view-1.25.4.jar:na]
at pl.matisoft.soy.data.DefaultToSoyDataConverter.toSoyCompatibleObjects(DefaultToSoyDataConverter.java:106) ~[spring-soy-view-1.25.4.jar:na]

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants