You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Grzegorz Kossakowski <gr...@tuffmail.com> on 2007/01/27 21:58:24 UTC

${cocoon.request.contextPath} returns null in 2.2

Hello,

I'm hacking now ajax and forms block to get them use of servlet-services
and came across a bug. When you put ${cocoon.request.contextPath} into
JX template it will always return null (at least while using servlet
dispatcher). However, ${cocoon.request.requestURI} returns valid value,
so it must be only contextPath broken somehow. Unfortunately, I have no
skills to debug this.
Anyone can at least confirm this? Can you test it without servlet
dispatcher? (I would do it myself if I knew how)

Thanks.

-- 
Grzegorz Kossakowski

Re: ${cocoon.request.contextPath} returns null in 2.2

Posted by Grzegorz Kossakowski <gr...@tuffmail.com>.
Grzegorz Kossakowski napisał(a):
>
>> To get the mountPath, it is better to use the blockPath module e.g.
>> {block-path:ajax} (assuming that the cocoon-ajax-impl service servlet
>> is connected at the name ajax in the Spring config). You can also use
>> the service protocol inside the pipeline:
>>
>> <script type="text/javascript"
>> src="servlet:ajax://resources/dojo/dojo.js"/>
>>
>> and end the pipeline with a link rewriter transformer that use the
>> block path module to get the path right.
>>
>> The link rewriter transformer can probably be configured to add the
>> prefix "/blocks-test" as well
>> http://cocoon.apache.org/2.1/apidocs/org/apache/cocoon/transformation/LinkRewriterTransformer.html.
>>
> Doh! I've learned about blocks connections just few days ago and had
> enough time to forgot them ;)
> Obviously, I will try your hints.
>

Daniel, could review my last patches, please? On my machine all forms
works like a charm. Please provide your comments in appropriate issue
page.  It will be easier for someone else to track these discussion in
the future.
Thanks.

-- 
Grzegorz Kossakowski

Re: ${cocoon.request.contextPath} returns null in 2.2

Posted by Grzegorz Kossakowski <gr...@tuffmail.com>.
Daniel Fagerstrom napisał(a):
> You don't get that part, which show that there is a problem with my 
> design. I probably mounted the dispatcher servlet at "/*" while 
> developing the stuff :/ Thinking a little bit more about it, it would 
> probably better to let the servlet path of the dispatcher servlet go 
> to the context path when calling the servlet services. Then we would get:
>
> newContextPath = contextPath + servletPath
> newServletPath = mountPath
> newPathInfo = pathInfo.substring(mountPath.length())
>
> where servletPath above is the servletPath of the dispatcher servlet 
> in the web.xml. Looking at it this mapping looks much more natural 
> than the original one. But there might have been some god reason that 
> I choose the original design that I have forgotten. If no one finds 
> any problem with the new proposal we could switch to that.
Maybe I'm myopic but I would go for that. Speaking for myself I was 
having hard times understanding this path calculations, your new 
proposal seems to be more natural for me also.
> To get the mountPath, it is better to use the blockPath module e.g. 
> {block-path:ajax} (assuming that the cocoon-ajax-impl service servlet 
> is connected at the name ajax in the Spring config). You can also use 
> the service protocol inside the pipeline:
>
> <script type="text/javascript"
> src="servlet:ajax://resources/dojo/dojo.js"/>
>
> and end the pipeline with a link rewriter transformer that use the 
> block path module to get the path right.
>
> The link rewriter transformer can probably be configured to add the 
> prefix "/blocks-test" as well 
> http://cocoon.apache.org/2.1/apidocs/org/apache/cocoon/transformation/LinkRewriterTransformer.html. 
>
Doh! I've learned about blocks connections just few days ago and had 
enough time to forgot them ;)
Obviously, I will try your hints.

-- 
Grzegorz Kossakowski

Re: ${cocoon.request.contextPath} returns null in 2.2

