Re: Tomcat class reloading and the development cycle

2007-05-14 Thread Matt Larson

Inge,

You are right--this is much improved in Tap 5.  However, as far as I 
understand (asked Howard about it at JavaOne) this works by using some 
custom classloader functionality that handles reloading specific 
Tapestry packages for your pages and components.  The code checks for 
changes on some specified interval and reloads the changed classes.  In 
Howard's demo at JavaOne all changes looked basically instantaneous.


I'm sorry that's not really any help--just know that there's some 
special code to make this happen in Tap 5 that Tap 4 doesn't have.  I 
have exactly the same problem with Tap 4 in Tomcat, and it is a huge 
pain due especially to hibernate intialization.  A fast machine makes it 
less painful, but that's about it...


Maybe others have suggestions for Tap 4.

Matt

Inge Solvoll wrote:

Hi

I would like to shorten the time spent from changing a class file to
actually seeing the change in the browser.

My problem now is that if I set my Tomcat application to reloadable, it
reloads all servlets (including struts, tapestry and more) when I 
change a
class file. This takes at least 5-10 secs. Then on the first page 
access to

tapestry, it spends another 5 secs (at least) initializing tapestry,
hivemind, tacos and so on. How can I avoid this reloading and still get
tomcat to pick up the newest version of my class files?

I've seen Howard's demos of Tapestry 5, where he hits reload in the 
browser

1 sec after a class change, and it loads in the browser within the same
second. How can I achieve this on my system?

I've seen people referring to the following hack on an application with
reloadable=false, but I'm thinking there has to be a simpler way?
- Delete the class file
- Access the page, tomcat throws an exception because of missing class
- Compile the class
- Reload the page, tomcat picks up the new class file

I suppose this is more of a Tomcat question than a Tapestry question, but
it's heavily affecting the productivity of tapestry developers...


Regards

Inge




-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Create error page T4.0.2

2007-04-27 Thread Matt Larson
The absolute easiest thing to do is to create a page named Exception 
(.html and .page).  This will then be picked up automatically as the 
Exception page.  Unfortunately you may have to do some build script 
magic to differentiate between production and development.  I have my 
production Exception page log the error to a log file using Tapestry's 
exception display code but just display something generic for the user.


You should be able to override hivemind settings to accomplish this if 
you want to call you page something else. 

For more info there are various discussions of this in the email list 
archives.


Matt

Josh Joy wrote:

Hi,

Sorry, though I've tried looking for the documentation
though I probably 
just missed it...

If tapestry experiences an error, for example I have
an invalid HTML 
template so it will have a parsing error, or perhaps I
have an 
application error, Tapestry will display a very nice
exception page with 
stack trace and various other info. This is helpful
for development, 
though for production how can I define my own error

page?

Thanks,
Josh

-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

  



-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Session invalidate question

2007-04-25 Thread Matt Larson

Peter,

I have encountered a similar problem, and I think that the problem was 
not in my code, but in where I was doing the session.invalidate().  In 
trying to remove a cookie on logout, I found that I needed to do the 
invalidation in an IEngineService.  You can then do a redirect to 
whatever page you want at that time. 

This may not fit your needs, but what I did was to create my own service 
via this configuration point in Hivemind:


service-point id=LogoutService 
interface=org.apache.tapestry.engine.IEngineService

   invoke-factory
   construct class=tapestry.LogoutService
   set-service property=request 
service-id=tapestry.globals.HttpServletRequest /
   set-service property=response 
service-id=tapestry.globals.HttpServletResponse /
   set-object property=servletPath 
value=app-property:org.apache.tapestry.servlet-path /
   set-object property=linkFactory 
value=infrastructure:linkFactory /

   /construct
   /invoke-factory
   /service-point

contribution configuration-id=tapestry.services.FactoryServices
   service name=logout object=service:LogoutService /
   /contribution

Then in my service method of my engine class, I did the cookie handling 
and the session.invalidate() using parts of the code from Tapestry's 
logout service:


public void service(IRequestCycle cycle) throws IOException {
   HttpSession session = _request.getSession(false);

   if (session != null) {
   try {
   session.invalidate();
   } catch (IllegalStateException ex) {
   logger.warn(Exception thrown invalidating 
HttpSession., ex);


   // Otherwise, ignore it.
   }
   }

   [do cookie handling]

   _response.sendRedirect(page_to_redirect_to.html);
   }

