Re: Bes practice for deployment to avoid ClassNotFoundException

2014-11-23 Thread Martin Grigorov
Hi,

You are experiencing Tomcat Session Persistence -
http://tomcat.apache.org/tomcat-7.0-doc/config/manager.html#Persistence_Across_Restarts
Just disable it for development to avoid such kind of problems.

I'd also recommend to use Jetty for development if possible. It is much
faster to restart. See src/test/java/.../Start.java in Wicket Quickstart.

Martin Grigorov
Wicket Training and Consulting
https://twitter.com/mtgrigorov

On Fri, Nov 21, 2014 at 6:22 PM, Thorsten Schöning tschoen...@am-soft.de
wrote:

 Hi all,

 I'm new to wicket and just recently started to use it for a new web
 app for one of our projects. Today I came across a similar issue like
 described in [1], a ClassNotFoundException during deserialization of a
 page. The interesting part about this in my mind is, that the
 mentioned missing class was missing for a good reason: I simply
 refactored a bit and renamed the class, redeployed and restarted my
 Tomcat. This looks like a normal use case to me, but is something I
 didn't thought of when I've read through the docs because.

 My deployment is very simple: I check out a SVN working copy with a
 pre-configured tag containing the whole application once and
 afterwards just need to merge/update and stop/start the web
 server/app.

 How is deployment supposed to work in Wicket after I have refactored
 or otherwise changed my classes regarding cached and serialized pages?
 Is there anything I need to tell wicket to clear its caches on each
 deployment or ignore those or whatever? Am I forced to not delete once
 deployed classes for a fair period of time? That would be a litte
 nightmare... Or is there any other issue I ran into I should have
 avoided?

 Obviously others do deploy their Wicket apps as well, so I hope you
 have some input on how to avoid the problem I've ran into. Thanks!

 The important parts of the stacktrace:

 java.lang.ClassNotFoundException:
 de.am_soft.util.frontend.wicket.markup.link.LogoutLink
  at
 org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
  at
 org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
  at java.lang.Class.forName0(Native Method)
  at java.lang.Class.forName(Unknown Source)
  at
 org.apache.wicket.application.AbstractClassResolver.resolveClass(AbstractClassResolver.java:108)
  at
 org.apache.wicket.serialize.java.JavaSerializer$ClassResolverObjectInputStream.resolveClass(JavaSerializer.java:218)
  at java.io.ObjectInputStream.[...]
  [...]
  at
 org.apache.wicket.serialize.java.JavaSerializer.deserialize(JavaSerializer.java:122)
  at
 org.apache.wicket.pageStore.DefaultPageStore.deserializePage(DefaultPageStore.java:396)
  at
 org.apache.wicket.pageStore.DefaultPageStore.getPage(DefaultPageStore.java:135)
  at
 org.apache.wicket.page.PageStoreManager$SessionEntry.getPage(PageStoreManager.java:203)
  at
 org.apache.wicket.page.PageStoreManager$PersistentRequestAdapter.getPage(PageStoreManager.java:360)
  at
 org.apache.wicket.page.AbstractPageManager.getPage(AbstractPageManager.java:107)

 [1]: https://issues.apache.org/jira/browse/WICKET-4785

 Mit freundlichen Grüßen,

 Thorsten Schöning

 --
 Thorsten Schöning   E-Mail: thorsten.schoen...@am-soft.de
 AM-SoFT IT-Systeme  http://www.AM-SoFT.de/

 Telefon...05151-  9468- 55
 Fax...05151-  9468- 88
 Mobil..0178-8 9468- 04

 AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
 AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow


 -
 To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
 For additional commands, e-mail: users-h...@wicket.apache.org




Re: Bes practice for deployment to avoid ClassNotFoundException

2014-11-23 Thread Thorsten Schöning
Guten Tag Martin Grigorov,
am Sonntag, 23. November 2014 um 11:22 schrieben Sie:

 You are experiencing Tomcat Session Persistence -
 http://tomcat.apache.org/tomcat-7.0-doc/config/manager.html#Persistence_Across_Restarts
 Just disable it for development to avoid such kind of problems.