Posted by Daniel Fagerstrom <da...@nada.kth.se>.
Grzegorz Kossakowski skrev:
> Daniel Fagerstrom napisał(a):
>   
>> Daniel Fagerstrom skrev:
>>     
>>> Grzegorz Kossakowski wrote:
>>>       
>>>> Hello,
>>>>
>>>> I'm hacking now ajax and forms block to get them use of
>>>> servlet-services
>>>> and came across a bug. When you put ${cocoon.request.contextPath} into
>>>> JX template it will always return null (at least while using servlet
>>>> dispatcher). However, ${cocoon.request.requestURI} returns valid value,
>>>> so it must be only contextPath broken somehow. Unfortunately, I have no
>>>> skills to debug this.
>>>> Anyone can at least confirm this? Can you test it without servlet
>>>> dispatcher? (I would do it myself if I knew how)
>>>>   
>>>>         
>>> I have not tested it. But looking at the code the servlet dispatcher
>>> just embeds the request object from the servlet container with a
>>> proxy. And the proxy doesn't affect the contextPath AFAICS, so it
>>> might be that the context path is null in the original request.
>>>
>>> For a servlet service that is called through the servlet protocol,
>>> the contextPath will always be "", which is a bug. Currently the
>>> request object of the calling servlet service is not available in the
>>> servlet source, so there is no easy fix. I plan to refactor the call
>>> stack and make it available there.
>>>
>>> In the servlet architecture we have:
>>>
>>> requestURI = contextPath + servletPath + pathInfo
>>>
>>> As the servlet service architecture creates an extra level of paths
>>> relative to the servlet architecture there are several possibilities
>>> where to add the mountPath.  I solved it in the following way: the
>>> dispatcher servlet will look for the mountPath that is the longest
>>> prefix in the incoming pathInfo. It will then create a new
>>> servletPath and pathInfo for the called servlet service:
>>>
>>> newServletPath = servletPath + mountPath
>>> newPathInfo = pathInfo.substring(mountPath.length())
>>>
>>> So as you can see the contextPath will be the same as for all servlet
>>> services.
>>>       
>> Taking a look at your patches in JIRA I see that you have replaced
>>  {request:contextPath}/_cocoon/resources
>> with
>>  /blocks-test/cocoon-forms-impl/resources
>>
>> Now the original pattern is actually faulty (even if it seem to be
>> used everywhere in the samples), it should have been
>>  {request:contextPath}{request:servletPath}/_cocoon/resources
>> and
>>  {request:contextPath}{request:servletPath}/resources
>> in your refactored code.
>>
>> The only reason that the samples work is that the web.xml in
>> cocoon-webapp mounts the sitemap servlet at "/*" which gives
>> servletPath="", but there is no reason to constrain the use of the
>> sitemap servlet to be used only with an empty servlet path. A servlet
>> is supposed to be mountable wherever the user want it.
>>
>> Using the servlet service fw, sitemap servlets will be mounted at
>> other paths and the servletPath must be taken into account.
>>     
> Thanks for explanation. However, your proposed solution will not work.
> In cocoon-ajax-sample we have:
> <script type="text/javascript"
> src="/blocks-test/cocoon-ajax-impl/resources/dojo/dojo.js"/>
> Now if it is replaced by:
> <script type="text/javascript"
> src="${cocoon.request.contextPath}${cocoon.request.servletPath}/resources
> /resources/dojo/dojo.js"/>
> It would be resolved into:
> <script type="text/javascript"
> src="/blocks-test/cocoon-ajax-sample/resources/dojo/dojo.js"/>
>
> So in short, all we want is '/blocks-test' part, the rest depends on
> which block's resources we link to. How get this part?
>   
You don't get that part, which show that there is a problem with my 
design. I probably mounted the dispatcher servlet at "/*" while 
developing the stuff :/ Thinking a little bit more about it, it would 
probably better to let the servlet path of the dispatcher servlet go to 
the context path when calling the servlet services. Then we would get:

newContextPath = contextPath + servletPath
newServletPath = mountPath
newPathInfo = pathInfo.substring(mountPath.length())

where servletPath above is the servletPath of the dispatcher servlet in 
the web.xml. Looking at it this mapping looks much more natural than the 
original one. But there might have been some god reason that I choose 
the original design that I have forgotten. If no one finds any problem 
with the new proposal we could switch to that.

To get the mountPath, it is better to use the blockPath module e.g. 
{block-path:ajax} (assuming that the cocoon-ajax-impl service servlet is 
connected at the name ajax in the Spring config). You can also use the 
service protocol inside the pipeline:

