REST + Spring Security session problem

REST, sessions .. wait. There are no sessions in REST application, right? Well, thats true. If we can avoid sessions we should do that. REST is stateless. The main concern about statelessness is authentication. In usual web applications we were used to store user data in session after authentication. How to solve that if we don’t want to use sessions? We should authenticate every request.

Thanks to that we can scale our application, add new nodes, remove nodes without care about session replication and also about consumed Java heap memory.

Recently I’ve been working on high load REST application. Actually we didn’t expect to have high traffic there but surprisingly we had much much higher that we have been prepared for (it’s so called “happy problem”). Application is based on Spring Framework and its secured with Spring Security deployed on Apache Tomcat 7. All resources are totally stateless – HttpSession is not touched by any piece of my code. Unfortunately used Java heap space was increasing all the time until:

java.lang.OutOfMemoryError: Java heap space

was thrown. In order to analyze Java heap dump and runtime usage of heap I used VisualVM.

Heap dump analysis shown that big part of memory was used by ConcurrentHashMaps used by Tomcat to store sessions. Those sessions object were almost empty but there were so many of them that they consumed ~50% of reserved Java heap space.

Add parameter to Tomcat startup script: -XX:+HeapDumpOnOutOfMemoryError to get Java heap dump on java.lang.OutOfMemoryError: Java heap space
First thing that I’ve done was to limit session timeout from default 30 minutes to 1 minute (lowest possible option) in web.xml:

<?xml version='1.0' encoding='UTF-8'?>
<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'>
    <!-- ... -->

    <session-config>
        <session-timeout>1</session-timeout>
    </session-config>
</web-app>

That solved the problem – heap was cleaned by GC with better results and OutOfMemoryError was not thrown anymore. But more important thing is where those sessions were coming from? The answer is: Spring Security.

By default Spring Security creates sessions if required – which means that if user has authenticated successfully then session is created. In my case it meaan – always. In order to prevent Spring Security from creating sessions create-session='never' needs to be added to http:

<http create-session='never'>
    <!-- ... -->
</http>

You might think – empty session objects should not be a problem. I can tell you that for application handling few hundreds of requests per second it does a real change. Especially when its not running in the cloud or has few GB or RAM memory dedicated for Java heap. That’s how Java heap usage look like after those modifications:

Reference: Solving REST + Spring Security session problem from our JCG partner Maciej Walkowiak at the Software Development Journey blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

Leave a Reply


nine × = 72



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use | Privacy Policy
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

20,709 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books