Hope that helps.

Cheers,
Matt

Peter Stavrinides wrote:

Hi Everyone,

I want to redirect to a page (other than my home page) and invalidate 
the session there.


After i call invalidate I get an exception that states the session has 
already been invalidated, even if I invalidate the session on the 
target page in pageEndRender. The question is how do I delay the 
invalidate on the target page long enough to prevent this exception.


For Example:

public void pageEndRender(PageEvent e) {
   if (getRequest().getSession(false) != null){
   try {
   //some clean up code here
   getRequest().getSession(false).invalidate();
   } catch (Exception ex){
//XXX -Exception still appears at runtime in tomcat 
which cannot be caught

   }
   }
   }

Produces The following  stack trace:
WARN - Exception during post-request cleanup: setAttribute: Session 
already invalidated
- org.apache.tapestry.error.RequestExceptionReporterImpl (45) 
java.lang.IllegalStateException: setAttribute: Session already 
invalidated
   at 
org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1251) 

   at 
org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1233) 

   at 
org.apache.catalina.session.StandardSessionFacade.setAttribute(StandardSessionFacade.java:129) 

   at 
org.apache.tapestry.web.ServletWebSession.setAttribute(ServletWebSession.java:62) 

   at 
org.apache.tapestry.engine.state.SessionScopeManager.store(SessionScopeManager.java:90) 

   at 
$StateObjectPersistenceManager_1122965794b.store($StateObjectPersistenceManager_1122965794b.java) 

   at 
org.apache.tapestry.engine.state.StateObjectManagerImpl.store(StateObjectManagerImpl.java:56) 

   at 
org.apache.tapestry.engine.state.ApplicationStateManagerImpl.flush(ApplicationStateManagerImpl.java:87) 

   at 
$ApplicationStateManager_1122965778e.flush($ApplicationStateManager_1122965778e.java) 

   at 
$ApplicationStateManager_1122965778f.flush($ApplicationStateManager_1122965778f.java) 

   at 
org.apache.tapestry.engine.AbstractEngine.service(AbstractEngine.java:283) 

   at 
org.apache.tapestry.services.impl.InvokeEngineTerminator.service(InvokeEngineTerminator.java:54) 

   at 
$WebRequestServicer_1122965784e.service($WebRequestServicer_112296578


etc

Thanks
Peter




-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]




-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Re: Tap 4.1.1 problem: async direct link returns empty ajax response

2007-04-13 Thread Matt Larson
Sorry for the long interval on this discussion--needed time to try to 
understand this problem a bit more.  I am wondering if Jesse or anyone 
else can shed a little more light on the empty ajax response problem I 
am having, which is a showstopper for my app.


Using the example below (div jwcid=[EMAIL PROTECTED] ) did not work to add 
the div1 component to the list of components returned by 
getPage().getComponents(), which is why the 
page.components.div1.clientId expression fails.  What I found was that 
@Any components are not added to the component list if they are inside 
components themselves.  If I put an @Any component on the main container 
page with an ID, it showed up in the page.components list, but not if it 
was within my component. 

So I guess the question is, is there a way to get the div 
jwcid=[EMAIL PROTECTED]  component to show up in the page.components list? And 
if it did show up there, would it be found in the list that is returned 
by the _cycle.renderStackIterator() in the DojoAjaxResponseBuilder class 
that I think is doing this work? I see that the method


boolean contains(IComponent target, String id)

looks through the list returned by renderStackIterator() to try and find 
a matching clientId, so I guess that is what is failing in my case.


