Link to home
Start Free TrialLog in
Avatar of a122178
a122178

asked on

Question about tomcat shared session.

Hi all,

I want to have share sessions between two tomcat web application. I have read some information about the Tomcat cluster. However, the session will only be replicated when one of the servers are down. I want to have the sessions to be replicated anytime when there is a request. Also, the setup of the cluster is heavy. Since that all the objects have to be serialized, I could not find some of them. I want to see if anyone have any other suggestion for me to do this session sharing.

Thanks,
Avatar of rrz
rrz
Flag of United States of America image

I don't know anyway of sharing sessions. But what did you end up doing with your context elements in your last question ? The reason I ask is because the context element has the crossContext attribute. If you set crossContext = "true" , then you might be able to use  ServletContext.getContext(java.lang.String uripath)  to share info between the two contexts. I haven't tried this but maybe fargo or some other expert has tried it and will help you.   rrz
a122178, can I assume that you have this article http://www.onjava.com/pub/a/onjava/2004/11/24/replication1.html

Does it help?
Avatar of a122178
a122178

ASKER

For the last question, I figure it out how to do.

what I need is just to create an [myapp].xml file inside the folder, tomcat/conf/[EngineName]/[host]/

<context docBase="/myapp2">

</context>

Then when user put the link URL: http://localhost/myapp will be treated as http://localhost/myapp2

Hope it helps.
>I want to have share sessions between two tomcat web application.    
Please give us more details. What exactly are you trying to accomplish.   rrz
Avatar of a122178

ASKER

If one of the sessions is updated, the other one will update immediately. I want to have the user information synchronized together.
Hopefully bloodredsun will comeback here to help you. He has more knowledge then I do.  
>I want to have the user information synchronized together.  
 I have an idea how this could be accomplished. I did do a limited test. If you want and we have time, then we could do more work on this.
I made two  contexts and created two xml files that looked like  this

<Context docBase="${catalina.home}/webapps/test"
         crossContext="true">

</Context>

and put those two files in myTomcatHome\conf\Catalina\localhost  
Then I made two listeners  that looked like this

package test;  
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ShareListener implements HttpSessionAttributeListener {
 public void attributeAdded(HttpSessionBindingEvent event){}
 public void attributeRemoved(HttpSessionBindingEvent event){}
 public void attributeReplaced(HttpSessionBindingEvent event){
        String currentAttributeName = event.getName();
        System.out.println(currentAttributeName + " was replaced in test app"); // in other context change to its name
        HttpSession session = event.getSession();
        String userName = (String)session.getAttribute("userName");
        String newValue = (String)session.getAttribute(currentAttributeName);
        Hashtable table = (Hashtable)session.getServletContext().getAttribute("sessionShare");
        table.put(userName,newValue);
 }
}

and registered each of them in their respective context's web.xml file  with something like  this.
    <listener>
              <listener-class>test.ShareListener</listener-class>
    </listener>

Then i made four JSPs and placed two in each context
first JSP
<%@ page import="java.util.*"%>
<%
  application.setAttribute("sessionShare", new Hashtable());
  session.setAttribute("share","I am from test app"); //   in other context change to its name
  session.setAttribute("userName","rrz");
  String userName = (String)session.getAttribute("userName");
  String shareString = (String)session.getAttribute("share");
  Hashtable table = (Hashtable)application.getAttribute("sessionShare");
  table.put(userName,shareString);
%>
<%=(String)table.get(userName)%>
<%
  ServletContext testContext = application.getContext("/test2"); //  in the other context change to point this context
  Hashtable testTable = (Hashtable)testContext.getAttribute("sessionShare");
%>
<%=(String)testTable.get(userName)%>

second JSP
<%
  session.setAttribute("share","I am from test app and I am sharing!"); // in other context change its name
%>  

I tested all this by first accessing the first JSP in each context then accessing the second in each context. and finally going back to the first JSP.  Please give it a try and let us know what you think.     rrz


What I posted is "proof of concept" code. Certainly we need to do a lot more work on it. One thing that I can think of is using a servlet in each context that loads on startup to create the Hashtable in each context.  That is all the time I got now.    rrz
ASKER CERTIFIED SOLUTION
Avatar of rrz
rrz
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of a122178

ASKER

Thanks.. but please give me some times to digest.
Avatar of a122178

ASKER

You have mentioned master / slave webapp.

-- Are they in the same machine?
-- Are they in the different Tomcat servers?

Does the code work on different Tomcat servers?
>-- Are they in the same machine?
Yes  
>Does the code work on different Tomcat servers?  
No  
I assumed that the two contexts were in the same the Tomcat.  What is your situation ?
Avatar of a122178

ASKER

The situation is that they are in different machine and different Tomcat without cluster.
Thanks for your solution. At least I know how to share session in the same machine.
>The situation is that they are in different machine  
I guess you might be able to use RMI. I have never used it. But with a quick google, I found
http://java.sun.com/docs/books/tutorial/rmi/index.html
Avatar of a122178

ASKER

Thanks. I will try to implement the API by myself