baiheqiang / memcached-session-manager

Automatically exported from code.google.com/p/memcached-session-manager
0 stars 0 forks source link

Webapp context reload causes ClassCastException with sticky sessions #80

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Some package in jar in WEB-INF/lib
2. Init app, put object in session
3. Redeploy
4. Try to access object in session
5. ClassCastException

What is the expected output? What do you see instead?

Working without ClassCastException

What version of the product are you using? On what operating system?

tc7-1.4.0-RC1 
Tomcat 7.0.6
JDK 1.6.0_18 x86
Windows 7 x64

Please provide any additional information below.

Object o = session.getAttribute("cache");
ru.cache.Cache cache = (ru.cache.Cache) o;

java.lang.ClassCastException: ru.cache.CacheImpl cannot be cast to 
ru.cache.Cache
    at ru.web.application.WebContext.getCache(WebContext.java:349)
    at ..
    at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

Both ru.cache.Cache is interface, ru.cache.CacheImpl is class,
both in same jar, this jar is inside WEB-INF/lib.

Doublechecked not having this class in application server classpath.

When running under debugging, surprisingly
o.getClass().getClassLoader() != ru.cache.Cache.class.getClassLoader()

Original issue reported on code.google.com by rusla...@gmail.com on 4 Feb 2011 at 12:37

GoogleCodeExporter commented 8 years ago
How do you create and add the "cache"? Is it possible, that it's a cglib proxy, 
or is it just session.setAttribute("cache", new CacheImpl())? Which 
serialization strategy are you using (java, kryo, javolution)?

Original comment by martin.grotzke on 4 Feb 2011 at 12:51

GoogleCodeExporter commented 8 years ago
i just do session.setAttribute("cache", new CacheImpl()). Default java 
serialization is used, my manager configuration is following:

<Manager className="de.javakaffee.web.msm.MemcachedBackupSessionManager"
    memcachedNodes="nodename:hostname:11211"
    failoverNodes=""
    requestUriIgnorePattern=".*\.(png|gif|jpg|css|js)$"
    sessionBackupAsync="true"
    sessionBackupTimeout="100"
    copyCollectionsForSerialization="false"
/>

Original comment by rusla...@gmail.com on 4 Feb 2011 at 1:10

GoogleCodeExporter commented 8 years ago
I just create a sample webapp with a servlet that can put stuff into such a 
Cache/CacheImpl (implementing Serializable also) and list the content of the 
cache, but I cannot reproduce your issue:
https://github.com/magro/msm-sample-webapp/tree/simpleservlet

The following should work:

Install deps and build the war:
$ ./install-mvn-deps.sh
$ mvn package

Start memcached:
$ memcached -p 11211 -u memcached -m 64 -M -vv &
$ memcached -p 11212 -u memcached -m 64 -M -vv &

Start tomcats:
$ ./runtime/tomcat1/bin/catalina.sh run &
$ ./runtime/tomcat2/bin/catalina.sh run &

Populate/list the content of the cache which is stored in the session:
- In your browser request http://localhost:8081/put?foo=bar (or use curl or 
whatever)
- To see that the cache in the session is populated: http://localhost:8081/list
-> The response body should contain "foo=bar"

Load this session/cache in another tomcat to see that the session/cache can be 
deserialized:
- Request http://localhost:8082/list
-> The response body should contain "foo=bar"

Also, when running the tomcat I can redeploy the webapp via
$ mvn package
and after the context was restarted I still can list the session/cache content.

What's different in your case? Can you modify this sample app so that I can 
reproduce your issue?

Original comment by martin.grotzke on 6 Feb 2011 at 12:33

GoogleCodeExporter commented 8 years ago
Btw, I just pushed a new version of the sample with also tomcat 6.0.32 and a 
new msm 1.4.0-RC2 (which only contains fixes for #79 and #81, which should not 
affect you).

Original comment by martin.grotzke on 7 Feb 2011 at 10:52

