You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tapestry.apache.org by Jacob Mouka <jm...@gmail.com> on 2009/12/11 05:07:43 UTC

T5: handling form events in sub-components?

Hi all (apologies if this is really obvious, but I can't find the info  
in the docs/examples)

I have some sub-components (with form elements) in a form and I want  
to do some actions when the form is submitted. I've tried something like

	void onSubmit() {
		System.out.println("submitted");
	}

but it doesn't get called on the sub-components, only the parent  
component. What am I missing?

Thanks, Jacob

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5: handling form events in sub-components?

Posted by Jacob Mouka <jm...@gmail.com>.
Thanks Inge. I was hoping for a different answer, but this makes sense.

Jacob

On 11-Dec-09, at 4:02 AM, Inge Solvoll wrote:

> I struggled earlier with this. Components bubble up, not down. Your
> components won't be alerted that the form in your page was submitted.
>
> If you need form fields in components, you either have to put the  
> entire
> form in the component, or you need to avoid that the form fields  
> depend on
> form events.
>
> On Fri, Dec 11, 2009 at 6:06 AM, Benny Law <be...@gmail.com>  
> wrote:
>
>> Hi Jacob,
>>
>> It sounds like you have nested forms which is not allowed.
>>
>> Benny
>>
>> On Thu, Dec 10, 2009 at 11:07 PM, Jacob Mouka <jm...@gmail.com>  
>> wrote:
>>
>>> Hi all (apologies if this is really obvious, but I can't find the  
>>> info in
>>> the docs/examples)
>>>
>>> I have some sub-components (with form elements) in a form and I  
>>> want to
>> do
>>> some actions when the form is submitted. I've tried something like
>>>
>>>       void onSubmit() {
>>>               System.out.println("submitted");
>>>       }
>>>
>>> but it doesn't get called on the sub-components, only the parent
>> component.
>>> What am I missing?
>>>
>>> Thanks, Jacob
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
>>> For additional commands, e-mail: users-help@tapestry.apache.org
>>>
>>>
>>


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


RE: java.lang.AbstractMethodError - 5.1.0.5

Posted by Jim O'Callaghan <jc...@yahoo.co.uk>.
Hi Thiago,

Thanks for the response - comments below.

>Tapestry-IoC create proxies around your service implementations, so, when
>you @Inject UserEntityManager, the object your receive is proxy that
>implements UserEntityManager, not BaseEntityManager. This means that the
>proxy will invoke a method that returns IPersistentObject, not User.

This is the nub of the problem - the proxy implements UserEntityManager,
which by definition returns a User object for this particular method - not
explicitly a IPersistentObject as in your example, though the returned
object does implement IPersistentObject.  I thought that the StackTrace
might indicate that there is an exception in the ioc registry area that is
not being caught / reported properly. If the java.lang.AbstractMethodError
had a message that contained something indicating an unexpected return type
/ class cast issue etc. it would have been easier to pin down.

>> This is to reduce the need for explicit casting around the application.

>This doesn't seem right to me. You shouldn't rely on an specific
>implementation of a given interface. If you need, why return an interface
>in first place?

Agreed - this is just for convenience in a very context relevant area of the
system (user CRUD and other ops) - in other areas of the system the
IPersistentObject interface is used as a matter of course in place of Users
and other domain objects.

Regards,
Jim.



-----Original Message-----
From: Thiago H. de Paula Figueiredo [mailto:thiagohp@gmail.com]
Sent: 11 December 2009 12:39
To: Tapestry users
Subject: Re: java.lang.AbstractMethodError - 5.1.0.5


Em Fri, 11 Dec 2009 10:23:11 -0200, Jim O'Callaghan
<jc...@yahoo.co.uk> escreveu:

> Hi,

Hi!

> I have a service bound to an interface in the ioc registry.  The
> interface extends another interface and duplicates a method name and
> parameter list
> however the return type in the overridden method is a concrete class
> rather than an implementing interface, as specified in the super
> interface ex.:

Tapestry-IoC create proxies around your service implementations, so, when
you @Inject UserEntityManager, the object your receive is proxy that
implements UserEntityManager, not BaseEntityManager. This means that the
proxy will invoke a method that returns IPersistentObject, not User.