Also, I am still wondering why this works so nicely when I go directly 
to the containing page (it's my Home page) but not if I use a DirectLink 
with a listener to update some values in my Home page and then rerender 
it?  Is there a call I can make to ensure that the Home page thinks it 
was called as Home.html rather than through a DirectLink?  I think it 
needs to do some kind of setup that it doesn't do via a DirectLink.


Thanks for the help,
Matt

PS. Some named components within other components did show up in the 
page.components list, such as a @For component I used in my .jwc file to 
see the page.components list:


component id=listComponents type=For
   binding name=source value=ognl:page.components.keySet()/
   binding name=value value=ognl:myComponent/
/component

Searching through the list archives a bit, I saw a few suggestions that 
this was related to the fact that @For extends the FormComponent class, 
which sounded plausible but I did not experiment with this enough to 
confirm.



Jesse Kuhnert wrote:

No things should still work the same with 4.1.1. .(but upgrading might
be a good idea either way)

The error you got means that you don't have a component defined in
your page with an id of div1. Your example before on how you were
defining your div blocks was incorrect and I provided an example of
how to do it...ie :

div jwcid=[EMAIL PROTECTED] 

It'll work if you define your block that way.

On 4/10/07, Matt Larson [EMAIL PROTECTED] wrote:

Hi Jesse,

I did try this approach previously, thinking OGNL would use the Map key
as a property like in your example (I think that's what it's doing in
your example?).  But following your example very closely, I get this
exception:

Unable to read OGNL expression...source is null for getProperty(null,
clientId)

(source is
updateComponents=ognl:{page.components.div1.clientId,page.components.div2.clientId}) 



I think was partly the cause of my confusion before :).  I couldn't see
how that expression could work, and it appears to be dying at the
div1/div2 step.

Now I'm suspecting I need to upgrade to the latest Tap 4.x source and
the latest OGNL, which I know you have done a lot of work on.  Do I need
those to make your example work?

Thanks again,
Matt

Jesse Kuhnert wrote:
 You want to do something like this instead for your divs:

 div jwcid=[EMAIL PROTECTED] 

 Then your updateComponents statement becomes

 
updateComponents=ognl:{page.components.foo.clientId,page.components.someOtherDiv.clientId} 




 On 4/10/07, Matt Larson [EMAIL PROTECTED] wrote:
 Jesse,

 Thanks for your response.  This feels like the problem, that the 
IDs on

 the div tags are not being matched.  However due to my lack of
 knowledge about Tapestry's internals, I haven't been able to 
implement

 your suggestion.

 What I can't figure out is how to get the clientId out of the OGNL
 expression you used (page.components.div1.clientId).  I had a look at
 what is in the Map that page.components returns, and I don't see
 anything that looks like my components' clientIds in either the
 component.getClientId() or in the set of keys of the components Map.
 How do I get the clientId from a component named div1, given 
that I'm

 in a For loop as well?  I'm confused about what the updateComponents
 parameter in the DirectLink component should take instead of the 
IDs on

 the divs since I can't seem to retrieve the clientIds.

 Here is what I am doing now, using components with IDs to try to 
follow

 your example:

 In the .jwc file I have two components for divs that look like 
this:


 component id=div1 type=Any
 binding name=id value=ognl:'ratingStars' + hunch.id/
 /component

Re: Tap 4.1.1 problem: async direct link returns empty ajax response

2007-04-10 Thread Matt Larson

Jesse,

Thanks for your response.  This feels like the problem, that the IDs on 
the div tags are not being matched.  However due to my lack of 
knowledge about Tapestry's internals, I haven't been able to implement 
your suggestion.


What I can't figure out is how to get the clientId out of the OGNL 
expression you used (page.components.div1.clientId).  I had a look at 
what is in the Map that page.components returns, and I don't see 
anything that looks like my components' clientIds in either the 
component.getClientId() or in the set of keys of the components Map.  
How do I get the clientId from a component named div1, given that I'm 
in a For loop as well?  I'm confused about what the updateComponents 
parameter in the DirectLink component should take instead of the IDs on 
the divs since I can't seem to retrieve the clientIds.


Here is what I am doing now, using components with IDs to try to follow 
your example:


In the .jwc file I have two components for divs that look like this:

component id=div1 type=Any
   binding name=id value=ognl:'ratingStars' + hunch.id/   
/component
  
   component id=div2 type=Any
   binding name=id value=ognl:'ratingImage' + hunch.id/   
   /component


These are used to display the divs in the .html file, which will be 
updated by the asynchronous DirectLink.


Then in my DirectLink component:

a jwcid=@DirectLink
   listener=listener:submitRatingAjax
   async=ognl:true
   updateComponents=ognl:{'ratingImage' + 
hunch.id,'ratingStars' + hunch.id}.../a


If you or anyone else can help direct me to the right way to get the 
clientIds for components for use within the updateComponents parameter, 
that would be greatly appreciated.  I have looked at the source code and 
APIs but so far that hasn't cleared it up.


Cheers,
Matt

Jesse Kuhnert wrote:

Hmm... You can try adding some of the server side logging stuff
outlined here: http://tapestry.apache.org/tapestry4.1/ajax/debugging.html
.