But the exception clearly comes from wicket's page store, I already
found the code where the exception is captured and rethrown as
RuntimeException. I really doubt this is a problem of the Tomcat.

 122: return ois.readObject();
 at 
 org.apache.wicket.serialize.java.JavaSerializer.deserialize(JavaSerializer.java:122)
 java.lang.RuntimeException: Could not deserialize object from byte[]
 throw new RuntimeException(Could not deserialize object from byte[], cnfx);

Additionally, deactivating this feature for development only in Tomcat
wouldn't change anything, if I update the production system after
refactoring I would get the same error there of course.

From looking at the code I think what I would need to do instead is
create my own delegating serializer, which encapsulates the default
Wicket one, catches the problematic exception and returns null instead
of throwing the exception. It looks like that all code mentioned in
the stacktrace is using null if things are not found or such and would
ultimately lead to PageProvider.isNewPageInstance believing that a new
instance is needed:

 public boolean isNewPageInstance()
 {
boolean isNew = pageInstance == null;
   if (isNew  pageId != null)
   {
   IRequestablePage storedPageInstance = 
 getStoredPage(pageId);
   if (storedPageInstance != null)
   {
   pageInstance = 
 storedPageInstance;
   isNew = false;
   }
   }
 
   return isNew;
 }

storedPageInstance would simply be null when using my own serializer.
From my opinion this should be a at least configurable default
behavior in Wicket anyways, I don't see how else it can handle things
like refactoring with using it's own page store of serialized Java
classes. It must ignore ClassNotFoundException in such cases somehow
because it's a perfectly valid situation.

Mit freundlichen Grüßen,

Thorsten Schöning

-- 
Thorsten Schöning   E-Mail: thorsten.schoen...@am-soft.de
AM-SoFT IT-Systeme  http://www.AM-SoFT.de/

Telefon...05151-  9468- 55
Fax...05151-  9468- 88
Mobil..0178-8 9468- 04

AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow


-
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org



Re: Bes practice for deployment to avoid ClassNotFoundException

2014-11-23 Thread Martin Grigorov
Hallo Thorsten,

On Sun, Nov 23, 2014 at 1:02 PM, Thorsten Schöning tschoen...@am-soft.de
wrote:

 Guten Tag Martin Grigorov,
 am Sonntag, 23. November 2014 um 11:22 schrieben Sie:

  You are experiencing Tomcat Session Persistence -
 
 http://tomcat.apache.org/tomcat-7.0-doc/config/manager.html#Persistence_Across_Restarts
  Just disable it for development to avoid such kind of problems.

 But the exception clearly comes from wicket's page store, I already
 found the code where the exception is captured and rethrown as
 RuntimeException. I really doubt this is a problem of the Tomcat.


Here is what happens:
1) Wicket stores a Page into the HTTP session
2) Tomcat shuts down and persists all HTTP sessions into the disk
3) you deploy and new version of the app (with incompatible changes in the
classes, like renaming a class)
4) you start Tomcat and it tries to load the persisted sessions
4.1) Since Wicket stores its data
as org.apache.wicket.pageStore.DefaultPageStore.SerializedPage (a triple of
pageId (int) / sessionId (String) / pageData (byte[])) it is Wicket's job
to deserialize the pageData byte[] to SomePage instance. That's why you
think Wicket is to blame here. But even if there was a Page stored as an
attribute in the http session then Tomcat would fail the same way since
there is no such class in the webapp class loader anymore.

In both cases I think Tomcat will just log an error that an old session
cannot be loaded and continue with the start of the application.
Am I correct or Tomcat fails to start ?
Please paste the complete exception if I am not correct.



  122: return ois.readObject();
  at
 org.apache.wicket.serialize.java.JavaSerializer.deserialize(JavaSerializer.java:122)
  java.lang.RuntimeException: Could not deserialize object from byte[]
  throw new RuntimeException(Could not deserialize object from byte[],
 cnfx);

 Additionally, deactivating this feature for development only in Tomcat
 wouldn't change anything, if I update the production system after
 refactoring I would get the same error there of course.