> This is to reduce the need for explicit casting around the application.

This doesn't seem right to me. You shouldn't rely on an specific
implementation of a given interface. If you need, why return an interface
in first place?

--
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da
Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: java.lang.AbstractMethodError - 5.1.0.5

Posted by "Thiago H. de Paula Figueiredo" <th...@gmail.com>.
Em Fri, 11 Dec 2009 10:23:11 -0200, Jim O'Callaghan  
<jc...@yahoo.co.uk> escreveu:

> Hi,

Hi!

> I have a service bound to an interface in the ioc registry.  The  
> interface extends another interface and duplicates a method name and  
> parameter list
> however the return type in the overridden method is a concrete class  
> rather than an implementing interface, as specified in the super  
> interface ex.:

Tapestry-IoC create proxies around your service implementations, so, when  
you @Inject UserEntityManager, the object your receive is proxy that  
implements UserEntityManager, not BaseEntityManager. This means that the  
proxy will invoke a method that returns IPersistentObject, not User.

> This is to reduce the need for explicit casting around the application.

This doesn't seem right to me. You shouldn't rely on an specific  
implementation of a given interface. If you need, why return an interface  
in first place?

-- 
Thiago H. de Paula Figueiredo
Independent Java, Apache Tapestry 5 and Hibernate consultant, developer,  
and instructor
Owner, software architect and developer, Ars Machina Tecnologia da  
Informação Ltda.
http://www.arsmachina.com.br

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


java.lang.AbstractMethodError - 5.1.0.5

Posted by Jim O'Callaghan <jc...@yahoo.co.uk>.
Hi,

I came across an interesting issue and thought I would post it so that it
might save someone else some time - I'm not sure if this is down to
questionable coding practise on my part causing the relevant classloader to
burp or Tapestry relevant ...  the stack trace is at the bottom of the mail.

I have a service bound to an interface in the ioc registry.  The interface
extends another interface and duplicates a method name and parameter list
however the return type in the overridden method is a concrete class rather
than an implementing interface, as specified in the super interface ex.:

public interface BaseEntityManager {
	public void IPersistentObject getEntity(IPersistentObjectKey key);
}
public interface UserEntityManager extends BaseEntityManager {
	public void User getEntity(IPersistentObjectKey key);
}

This is to reduce the need for explicit casting around the application.

Concrete class User implements IPersistentObject and extends
BasePersistentObject.  Service UserEntityManagerImpl implements
UserEntityManager and extends BaseEntityManagerImpl - it implements User
getEntity(IPersistentObjectKey key), which just calls the superclass
equivalent and casts the result to a User object.  Service
UserEntityManagerImpl is bound to the ioc registry against interface
UserEntityManager.  UserEntityManager is injected into a page and when the
getEntity method is called the stack trace below results.  If I use a
non-injected version of the same class via the interface (ex.
UserEntityManager uam = new UserEntityManagerImpl();, uam.getEntity(key)), I
get the expected (correct) result.  Is this possibly down to a JIT object
creation issue in the IOC Registry, or the duplicate method name causing
some ambiguity problem on the return type (concrete vs. interface)?

I don't need a solution to this, as I just altered my specialised interface
to have different method names - just thought it might help someone else
trying to trace through a lot of dynamically generated code.

[ERROR] TapestryModule.RequestExceptionHandler Processing of request failed
with uncaught exception:
$UserEntityManagerEX_1257d50b8e1.getExistingEntity(Lcom/<company>/<product>/
common/IPersistentObjectRef;)Lcom/<company>/<product>/entities/core/user/Use
r;
java.lang.AbstractMethodError:
$UserEntityManagerEX_1257d50b8e1.getExistingEntity(Lcom/<company>/<product>/
common/IPersistentObjectRef;)Lcom/<company>/<product>/entities/core/user/Use
r;
	at
com.<company>.<product>.pages.user.SearchUser.onShowDetails(SearchUser.java:
71)
	at
com.<company>.<product>.pages.user.SearchUser.dispatchComponentEvent(SearchU
ser.java)
	at