<script type="text/javascript"
src="servlet:ajax://resources/dojo/dojo.js"/>

and end the pipeline with a link rewriter transformer that use the block 
path module to get the path right.

The link rewriter transformer can probably be configured to add the 
prefix "/blocks-test" as well 
http://cocoon.apache.org/2.1/apidocs/org/apache/cocoon/transformation/LinkRewriterTransformer.html.

/Daniel


Re: ${cocoon.request.contextPath} returns null in 2.2

Posted by Grzegorz Kossakowski <gr...@tuffmail.com>.
Daniel Fagerstrom napisał(a):
> Daniel Fagerstrom skrev:
>> Grzegorz Kossakowski wrote:
>>> Hello,
>>>
>>> I'm hacking now ajax and forms block to get them use of
>>> servlet-services
>>> and came across a bug. When you put ${cocoon.request.contextPath} into
>>> JX template it will always return null (at least while using servlet
>>> dispatcher). However, ${cocoon.request.requestURI} returns valid value,
>>> so it must be only contextPath broken somehow. Unfortunately, I have no
>>> skills to debug this.
>>> Anyone can at least confirm this? Can you test it without servlet
>>> dispatcher? (I would do it myself if I knew how)
>>>   
>> I have not tested it. But looking at the code the servlet dispatcher
>> just embeds the request object from the servlet container with a
>> proxy. And the proxy doesn't affect the contextPath AFAICS, so it
>> might be that the context path is null in the original request.
>>
>> For a servlet service that is called through the servlet protocol,
>> the contextPath will always be "", which is a bug. Currently the
>> request object of the calling servlet service is not available in the
>> servlet source, so there is no easy fix. I plan to refactor the call
>> stack and make it available there.
>>
>> In the servlet architecture we have:
>>
>> requestURI = contextPath + servletPath + pathInfo
>>
>> As the servlet service architecture creates an extra level of paths
>> relative to the servlet architecture there are several possibilities
>> where to add the mountPath.  I solved it in the following way: the
>> dispatcher servlet will look for the mountPath that is the longest
>> prefix in the incoming pathInfo. It will then create a new
>> servletPath and pathInfo for the called servlet service:
>>
>> newServletPath = servletPath + mountPath
>> newPathInfo = pathInfo.substring(mountPath.length())
>>
>> So as you can see the contextPath will be the same as for all servlet
>> services.
> Taking a look at your patches in JIRA I see that you have replaced
>  {request:contextPath}/_cocoon/resources
> with
>  /blocks-test/cocoon-forms-impl/resources
>
> Now the original pattern is actually faulty (even if it seem to be
> used everywhere in the samples), it should have been
>  {request:contextPath}{request:servletPath}/_cocoon/resources
> and
>  {request:contextPath}{request:servletPath}/resources
> in your refactored code.
>
> The only reason that the samples work is that the web.xml in
> cocoon-webapp mounts the sitemap servlet at "/*" which gives
> servletPath="", but there is no reason to constrain the use of the
> sitemap servlet to be used only with an empty servlet path. A servlet
> is supposed to be mountable wherever the user want it.
>
> Using the servlet service fw, sitemap servlets will be mounted at
> other paths and the servletPath must be taken into account.
Thanks for explanation. However, your proposed solution will not work.
In cocoon-ajax-sample we have:
<script type="text/javascript"
src="/blocks-test/cocoon-ajax-impl/resources/dojo/dojo.js"/>
Now if it is replaced by:
<script type="text/javascript"
src="${cocoon.request.contextPath}${cocoon.request.servletPath}/resources
/resources/dojo/dojo.js"/>
It would be resolved into:
<script type="text/javascript"
src="/blocks-test/cocoon-ajax-sample/resources/dojo/dojo.js"/>

So in short, all we want is '/blocks-test' part, the rest depends on
which block's resources we link to. How get this part?
> It is still a bug that the contextPath is null, it should be "" (or
> some other non null string).

After reverting all my hacking with servlet-services-fw it works well.
Next time I'll check thing more carefully, sorry for the noise.

-- 
Grzegorz Kossakowski

Re: ${cocoon.request.contextPath} returns null in 2.2