No.
Wicket cleans up its data storages at session invalidation time (per
sessionId) or at application stop (for all sessions).
So there is nothing to load at start time and no knowledge about old stuff.



 From looking at the code I think what I would need to do instead is
 create my own delegating serializer, which encapsulates the default
 Wicket one, catches the problematic exception and returns null instead
 of throwing the exception. It looks like that all code mentioned in
 the stacktrace is using null if things are not found or such and would
 ultimately lead to PageProvider.isNewPageInstance believing that a new
 instance is needed:

  public boolean isNewPageInstance()
  {
 boolean isNew = pageInstance == null;
if (isNew  pageId != null)
{
IRequestablePage storedPageInstance =
 getStoredPage(pageId);
if (storedPageInstance != null)
{
pageInstance =
 storedPageInstance;
isNew = false;
}
}
 
return isNew;
  }

 storedPageInstance would simply be null when using my own serializer.
 From my opinion this should be a at least configurable default
 behavior in Wicket anyways, I don't see how else it can handle things
 like refactoring with using it's own page store of serialized Java
 classes. It must ignore ClassNotFoundException in such cases somehow
 because it's a perfectly valid situation.

 Mit freundlichen Grüßen,

 Thorsten Schöning

 --
 Thorsten Schöning   E-Mail: thorsten.schoen...@am-soft.de
 AM-SoFT IT-Systeme  http://www.AM-SoFT.de/

 Telefon...05151-  9468- 55
 Fax...05151-  9468- 88
 Mobil..0178-8 9468- 04

 AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
 AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow


 -
 To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
 For additional commands, e-mail: users-h...@wicket.apache.org




Re: Bes practice for deployment to avoid ClassNotFoundException

2014-11-23 Thread Thorsten Schöning
Guten Tag Martin Grigorov,
am Sonntag, 23. November 2014 um 12:20 schrieben Sie:

 4) you start Tomcat and it tries to load the persisted sessions
 4.1) Since Wicket stores its data
 as org.apache.wicket.pageStore.DefaultPageStore.SerializedPage (a triple of
 pageId (int) / sessionId (String) / pageData (byte[])) it is Wicket's job
 to deserialize the pageData byte[] to SomePage instance.

I'm pretty sure this is not what is happening and the provided
stacktrace makes clear that Wicket is doing everything. The only thing 
where Tomcat comes into play is the actual class loading itself, but
that's correct of course because Tomcat provides at least a parent
classloader to use. Wicket does serialize and deserialize the pages on
it's own just because of an incoming request.

 In both cases I think Tomcat will just log an error that an old session
 cannot be loaded and continue with the start of the application.
 Am I correct or Tomcat fails to start ?

Tomcat doesn't log anything and just succeeds to start, at least I
didn't find any log messages from Tomcat in Eclipse and requesting
other pages from Wicket after ClassNotFoundException succeeded as
well. Simply because there were newly created.

 Please paste the complete exception if I am not correct.

I attached the saved HTML file with everything Wicket told me, but
there's nothing more interesting than what I've already posted in my
fist mail.

 No.
 Wicket cleans up its data storages at session invalidation time (per
 sessionId) or at application stop (for all sessions).
 So there is nothing to load at start time and no knowledge about old stuff.

If that was true, Tomcat wouldn't be able to run into any problems with
a serialized session as well because there wouldn't be anything left
from Wicket to serialize. Or does Wicket only clear persistent storage
in files, but retains it's session data? That wouldn't make much sense
to me, because the problem would remain.

Besides that, I just tested with a request for some page: Wicket did
create a folder to save the serialized page during runtime of Tomcat.
So I stopped Tomcat to see if the folder gets deleted or such and it
didn't, instead Wicket created the additional file DiskDataStoreIndex
as serialized Java object, which clearly contains the path to the
serialized page. Afterwards I restarted Tomcat, issued another
request, DiskDataStoreIndex got read (monitored using ProcMon) and
afterwards deleted. The only thing I didn't see was reading the former
persisted page... But the former behavior corresponds to the code:
DiskDataStore.destroy doesn't just empty anything, data gets persisted
in a file and there's even a load method to load the data.

So the only interesting thing is if pages are used as well after the
restart or not: Application.internalDestroy does call a lot of destroy
methods, but DiskDataStore.destroy e.g. is implemented to persist
data, while other caches seem to really be just cleared, like that for
markup.