org.apache.tapestry5.internal.structure.ComponentPageElementImpl.dispatchEve
nt(ComponentPageElementImpl.java:902)
	at
org.apache.tapestry5.internal.structure.ComponentPageElementImpl.triggerCont
extEvent(ComponentPageElementImpl.java:1081)
	at
org.apache.tapestry5.internal.services.ComponentEventRequestHandlerImpl.hand
le(ComponentEventRequestHandlerImpl.java:75)
	at
org.apache.tapestry5.internal.services.ImmediateActionRenderResponseFilter.h
andle(ImmediateActionRenderResponseFilter.java:42)
	at
$ComponentEventRequestHandler_1257d50b98a.handle($ComponentEventRequestHandl
er_1257d50b98a.java)
	at
org.apache.tapestry5.internal.services.AjaxFilter.handle(AjaxFilter.java:42)
	at
$ComponentEventRequestHandler_1257d50b98a.handle($ComponentEventRequestHandl
er_1257d50b98a.java)
	at
org.apache.tapestry5.services.TapestryModule$36.handle(TapestryModule.java:2
164)
	at
$ComponentEventRequestHandler_1257d50b98a.handle($ComponentEventRequestHandl
er_1257d50b98a.java)
	at
$ComponentEventRequestHandler_1257d50b8b5.handle($ComponentEventRequestHandl
er_1257d50b8b5.java)
	at
org.apache.tapestry5.internal.services.ComponentRequestHandlerTerminator.han
dleComponentEvent(ComponentRequestHandlerTerminator.java:43)
	at
$ComponentRequestHandler_1257d50b8a9.handleComponentEvent($ComponentRequestH
andler_1257d50b8a9.java)
	at
org.apache.tapestry5.internal.services.ComponentEventDispatcher.dispatch(Com
ponentEventDispatcher.java:46)
	at $Dispatcher_1257d50b8ab.dispatch($Dispatcher_1257d50b8ab.java)
	at $Dispatcher_1257d50b8a2.dispatch($Dispatcher_1257d50b8a2.java)
	at
org.apache.tapestry5.services.TapestryModule$RequestHandlerTerminator.servic
e(TapestryModule.java:245)
	at
nu.localhost.tapestry5.springsecurity.services.internal.RequestFilterWrapper
$1.doFilter(RequestFilterWrapper.java:60)
	at
nu.localhost.tapestry5.springsecurity.services.internal.SpringSecurityExcept
ionTranslationFilter.doFilterHttp(SpringSecurityExceptionTranslationFilter.j
ava:100)
	at
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurity
Filter.java:53)
	at
nu.localhost.tapestry5.springsecurity.services.internal.RequestFilterWrapper
.service(RequestFilterWrapper.java:55)
	at $RequestHandler_1257d50b8a3.service($RequestHandler_1257d50b8a3.java)
	at
org.apache.tapestry5.internal.services.RequestErrorFilter.service(RequestErr
orFilter.java:26)
	at $RequestHandler_1257d50b8a3.service($RequestHandler_1257d50b8a3.java)
	at
org.apache.tapestry5.services.TapestryModule$4.service(TapestryModule.java:7
78)
	at $RequestHandler_1257d50b8a3.service($RequestHandler_1257d50b8a3.java)
	at
org.apache.tapestry5.services.TapestryModule$3.service(TapestryModule.java:7
67)
	at $RequestHandler_1257d50b8a3.service($RequestHandler_1257d50b8a3.java)
	at
org.apache.tapestry5.internal.services.StaticFilesFilter.service(StaticFiles
Filter.java:85)
	at $RequestHandler_1257d50b8a3.service($RequestHandler_1257d50b8a3.java)
	at
org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckF
orUpdatesFilter.java:90)
	at
org.apache.tapestry5.internal.services.CheckForUpdatesFilter$2.invoke(CheckF
orUpdatesFilter.java:81)
	at
org.apache.tapestry5.ioc.internal.util.ConcurrentBarrier.withRead(Concurrent
Barrier.java:85)
	at