GoogleCodeExporter commented 8 years ago
Sorry I can`t run it, I don`t have POM and my target environment is not Linux. 
However I`ve made simpler test, just unpack over fresh apache-tomcat-7.0.6. 

I am experiencing odd behaviour - on subsequential request, value is not stored 
into session. Also in log, I see double initialization of MSM.

Original comment by rusla...@gmail.com on 7 Feb 2011 at 11:47

Attachments:

GoogleCodeExporter commented 8 years ago
Same setup, tc6.0.32, msm tc6 jar - i get java.lang.IllegalArgumentException: 
setAttribute: Non-serializable attribute cache

I wonder why tc7 setup does not check that.

Original comment by rusla...@gmail.com on 7 Feb 2011 at 11:51

GoogleCodeExporter commented 8 years ago
Fixed and made a completely reproducable setup.
This time tc6.0.32
1. unpack zip over fresh tomcat
2. modify memcached node in conf/Catalina/localhost/testmsm.xml
3. launch fresh browser over to http://locahost:8080/testmsm/
4. touch web.xml
5. wait for app to be redeployed
6. reload page
7. classcastexception appears

Original comment by rusla...@gmail.com on 7 Feb 2011 at 11:59

Attachments:

GoogleCodeExporter commented 8 years ago
Ok, I can reproduce this. The next steps I'd take is to bring our two versions 
as nearly together as possible to see where things break.

But I don't have the time to do this now/today because I need to get back to my 
day job.
You can also use my github version and adapt it step by step to your example. 
This should not be much work and there's nothing that is really bound to linux 
(scripts are only convenience, you also don't need the symlinks), if you have a 
look at what's there I think you get what it's doing. Maven is also available 
for windows, you can just install it.

Original comment by martin.grotzke on 7 Feb 2011 at 12:16

GoogleCodeExporter commented 8 years ago
As this issue does not occur within a servlet (my example) I'd assume that it's 
a classloading issue with jsps, not sure.

Do you really need to cast in your jsp? I thought scripting in jsp would be 
deprecated since years ;-)
An alternative would be to access via standard jsp tags which should work as 
just the object is accessed, so there should (hopefully) be no classloader 
issue.

This should be just a workaround as the underlying classloading issue should be 
solved, but this might take some time.

Original comment by martin.grotzke on 7 Feb 2011 at 12:58

GoogleCodeExporter commented 8 years ago
Can you confirm that it's only a problem with the jsp and not a general issue?

Original comment by martin.grotzke on 7 Feb 2011 at 12:58

GoogleCodeExporter commented 8 years ago
Can you check the attached jar?

Sessions are now removed from the local session map when the context 
reloads/stops so that the old classloader is no longer referenced from classes.

Original comment by martin.grotzke on 7 Feb 2011 at 1:24

Attachments:

GoogleCodeExporter commented 8 years ago
It is just the same with servlet. I believe it is generic issue with webapp 
reloading.

Original comment by rusla...@gmail.com on 7 Feb 2011 at 1:32

Attachments:

GoogleCodeExporter commented 8 years ago
Did you see my comment 11?

Original comment by martin.grotzke on 7 Feb 2011 at 2:45

GoogleCodeExporter commented 8 years ago
Yes. Sorry been busy. It works fine on tc6. Probably need to check on tc7 to be 
100% sure? Can you produce new jar?

Original comment by rusla...@gmail.com on 7 Feb 2011 at 2:58

GoogleCodeExporter commented 8 years ago
Attached.

Original comment by martin.grotzke on 7 Feb 2011 at 3:10

Attachments:

GoogleCodeExporter commented 8 years ago
Does it work for you with tomcat7 also, can we close this issue?

Original comment by martin.grotzke on 8 Feb 2011 at 8:55

GoogleCodeExporter commented 8 years ago
No ClassCastException. However, upon reloading web application session is new, 
i.e. it is not fetched from memcached.

Original comment by rusla...@gmail.com on 8 Feb 2011 at 5:27

GoogleCodeExporter commented 8 years ago
Also, there two MSM initialization attempts in log and in console windows there 
is message "2011-02-08 20:26:29.369 INFO net.spy.memcached.MemcachedClient:  
Suppressing duplicate attempt to shut down"

Original comment by rusla...@gmail.com on 8 Feb 2011 at 5:28

Attachments:

GoogleCodeExporter commented 8 years ago
The attached jar skips double initialization of internal services now, although 
this didn't cause any real issue.

That the session is not fetched from memcached after the reload is caused by a 
missing call of manager.initInternal for tomcat7, which seems to be a bug in 
tomcat7 compared with the behaviour of tomcat6. Need to submit this as an issue 
against tomcat7 (tomorrow).

Original comment by martin.grotzke on 9 Feb 2011 at 1:22

Attachments:

GoogleCodeExporter commented 8 years ago
Just submitted the bug: https://issues.apache.org/bugzilla/show_bug.cgi?id=50738

Original comment by martin.grotzke on 9 Feb 2011 at 1:38

GoogleCodeExporter commented 8 years ago
According to tomcat guys it's not a bug of tomcat7 that behaviour is changed 
since tomcat6 (regarding context reload), so msm needs to be adapted to this.

I opened this as issue 82.

This one is closed as the originally reported ClassCastException is solved.

Original comment by martin.grotzke on 9 Feb 2011 at 10:54

GoogleCodeExporter commented 8 years ago
Can you check issue 82 and confirm if it works for you? Thanx!

Original comment by martin.grotzke on 9 Feb 2011 at 4:13