Which is the codepath where I can see that persisted pages get
forgotten on shutdown of Wicket? Following Application.internalDestroy
and it's call of internalGetPageManager().destroy(); lead me to
DiskDataStore which clearly doesn't destroy the data...

A simple explanation for my problem could as well be that I didn't
restart the Tomcat and that during it's restart it works like you say,
but in that case I want to make sure that really session and
persistent page store are abandoned and currently it doesn't look
so...

Mit freundlichen Grüßen,

Thorsten Schöning

-- 
Thorsten Schöning   E-Mail: thorsten.schoen...@am-soft.de
AM-SoFT IT-Systeme  http://www.AM-SoFT.de/

Telefon...05151-  9468- 55
Fax...05151-  9468- 88
Mobil..0178-8 9468- 04

AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow

-
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org

Bes practice for deployment to avoid ClassNotFoundException

2014-11-21 Thread Thorsten Schöning
Hi all,

I'm new to wicket and just recently started to use it for a new web
app for one of our projects. Today I came across a similar issue like
described in [1], a ClassNotFoundException during deserialization of a
page. The interesting part about this in my mind is, that the
mentioned missing class was missing for a good reason: I simply
refactored a bit and renamed the class, redeployed and restarted my
Tomcat. This looks like a normal use case to me, but is something I
didn't thought of when I've read through the docs because.

My deployment is very simple: I check out a SVN working copy with a
pre-configured tag containing the whole application once and
afterwards just need to merge/update and stop/start the web
server/app.

How is deployment supposed to work in Wicket after I have refactored
or otherwise changed my classes regarding cached and serialized pages?
Is there anything I need to tell wicket to clear its caches on each
deployment or ignore those or whatever? Am I forced to not delete once
deployed classes for a fair period of time? That would be a litte
nightmare... Or is there any other issue I ran into I should have
avoided?

Obviously others do deploy their Wicket apps as well, so I hope you
have some input on how to avoid the problem I've ran into. Thanks!

The important parts of the stacktrace:

java.lang.ClassNotFoundException: 
de.am_soft.util.frontend.wicket.markup.link.LogoutLink
 at 
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1720)
 at 
org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1571)
 at java.lang.Class.forName0(Native Method)
 at java.lang.Class.forName(Unknown Source)
 at 
org.apache.wicket.application.AbstractClassResolver.resolveClass(AbstractClassResolver.java:108)
 at 
org.apache.wicket.serialize.java.JavaSerializer$ClassResolverObjectInputStream.resolveClass(JavaSerializer.java:218)
 at java.io.ObjectInputStream.[...]
 [...]
 at 
org.apache.wicket.serialize.java.JavaSerializer.deserialize(JavaSerializer.java:122)
 at 
org.apache.wicket.pageStore.DefaultPageStore.deserializePage(DefaultPageStore.java:396)
 at 
org.apache.wicket.pageStore.DefaultPageStore.getPage(DefaultPageStore.java:135)
 at 
org.apache.wicket.page.PageStoreManager$SessionEntry.getPage(PageStoreManager.java:203)
 at 
org.apache.wicket.page.PageStoreManager$PersistentRequestAdapter.getPage(PageStoreManager.java:360)
 at 
org.apache.wicket.page.AbstractPageManager.getPage(AbstractPageManager.java:107)

[1]: https://issues.apache.org/jira/browse/WICKET-4785

Mit freundlichen Grüßen,

Thorsten Schöning

-- 
Thorsten Schöning   E-Mail: thorsten.schoen...@am-soft.de
AM-SoFT IT-Systeme  http://www.AM-SoFT.de/

Telefon...05151-  9468- 55
Fax...05151-  9468- 88
Mobil..0178-8 9468- 04

AM-SoFT GmbH IT-Systeme, Brandenburger Str. 7c, 31789 Hameln
AG Hannover HRB 207 694 - Geschäftsführer: Andreas Muchow


-
To unsubscribe, e-mail: users-unsubscr...@wicket.apache.org
For additional commands, e-mail: users-h...@wicket.apache.org