org.apache.tapestry5.internal.services.CheckForUpdatesFilter.service(CheckFo
rUpdatesFilter.java:103)
	at $RequestHandler_1257d50b8a3.service($RequestHandler_1257d50b8a3.java)
	at $RequestHandler_1257d50b896.service($RequestHandler_1257d50b896.java)
	at
org.apache.tapestry5.services.TapestryModule$HttpServletRequestHandlerTermin
ator.service(TapestryModule.java:197)
	at
org.apache.tapestry5.internal.gzip.GZipFilter.service(GZipFilter.java:53)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
org.apache.tapestry5.internal.services.IgnoredPathsFilter.service(IgnoredPat
hsFilter.java:62)
	at
$HttpServletRequestFilter_1257d50b895.service($HttpServletRequestFilter_1257
d50b895.java)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper$1.doFilter(HttpServletRequestFilterWrapper.java:56)
	at
org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(
FilterSecurityInterceptor.java:109)
	at
org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilte
r(FilterSecurityInterceptor.java:83)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper.service(HttpServletRequestFilterWrapper.java:52)
	at
$HttpServletRequestFilter_1257d50b892.service($HttpServletRequestFilter_1257
d50b892.java)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper$1.doFilter(HttpServletRequestFilterWrapper.java:56)
	at
nu.localhost.tapestry5.springsecurity.services.internal.SpringSecurityExcept
ionTranslationFilter.doFilterHttp(SpringSecurityExceptionTranslationFilter.j
ava:100)
	at
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurity
Filter.java:53)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper.service(HttpServletRequestFilterWrapper.java:52)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper$1.doFilter(HttpServletRequestFilterWrapper.java:56)
	at
org.springframework.security.providers.anonymous.AnonymousProcessingFilter.d
oFilterHttp(AnonymousProcessingFilter.java:105)
	at
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurity
Filter.java:53)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper.service(HttpServletRequestFilterWrapper.java:52)
	at
$HttpServletRequestFilter_1257d50b891.service($HttpServletRequestFilter_1257
d50b891.java)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper$1.doFilter(HttpServletRequestFilterWrapper.java:56)
	at
org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter
.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
	at
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurity
Filter.java:53)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper.service(HttpServletRequestFilterWrapper.java:52)
	at
$HttpServletRequestFilter_1257d50b890.service($HttpServletRequestFilter_1257
d50b890.java)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper$1.doFilter(HttpServletRequestFilterWrapper.java:56)
	at
org.springframework.security.ui.rememberme.RememberMeProcessingFilter.doFilt
erHttp(RememberMeProcessingFilter.java:109)
	at
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurity
Filter.java:53)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper.service(HttpServletRequestFilterWrapper.java:52)
	at
$HttpServletRequestFilter_1257d50b88f.service($HttpServletRequestFilter_1257
d50b88f.java)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper$1.doFilter(HttpServletRequestFilterWrapper.java:56)
	at
org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(Abstra
ctProcessingFilter.java:277)
	at
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurity
Filter.java:53)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper.service(HttpServletRequestFilterWrapper.java:52)
	at
$HttpServletRequestFilter_1257d50b88e.service($HttpServletRequestFilter_1257
d50b88e.java)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper$1.doFilter(HttpServletRequestFilterWrapper.java:56)
	at
org.springframework.security.context.HttpSessionContextIntegrationFilter.doF
ilterHttp(HttpSessionContextIntegrationFilter.java:235)
	at
org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurity
Filter.java:53)
	at
nu.localhost.tapestry5.springsecurity.services.internal.HttpServletRequestFi
lterWrapper.service(HttpServletRequestFilterWrapper.java:52)
	at
$HttpServletRequestFilter_1257d50b88d.service($HttpServletRequestFilter_1257
d50b88d.java)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
org.apache.tapestry5.services.TapestryModule$2.service(TapestryModule.java:7
26)
	at
$HttpServletRequestHandler_1257d50b898.service($HttpServletRequestHandler_12
57d50b898.java)
	at
$HttpServletRequestHandler_1257d50b88c.service($HttpServletRequestHandler_12
57d50b88c.java)
	at org.apache.tapestry5.TapestryFilter.doFilter(TapestryFilter.java:127)
	at
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler
.java:1084)
	at