I'm guessing that the clientId of the div's you are trying to update
doesn't match on these responses.

One thing you could do as a test is if you currently do something like:

a jwcid=@DirectLink updateComponents=div1,div2

change it to :

a jwcid=@DirectLink
updateComponents=ognl:{page.components.div1.clientId,
page.components.div2.clientId}

I noticed something similar to this recently and probably need to make
updateComponents=a,b automatically use the clientId and not
componentId to match id's on the response.

Hopefully that's the problem.

On 4/8/07, Matt Larson [EMAIL PROTECTED] wrote:

I have just run into a problem that I think is probably a bug, but may
be something that I am doing wrong.  It's definitely a showstopper in my
app, though.

I have a component that allows users to rate something via the normal
kind of stars rating.  After a user clicks a star the overall rating
of the object is calculated and displayed as a graphic.  I use a
component that employs an asynchronous DirectLink to do this, with each
star having a different value on submit, and it works quite nicely.  I
have this custom component on two different pages and I can submit
ratings on both.

However, I just added pagination, and as soon as you move off of the
home page via the next pagination link, the DirectLink for ratings no
longer returns anything. The pagination works using the standard kind of
start from parameter, which calls a listener that simply does
setStartFrom(int startFrom) and then lets the pageBeginRender() method
calculate the objects to display.

I do know the reason that the ratings no longer show the updated
graphic--the AjaxResponse just returns empty tags, with no errors
reported at all (had a look at this with firebug):

ajax-response/ajax-response

The actual link is firing just fine, and all of the server side
processing happens as my logs show. It's just that the ajax response is
empty when it should include new HTML for the divs to be updated.  It
seems like there is some kind of setup that happens when you go directly
to Home.html and click the rating link, but not when I've gone to the
home page via a DirectLink.  I cannot see what would be different, since
my pageBeginRender() method is called, and everything else happens just
like it should in the component and in the page.

If anyone has run into this before or has an idea regarding what this
might cause an async DirectLink to return nothing in some cases, please
let me know.  The pagination is a major part of my app, and users need
to be able to submit ratings no matter which page they are on, so I am
kind of dead in the water until I get this fixed.  Next step is to spend
quality time with the source code, but if anyone has a better idea
before I take that time...

Cheers,
Matt




-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED

Re: Tap 4.1.1 problem: async direct link returns empty ajax response

2007-04-10 Thread Matt Larson

Hi Jesse,

I did try this approach previously, thinking OGNL would use the Map key 
as a property like in your example (I think that's what it's doing in 
your example?).  But following your example very closely, I get this 
exception:


Unable to read OGNL expression...source is null for getProperty(null, 
clientId)


(source is 
updateComponents=ognl:{page.components.div1.clientId,page.components.div2.clientId})


I think was partly the cause of my confusion before :).  I couldn't see 
how that expression could work, and it appears to be dying at the 
div1/div2 step.


Now I'm suspecting I need to upgrade to the latest Tap 4.x source and 
the latest OGNL, which I know you have done a lot of work on.  Do I need 
those to make your example work?


Thanks again,
Matt

Jesse Kuhnert wrote:

You want to do something like this instead for your divs:

div jwcid=[EMAIL PROTECTED] 

Then your updateComponents statement becomes

updateComponents=ognl:{page.components.foo.clientId,page.components.someOtherDiv.clientId} 



On 4/10/07, Matt Larson [EMAIL PROTECTED] wrote:

Jesse,

Thanks for your response.  This feels like the problem, that the IDs on
the div tags are not being matched.  However due to my lack of
knowledge about Tapestry's internals, I haven't been able to implement
your suggestion.

What I can't figure out is how to get the clientId out of the OGNL
expression you used (page.components.div1.clientId).  I had a look at
what is in the Map that page.components returns, and I don't see
anything that looks like my components' clientIds in either the
component.getClientId() or in the set of keys of the components Map.
How do I get the clientId from a component named div1, given that I'm
in a For loop as well?  I'm confused about what the updateComponents
parameter in the DirectLink component should take instead of the IDs on
the divs since I can't seem to retrieve the clientIds.

Here is what I am doing now, using components with IDs to try to follow
your example:

In the .jwc file I have two components for divs that look like this:

component id=div1 type=Any
binding name=id value=ognl:'ratingStars' + hunch.id/
/component

component id=div2 type=Any
binding name=id value=ognl:'ratingImage' + hunch.id/
/component