Posted by Daniel Fagerstrom <da...@nada.kth.se>.
Daniel Fagerstrom skrev:
> Grzegorz Kossakowski wrote:
>> Hello,
>>
>> I'm hacking now ajax and forms block to get them use of servlet-services
>> and came across a bug. When you put ${cocoon.request.contextPath} into
>> JX template it will always return null (at least while using servlet
>> dispatcher). However, ${cocoon.request.requestURI} returns valid value,
>> so it must be only contextPath broken somehow. Unfortunately, I have no
>> skills to debug this.
>> Anyone can at least confirm this? Can you test it without servlet
>> dispatcher? (I would do it myself if I knew how)
>>   
> I have not tested it. But looking at the code the servlet dispatcher 
> just embeds the request object from the servlet container with a 
> proxy. And the proxy doesn't affect the contextPath AFAICS, so it 
> might be that the context path is null in the original request.
>
> For a servlet service that is called through the servlet protocol, the 
> contextPath will always be "", which is a bug. Currently the request 
> object of the calling servlet service is not available in the servlet 
> source, so there is no easy fix. I plan to refactor the call stack and 
> make it available there.
>
> In the servlet architecture we have:
>
> requestURI = contextPath + servletPath + pathInfo
>
> As the servlet service architecture creates an extra level of paths 
> relative to the servlet architecture there are several possibilities 
> where to add the mountPath.  I solved it in the following way: the 
> dispatcher servlet will look for the mountPath that is the longest 
> prefix in the incoming pathInfo. It will then create a new servletPath 
> and pathInfo for the called servlet service:
>
> newServletPath = servletPath + mountPath
> newPathInfo = pathInfo.substring(mountPath.length())
>
> So as you can see the contextPath will be the same as for all servlet 
> services.
Taking a look at your patches in JIRA I see that you have replaced
  {request:contextPath}/_cocoon/resources
with
  /blocks-test/cocoon-forms-impl/resources

Now the original pattern is actually faulty (even if it seem to be used 
everywhere in the samples), it should have been
  {request:contextPath}{request:servletPath}/_cocoon/resources
and
  {request:contextPath}{request:servletPath}/resources
in your refactored code.

The only reason that the samples work is that the web.xml in 
cocoon-webapp mounts the sitemap servlet at "/*" which gives 
servletPath="", but there is no reason to constrain the use of the 
sitemap servlet to be used only with an empty servlet path. A servlet is 
supposed to be mountable wherever the user want it.

Using the servlet service fw, sitemap servlets will be mounted at other 
paths and the servletPath must be taken into account.

It is still a bug that the contextPath is null, it should be "" (or some 
other non null string).

/Daniel


Re: ${cocoon.request.contextPath} returns null in 2.2

Posted by Daniel Fagerstrom <da...@nada.kth.se>.
Grzegorz Kossakowski wrote:
> Hello,
>
> I'm hacking now ajax and forms block to get them use of servlet-services
> and came across a bug. When you put ${cocoon.request.contextPath} into
> JX template it will always return null (at least while using servlet
> dispatcher). However, ${cocoon.request.requestURI} returns valid value,
> so it must be only contextPath broken somehow. Unfortunately, I have no
> skills to debug this.
> Anyone can at least confirm this? Can you test it without servlet
> dispatcher? (I would do it myself if I knew how)
>   
I have not tested it. But looking at the code the servlet dispatcher 
just embeds the request object from the servlet container with a proxy. 
And the proxy doesn't affect the contextPath AFAICS, so it might be that 
the context path is null in the original request.

For a servlet service that is called through the servlet protocol, the 
contextPath will always be "", which is a bug. Currently the request 
object of the calling servlet service is not available in the servlet 
source, so there is no easy fix. I plan to refactor the call stack and 
make it available there.

In the servlet architecture we have:

requestURI = contextPath + servletPath + pathInfo

As the servlet service architecture creates an extra level of paths 
relative to the servlet architecture there are several possibilities 
where to add the mountPath.  I solved it in the following way: the 
dispatcher servlet will look for the mountPath that is the longest 
prefix in the incoming pathInfo. It will then create a new servletPath 
and pathInfo for the called servlet service:

newServletPath = servletPath + mountPath
newPathInfo = pathInfo.substring(mountPath.length())

So as you can see the contextPath will be the same as for all servlet 
services.

/Daniel