org.tuckey.web.filters.urlrewrite.RuleChain.handleRewrite(RuleChain.java:164
)
	at org.tuckey.web.filters.urlrewrite.RuleChain.doRules(RuleChain.java:141)
	at
org.tuckey.web.filters.urlrewrite.UrlRewriter.processRequest(UrlRewriter.jav
a:90)
	at
org.tuckey.web.filters.urlrewrite.UrlRewriteFilter.doFilter(UrlRewriteFilter
.java:406)
	at
org.mortbay.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler
.java:1084)
	at org.mortbay.jetty.servlet.ServletHandler.handle(ServletHandler.java:360)
	at
org.mortbay.jetty.security.SecurityHandler.handle(SecurityHandler.java:216)
	at org.mortbay.jetty.servlet.SessionHandler.handle(SessionHandler.java:181)
	at org.mortbay.jetty.handler.ContextHandler.handle(ContextHandler.java:722)
	at org.mortbay.jetty.webapp.WebAppContext.handle(WebAppContext.java:404)
	at org.mortbay.jetty.handler.HandlerWrapper.handle(HandlerWrapper.java:139)
	at org.mortbay.jetty.Server.handle(Server.java:324)
	at org.mortbay.jetty.HttpConnection.handleRequest(HttpConnection.java:505)
	at
org.mortbay.jetty.HttpConnection$RequestHandler.headerComplete(HttpConnectio
n.java:828)
	at org.mortbay.jetty.HttpParser.parseNext(HttpParser.java:514)
	at org.mortbay.jetty.HttpParser.parseAvailable(HttpParser.java:211)
	at org.mortbay.jetty.HttpConnection.handle(HttpConnection.java:380)
	at
org.mortbay.io.nio.SelectChannelEndPoint.run(SelectChannelEndPoint.java:395)
	at
org.mortbay.thread.BoundedThreadPool$PoolThread.run(BoundedThreadPool.java:4
50)


---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
For additional commands, e-mail: users-help@tapestry.apache.org


Re: T5: handling form events in sub-components?

Posted by Inge Solvoll <in...@gmail.com>.
I struggled earlier with this. Components bubble up, not down. Your
components won't be alerted that the form in your page was submitted.

If you need form fields in components, you either have to put the entire
form in the component, or you need to avoid that the form fields depend on
form events.

On Fri, Dec 11, 2009 at 6:06 AM, Benny Law <be...@gmail.com> wrote:

> Hi Jacob,
>
> It sounds like you have nested forms which is not allowed.
>
> Benny
>
> On Thu, Dec 10, 2009 at 11:07 PM, Jacob Mouka <jm...@gmail.com> wrote:
>
> > Hi all (apologies if this is really obvious, but I can't find the info in
> > the docs/examples)
> >
> > I have some sub-components (with form elements) in a form and I want to
> do
> > some actions when the form is submitted. I've tried something like
> >
> >        void onSubmit() {
> >                System.out.println("submitted");
> >        }
> >
> > but it doesn't get called on the sub-components, only the parent
> component.
> > What am I missing?
> >
> > Thanks, Jacob
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> > For additional commands, e-mail: users-help@tapestry.apache.org
> >
> >
>

Re: T5: handling form events in sub-components?

Posted by Benny Law <be...@gmail.com>.
Hi Jacob,

It sounds like you have nested forms which is not allowed.

Benny

On Thu, Dec 10, 2009 at 11:07 PM, Jacob Mouka <jm...@gmail.com> wrote:

> Hi all (apologies if this is really obvious, but I can't find the info in
> the docs/examples)
>
> I have some sub-components (with form elements) in a form and I want to do
> some actions when the form is submitted. I've tried something like
>
>        void onSubmit() {
>                System.out.println("submitted");
>        }
>
> but it doesn't get called on the sub-components, only the parent component.
> What am I missing?
>
> Thanks, Jacob
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe@tapestry.apache.org
> For additional commands, e-mail: users-help@tapestry.apache.org
>
>