These are used to display the divs in the .html file, which will be
updated by the asynchronous DirectLink.

Then in my DirectLink component:

a jwcid=@DirectLink
listener=listener:submitRatingAjax
async=ognl:true
updateComponents=ognl:{'ratingImage' +
hunch.id,'ratingStars' + hunch.id}.../a

If you or anyone else can help direct me to the right way to get the
clientIds for components for use within the updateComponents parameter,
that would be greatly appreciated.  I have looked at the source code and
APIs but so far that hasn't cleared it up.

Cheers,
Matt

Jesse Kuhnert wrote:
 Hmm... You can try adding some of the server side logging stuff
 outlined here: 
http://tapestry.apache.org/tapestry4.1/ajax/debugging.html

 .

 I'm guessing that the clientId of the div's you are trying to update
 doesn't match on these responses.

 One thing you could do as a test is if you currently do something 
like:


 a jwcid=@DirectLink updateComponents=div1,div2

 change it to :

 a jwcid=@DirectLink
 updateComponents=ognl:{page.components.div1.clientId,
 page.components.div2.clientId}

 I noticed something similar to this recently and probably need to make
 updateComponents=a,b automatically use the clientId and not
 componentId to match id's on the response.

 Hopefully that's the problem.

 On 4/8/07, Matt Larson [EMAIL PROTECTED] wrote:
 I have just run into a problem that I think is probably a bug, but 
may
 be something that I am doing wrong.  It's definitely a showstopper 
in my

 app, though.

 I have a component that allows users to rate something via the normal
 kind of stars rating.  After a user clicks a star the overall 
rating

 of the object is calculated and displayed as a graphic.  I use a
 component that employs an asynchronous DirectLink to do this, with 
each
 star having a different value on submit, and it works quite 
nicely.  I

 have this custom component on two different pages and I can submit
 ratings on both.

 However, I just added pagination, and as soon as you move off of the
 home page via the next pagination link, the DirectLink for 
ratings no
 longer returns anything. The pagination works using the standard 
kind of

 start from parameter, which calls a listener that simply does
 setStartFrom(int startFrom) and then lets the pageBeginRender() 
method

 calculate the objects to display.

 I do know the reason that the ratings no longer show the updated
 graphic--the AjaxResponse just returns empty tags, with no errors
 reported at all (had a look at this with firebug):

 ajax-response/ajax-response

 The actual link is firing just fine, and all of the server side
 processing happens as my logs show. It's just

Tap 4.1.1 problem: async direct link returns empty ajax response

2007-04-08 Thread Matt Larson
I have just run into a problem that I think is probably a bug, but may 
be something that I am doing wrong.  It's definitely a showstopper in my 
app, though. 

I have a component that allows users to rate something via the normal 
kind of stars rating.  After a user clicks a star the overall rating 
of the object is calculated and displayed as a graphic.  I use a 
component that employs an asynchronous DirectLink to do this, with each 
star having a different value on submit, and it works quite nicely.  I 
have this custom component on two different pages and I can submit 
ratings on both.


However, I just added pagination, and as soon as you move off of the 
home page via the next pagination link, the DirectLink for ratings no 
longer returns anything. The pagination works using the standard kind of 
start from parameter, which calls a listener that simply does 
setStartFrom(int startFrom) and then lets the pageBeginRender() method 
calculate the objects to display.


I do know the reason that the ratings no longer show the updated 
graphic--the AjaxResponse just returns empty tags, with no errors 
reported at all (had a look at this with firebug):


ajax-response/ajax-response

The actual link is firing just fine, and all of the server side 
processing happens as my logs show. It's just that the ajax response is 
empty when it should include new HTML for the divs to be updated.  It 
seems like there is some kind of setup that happens when you go directly 
to Home.html and click the rating link, but not when I've gone to the 
home page via a DirectLink.  I cannot see what would be different, since 
my pageBeginRender() method is called, and everything else happens just 
like it should in the component and in the page.


If anyone has run into this before or has an idea regarding what this 
might cause an async DirectLink to return nothing in some cases, please 
let me know.  The pagination is a major part of my app, and users need 
to be able to submit ratings no matter which page they are on, so I am 
kind of dead in the water until I get this fixed.  Next step is to spend 
quality time with the source code, but if anyone has a better idea 
before I take that time...


Cheers,
Matt




-
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]