You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@cocoon.apache.org by Sylvain Wallez <sy...@apache.org> on 2005/03/08 23:52:14 UTC

Experimental per-sitemap reloadable classloader

Hi all,

Having to often write quick prototypes with Cocoon, I have on my laptop 
one main Cocoon installation and a lot of subsitemap directories in 
various locations, all mounted into the main Cocoon using the 
mount-table matcher.

That works fine until the prototypes need some specific classes, as I 
then hit the problem of deploying these classes. Some ant tasks 
automatically copy the corresponding jars in the main WEB-INF/lib, but 
that's really not convenient.

So I wrote in 2.2 an experimental per-sitemap classpath that allows each 
sitemap to define its own specific classpath for the components defined 
by <map:components>.

The syntax is as follows (the sitemap is in src/webapp hence the "../..").
<map:components>
  <map:classpath>
    <class-dir src="../../build/eclipse"/>
    <lib-dir src="../../lib"/>
  </map:classpath>
  <!-- other components -->
</map:components>

A side benefit, tremedously useful, is that the classloader is 
re-created when the sitemap is reloaded. So this allows, by setting a 
class-dir, to reload changed classes simply by touching the sitemap.

Maybe not as smart as an automatic compiling classloader, but as saving 
in Eclipse automatically recompiles the classes, the productivity boost 
is impressive, especially when combined with the component lazy-loading 
mode.

This feature is intended for application development-time, as it doesn't 
take into consideration instances of the previous versions of the 
reloaded classes that may be stored here and there such as in session 
attributes. That means that you may get some ClassCastException whenever 
such a cases arises. This is the current price to pay for fast roundtrips.

Enjoy,
Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }


Re: Experimental per-sitemap reloadable classloader

Posted by Bertrand Delacretaz <bd...@apache.org>.
Le 8 mars 05, à 23:52, Sylvain Wallez a écrit :

> ...A side benefit, tremedously useful, is that the classloader is 
> re-created when the sitemap is reloaded. So this allows, by setting a 
> class-dir, to reload changed classes simply by touching the sitemap...

Wow. Anyone got some hero plate kits for sale?

-Bertrand

Re: Experimental per-sitemap reloadable classloader

Posted by Sylvain Wallez <sy...@apache.org>.
Carsten Ziegeler wrote:

<snip/>

>How does this new class loader searches for classes? Does it first ask the parent class loader? I'm just curious if it's save to put third party libraries into WEB-INF/lib *and* add them to a sitemap classpath.
>  
>

It uses the same code as the paranoid classloader, i.e. it searches 
locally first and then asks the parent classloader. We can make this 
configurable, although IMO this is the policy that most makes sense in 
this use case.

Using this feature will certainly give us a good jumpstart to discover 
all the good and bad things related to segmented classloading and hot 
reload and find what needs to be fixed or changed.

I can only say that my life as a developer has changed since yesterday 
evening ;-)

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }


Re: Experimental per-sitemap reloadable classloader

Posted by Carsten Ziegeler <cz...@apache.org>.
Sylvain Wallez wrote:
>>For reloading: when the sitemap is reloaded, the classloader could only
>>reload those classes/jars that have changed since the last load/reload.
>> 
>>
> 
> 
> Yes, but the classloader is created as part of the TreeProcessor build 
> process and therefore it's an all or nothing operation. 
Ah, ok.

> Smarter
> reloading would mean transmitting the classloader from the current 
> processor to the newly created one, checking that the classpath 
> definition hasn't changed and crawling the classpath in search for changes.
> 
> Not impossible, but a bit complicated and it won't fully solve the 
> ClassCastException problem for session attributes instance of reloaded 
> classes, although it will reduce the associated annoyances by reducing 
> the number of reloaded classes.
> 
> Problem also is that keeping unchanged classes means keeping their 
> classloader and that therefore we need the classloader for reloaded 
> class to be a child of the previous one, thus creating a classloader 
> chain that will grow over time. Maybe that will impact memory and 
> performance.

Ah, I see, hmm, sounds complicated.
How does this new class loader searches for classes? Does it first ask
the parent class loader? I'm just curious if it's save to put third
party libraries into WEB-INF/lib *and* add them to a sitemap classpath.

Carsten


-- 
Carsten Ziegeler - Open Source Group, S&N AG
http://www.s-und-n.de
http://www.osoco.org/weblogs/rael/

Re: Experimental per-sitemap reloadable classloader

Posted by Sylvain Wallez <sy...@apache.org>.
Carsten Ziegeler wrote:

>Sylvain Wallez wrote:
>  
>

<snip/>

>>This feature is intended for application development-time, as it doesn't 
>>take into consideration instances of the previous versions of the 
>>reloaded classes that may be stored here and there such as in session 
>>attributes. That means that you may get some ClassCastException whenever 
>>such a cases arises. This is the current price to pay for fast roundtrips.
>>
>>    
>>
>Great!!
>
>What about using this for blocks - a simple version - as well? So we
>could just drop a block of functionality (or a web app) into Cocoon. The
>sitemap has the includes for the components and this extra classpath.
>  
>

Yes, sure. That's how I started using it today with my mount-table 
mounted project! Here's a snippet of my sitemap:
    <map:components>
        <map:classpath>
            <class-dir src="BLOCK-INF/classes"/>
            <lib-dir src="BLOCK-INF/lib"/>
        </map:classpath>
        ...
    </map:components>

Real-block ready!!

>For reloading: when the sitemap is reloaded, the classloader could only
>reload those classes/jars that have changed since the last load/reload.
>  
>

Yes, but the classloader is created as part of the TreeProcessor build 
process and therefore it's an all or nothing operation. Smarter 
reloading would mean transmitting the classloader from the current 
processor to the newly created one, checking that the classpath 
definition hasn't changed and crawling the classpath in search for changes.

Not impossible, but a bit complicated and it won't fully solve the 
ClassCastException problem for session attributes instance of reloaded 
classes, although it will reduce the associated annoyances by reducing 
the number of reloaded classes.

Problem also is that keeping unchanged classes means keeping their 
classloader and that therefore we need the classloader for reloaded 
class to be a child of the previous one, thus creating a classloader 
chain that will grow over time. Maybe that will impact memory and 
performance.

Hmm... need more thinking ;-)

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }


Re: Experimental per-sitemap reloadable classloader

Posted by Stefano Mazzocchi <st...@apache.org>.
Carsten Ziegeler wrote:
> Sylvain Wallez wrote:
> 
>>Hi all,
>>
>>Having to often write quick prototypes with Cocoon, I have on my laptop 
>>one main Cocoon installation and a lot of subsitemap directories in 
>>various locations, all mounted into the main Cocoon using the 
>>mount-table matcher.
>>
>>That works fine until the prototypes need some specific classes, as I 
>>then hit the problem of deploying these classes. Some ant tasks 
>>automatically copy the corresponding jars in the main WEB-INF/lib, but 
>>that's really not convenient.
>>
>>So I wrote in 2.2 an experimental per-sitemap classpath that allows each 
>>sitemap to define its own specific classpath for the components defined 
>>by <map:components>.
>>
>>The syntax is as follows (the sitemap is in src/webapp hence the "../..").
>><map:components>
>>  <map:classpath>
>>    <class-dir src="../../build/eclipse"/>
>>    <lib-dir src="../../lib"/>
>>  </map:classpath>
>>  <!-- other components -->
>></map:components>
>>
>>A side benefit, tremedously useful, is that the classloader is 
>>re-created when the sitemap is reloaded. So this allows, by setting a 
>>class-dir, to reload changed classes simply by touching the sitemap.
>>
>>Maybe not as smart as an automatic compiling classloader, but as saving 
>>in Eclipse automatically recompiles the classes, the productivity boost 
>>is impressive, especially when combined with the component lazy-loading 
>>mode.
>>
>>This feature is intended for application development-time, as it doesn't 
>>take into consideration instances of the previous versions of the 
>>reloaded classes that may be stored here and there such as in session 
>>attributes. That means that you may get some ClassCastException whenever 
>>such a cases arises. This is the current price to pay for fast roundtrips.
>>
> 
> Great!!
> 
> What about using this for blocks - a simple version - as well? So we
> could just drop a block of functionality (or a web app) into Cocoon. The
> sitemap has the includes for the components and this extra classpath.
> 
> For reloading: when the sitemap is reloaded, the classloader could only
> reload those classes/jars that have changed since the last load/reload.
> 
> WDYT?

I was thinking about the exact same thing :-)

Boy, without even planning, we got closer and closer (incrementally) to 
real blocks.

-- 
Stefano.


Re: Experimental per-sitemap reloadable classloader

Posted by Carsten Ziegeler <cz...@apache.org>.
Sylvain Wallez wrote:
> Hi all,
> 
> Having to often write quick prototypes with Cocoon, I have on my laptop 
> one main Cocoon installation and a lot of subsitemap directories in 
> various locations, all mounted into the main Cocoon using the 
> mount-table matcher.
> 
> That works fine until the prototypes need some specific classes, as I 
> then hit the problem of deploying these classes. Some ant tasks 
> automatically copy the corresponding jars in the main WEB-INF/lib, but 
> that's really not convenient.
> 
> So I wrote in 2.2 an experimental per-sitemap classpath that allows each 
> sitemap to define its own specific classpath for the components defined 
> by <map:components>.
> 
> The syntax is as follows (the sitemap is in src/webapp hence the "../..").
> <map:components>
>   <map:classpath>
>     <class-dir src="../../build/eclipse"/>
>     <lib-dir src="../../lib"/>
>   </map:classpath>
>   <!-- other components -->
> </map:components>
> 
> A side benefit, tremedously useful, is that the classloader is 
> re-created when the sitemap is reloaded. So this allows, by setting a 
> class-dir, to reload changed classes simply by touching the sitemap.
> 
> Maybe not as smart as an automatic compiling classloader, but as saving 
> in Eclipse automatically recompiles the classes, the productivity boost 
> is impressive, especially when combined with the component lazy-loading 
> mode.
> 
> This feature is intended for application development-time, as it doesn't 
> take into consideration instances of the previous versions of the 
> reloaded classes that may be stored here and there such as in session 
> attributes. That means that you may get some ClassCastException whenever 
> such a cases arises. This is the current price to pay for fast roundtrips.
> 
Great!!

What about using this for blocks - a simple version - as well? So we
could just drop a block of functionality (or a web app) into Cocoon. The
sitemap has the includes for the components and this extra classpath.

For reloading: when the sitemap is reloaded, the classloader could only
reload those classes/jars that have changed since the last load/reload.

WDYT?

Carsten
-- 
Carsten Ziegeler - Open Source Group, S&N AG
http://www.s-und-n.de
http://www.osoco.org/weblogs/rael/

Re: Experimental per-sitemap reloadable classloader

Posted by Sylvain Wallez <sy...@apache.org>.
Torsten Curdt wrote:

>> A side benefit, tremedously useful, is that the classloader is 
>> re-created when the sitemap is reloaded. So this allows, by setting a 
>> class-dir, to reload changed classes simply by touching the sitemap.
>
>
> Awesome, mate! :-D
>
> If we integrate the file alteration monitor from
> jci we can even trigger the sitemap reload
> without the need of touching the sitemap.
>
> ...and we could also hook in the byte code
> transformations (if needed ..like for javaflow)
>
> Do you think that would work?


The classloader is created by a factory that is looked up using 
o.a.c.Core.ClassLoaderFactory, given the <map:classpath> configuration 
object (see in src/java/core). So by defining this component in the root 
cocoon.xconf, we can plug in any classloader strategy we want.

What's missing however, is the notification link between the classloader 
and the sitemap engine, in order to trigger reloading. That's something 
that should be fairly easy to add.

>> Maybe not as smart as an automatic compiling classloader, but as saving 
>
>
> ...not sure if it really has to be a compiling classloader
> as long as we have a automated reloading from within the ide.


Yep, you're right. It only has a drawback for the vi or emacs addicts ;-)

>> This feature is intended for application development-time, as it 
>> doesn't take into consideration instances of the previous versions of 
>> the reloaded classes that may be stored here and there such as in 
>> session attributes. That means that you may get some 
>> ClassCastException whenever such a cases arises. This is the current 
>> price to pay for fast roundtrips.
>
>
> I think that's ok for development!


Overnight (the brain is a non-stop machine) I found a scheme that could 
avoid this session-attribute annoyance: we can automatically invalidate 
sessions that have been created before the classloader creation. When a 
local classloader is created somewhere within Cocoon, a timestamp is 
stored in a global Context attribute. When a request comes in, we 
invalidate the session (if it exists) if it was created before the last 
classloader creation. HttpSession.getCreationTime() gives us the 
necessary information for this.

> Great stuff!


Thanks! Not that complicated though: I added the handling of <classpath> 
in CoreServiceManager and reused some parts of the paranoid block. A 
2-hours hacking session to save a lot of time :-)

Sylvain

-- 
Sylvain Wallez                                  Anyware Technologies
http://www.apache.org/~sylvain           http://www.anyware-tech.com
{ XML, Java, Cocoon, OpenSource }*{ Training, Consulting, Projects }


Re: Experimental per-sitemap reloadable classloader

Posted by Torsten Curdt <tc...@apache.org>.
> A side benefit, tremedously useful, is that the classloader is 
> re-created when the sitemap is reloaded. So this allows, by setting a 
> class-dir, to reload changed classes simply by touching the sitemap.

Awesome, mate! :-D

If we integrate the file alteration monitor from
jci we can even trigger the sitemap reload
without the need of touching the sitemap.

...and we could also hook in the byte code
transformations (if needed ..like for javaflow)

Do you think that would work?

> Maybe not as smart as an automatic compiling classloader, but as saving 

...not sure if it really has to be a compiling classloader
as long as we have a automated reloading from within the ide.

> This feature is intended for application development-time, as it doesn't 
> take into consideration instances of the previous versions of the 
> reloaded classes that may be stored here and there such as in session 
> attributes. That means that you may get some ClassCastException whenever 
> such a cases arises. This is the current price to pay for fast roundtrips.

I think that's ok for development!

Great stuff!

cheers
--
Torsten

Re: Experimental per-sitemap reloadable classloader

Posted by Sylvain Wallez <sy...@apache.org>.
Michael Wechner wrote:

> Sylvain Wallez wrote:
>
>>> The funny thing is that *all* sitemap resources how are relative to 
>>> the trunk... maybe something to do with symlinks?
>>
>>
>>
>> Hmmm... could this be a problem with File.getPath() or 
>> File.getCanonicalPath() on symlinks?
>
>
>
> getAbsolutePath() and getCanonicalPath() in combination can definitely 
> create conflicts ;-)
>
> Just my two cents


Thanks for them, Michi, but can you elaborate?

Sylvain

-- 
Sylvain Wallez                        Anyware Technologies
http://apache.org/~sylvain            http://anyware-tech.com
Apache Software Foundation Member     Research & Technology Director


Re: Experimental per-sitemap reloadable classloader

Posted by Michael Wechner <mi...@wyona.com>.
Sylvain Wallez wrote:

>
>
>> The funny thing is that *all* sitemap resources how are relative to 
>> the trunk... maybe something to do with symlinks?
>
>
>
> Hmmm... could this be a problem with File.getPath() or 
> File.getCanonicalPath() on symlinks?


getAbsolutePath() and getCanonicalPath() in combination can definitely 
create conflicts ;-)

Just my two cents

Michi


-- 
Michael Wechner
Wyona Inc.  -   Open Source Content Management   -   Apache Lenya
http://www.wyona.com                      http://lenya.apache.org
michael.wechner@wyona.com                        michi@apache.org


Re: Experimental per-sitemap reloadable classloader

Posted by Sylvain Wallez <sy...@apache.org>.
Stefano Mazzocchi wrote:

> Sylvain Wallez wrote:
>
>> Stefano Mazzocchi wrote:
>>
>>> Sylvain Wallez wrote:
>>>
>>>> So I wrote in 2.2 an experimental per-sitemap classpath that allows 
>>>> each sitemap to define its own specific classpath for the 
>>>> components defined by <map:components>.
>>>>
>>>> The syntax is as follows (the sitemap is in src/webapp hence the 
>>>> "../..").
>>>> <map:components>
>>>>  <map:classpath>
>>>>    <class-dir src="../../build/eclipse"/>
>>>>    <lib-dir src="../../lib"/>
>>>>  </map:classpath>
>>>>  <!-- other components -->
>>>> </map:components>
>>>
>>>
>>>
>>>
>>> Hmmm, I've used this for the first time today and I have to say that 
>>> I would love my cocoon application to be 'self-contained', so to 
>>> speak, so that I can move it around at best.
>>>
>>> What I've done is:
>>>
>>>  1) package my stuff so that it looks like a real block
>>>
>>>     README.txt
>>>     INSTALL.txt
>>>     sitemap.xmap <-- this is my block sitemap
>>>     stylesheets <-- this is the block resources
>>>     * <-- add other resources at will
>>>     src/java <-- this is the components sources
>>>     lib <-- this contains the jar my code depends on
>>>     build/eclipse <-- here is where eclipse compiles stuff
>>>
>>>  2) add
>>>
>>>     <map:classpath>
>>>      <class-dir src="./build/eclipse"/>
>>>      <lib-dir src="./lib"/>
>>>     </map:classpath>
>>>
>>>     to the sitemap above
>>>
>>>  3) add a symlink
>>>
>>>       $COCOON_HOME/build/webapp/mycocoonapp -> /code/mycocoonapp
>>>
>>> et voila', you are able to 'mount' stuff in cocoon without even 
>>> touching a single line in your cocoon installation, then you just 
>>> have to have your proxypass setup so that http://host/mycocoonapp 
>>> points to http://127.0.0.1:8888/mycocoonapp.
>>>
>>> Easy, fast and secure.
>>>
>>> Too bad it doesn't work! since 'lib-dir' resolves the '.' in './lib' 
>>> as local to the cocoon context, instead of the location of the 
>>> sitemap it's found in.
>>>
>>> This is a mistake, IMO: a real block should *NOT* contain any 
>>> information about where it has been mounted and this behavior 
>>> requires it to do so, preventing the block to be mounted somewhere 
>>> else transparently.
>>>
>>> Is there any need for this behavior that I didn't consider?
>>
>>
>>
>> I will check the lib problem. If it behaves as you state, this is 
>> clearly a bug.
>

I checked, it works for me. I added some stronger checks that given 
paths are actual directories.

An error I made after a quick copy/paste is to have <class-dir 
src="BLOCK-INF/lib"> when this should really be *<lib-dir>*, which is 
inspected to search for *.zip and *.jar files.

> The funny thing is that *all* sitemap resources how are relative to 
> the trunk... maybe something to do with symlinks?


Hmmm... could this be a problem with File.getPath() or 
File.getCanonicalPath() on symlinks?

> Is anybody using symlinks to mount stuff on the cocoon webapp? c'mon, 
> I can't be the only one!


Hey, we're doing it the pure Java way ;-P
And don't forget all those poor windoze users that don't know what 
symlinks are ;-)

>> I've been using the per-classpath feature extensively lately, but 
>> without additional libs (just a class-dir), and it works like a 
>> charm. What a productivity boost!
>>
>> Here's my classpath declaration :
>>
>> <map:classpath>
>>    <class-dir src="BLOCK-INF/classes"/>
>> </map:classpath>
>>
>> IMO the name "eclipse" should not appear, as the contents of the 
>> classes dir can be generated equally by saving your file in Eclipse 
>> or running an Ant build (I use both). My sample was the first layout 
>> I used, but I quickly changed to self-contained mini-apps as you 
>> describe. I think in a near future we'll have a "src-dir" 
>> configuration as well using the compiling classloader.
>>
>> Also, I don't use symlinks in build/webapp that can be destroyed by a 
>> build clean, but use the mount-table matcher. Copy 
>> mount-table.xml.sample in the main Cocoon dir to mount-table.xml and 
>> mount your external mini-apps there.
>
>
> Don't know why, but I've always disliked very much the mount-table.xml 
> thing.


Well, just try it! :-)

>> The only thing missing is the automatic reload of classes (you still 
>> need to touch the sitemap, which I sometimes forget), but other than 
>> this minor annoyance, what a pleasure!
>
>
> hmmm, but why is the sitemap now behaving as it's relative to the root 
> context? puzzling.


Yup. It really shouldn't...

Sylvain

-- 
Sylvain Wallez                        Anyware Technologies
http://apache.org/~sylvain            http://anyware-tech.com
Apache Software Foundation Member     Research & Technology Director


Re: Experimental per-sitemap reloadable classloader

Posted by Stefano Mazzocchi <st...@apache.org>.
Sylvain Wallez wrote:
> Stefano Mazzocchi wrote:
> 
>> Sylvain Wallez wrote:
>>
>>> So I wrote in 2.2 an experimental per-sitemap classpath that allows 
>>> each sitemap to define its own specific classpath for the components 
>>> defined by <map:components>.
>>>
>>> The syntax is as follows (the sitemap is in src/webapp hence the 
>>> "../..").
>>> <map:components>
>>>  <map:classpath>
>>>    <class-dir src="../../build/eclipse"/>
>>>    <lib-dir src="../../lib"/>
>>>  </map:classpath>
>>>  <!-- other components -->
>>> </map:components>
>>
>>
>>
>> Hmmm, I've used this for the first time today and I have to say that I 
>> would love my cocoon application to be 'self-contained', so to speak, 
>> so that I can move it around at best.
>>
>> What I've done is:
>>
>>  1) package my stuff so that it looks like a real block
>>
>>     README.txt
>>     INSTALL.txt
>>     sitemap.xmap <-- this is my block sitemap
>>     stylesheets <-- this is the block resources
>>     * <-- add other resources at will
>>     src/java <-- this is the components sources
>>     lib <-- this contains the jar my code depends on
>>     build/eclipse <-- here is where eclipse compiles stuff
>>
>>  2) add
>>
>>     <map:classpath>
>>      <class-dir src="./build/eclipse"/>
>>      <lib-dir src="./lib"/>
>>     </map:classpath>
>>
>>     to the sitemap above
>>
>>  3) add a symlink
>>
>>       $COCOON_HOME/build/webapp/mycocoonapp -> /code/mycocoonapp
>>
>> et voila', you are able to 'mount' stuff in cocoon without even 
>> touching a single line in your cocoon installation, then you just have 
>> to have your proxypass setup so that http://host/mycocoonapp points to 
>> http://127.0.0.1:8888/mycocoonapp.
>>
>> Easy, fast and secure.
>>
>> Too bad it doesn't work! since 'lib-dir' resolves the '.' in './lib' 
>> as local to the cocoon context, instead of the location of the sitemap 
>> it's found in.
>>
>> This is a mistake, IMO: a real block should *NOT* contain any 
>> information about where it has been mounted and this behavior requires 
>> it to do so, preventing the block to be mounted somewhere else 
>> transparently.
>>
>> Is there any need for this behavior that I didn't consider?
> 
> 
> I will check the lib problem. If it behaves as you state, this is 
> clearly a bug.

The funny thing is that *all* sitemap resources how are relative to the 
trunk... maybe something to do with symlinks?

Is anybody using symlinks to mount stuff on the cocoon webapp? c'mon, I 
can't be the only one!

> I've been using the per-classpath feature extensively lately, but 
> without additional libs (just a class-dir), and it works like a charm. 
> What a productivity boost!
> 
> Here's my classpath declaration :
> 
> <map:classpath>
>    <class-dir src="BLOCK-INF/classes"/>
> </map:classpath>
> 
> IMO the name "eclipse" should not appear, as the contents of the classes 
> dir can be generated equally by saving your file in Eclipse or running 
> an Ant build (I use both). My sample was the first layout I used, but I 
> quickly changed to self-contained mini-apps as you describe. I think in 
> a near future we'll have a "src-dir" configuration as well using the 
> compiling classloader.
> 
> Also, I don't use symlinks in build/webapp that can be destroyed by a 
> build clean, but use the mount-table matcher. Copy 
> mount-table.xml.sample in the main Cocoon dir to mount-table.xml and 
> mount your external mini-apps there.

Don't know why, but I've always disliked very much the mount-table.xml 
thing.

> The only thing missing is the automatic reload of classes (you still 
> need to touch the sitemap, which I sometimes forget), but other than 
> this minor annoyance, what a pleasure!

hmmm, but why is the sitemap now behaving as it's relative to the root 
context? puzzling.

-- 
Stefano.


Re: Experimental per-sitemap reloadable classloader

Posted by Vadim Gritsenko <va...@reverycodes.com>.
Torsten Curdt wrote:
> The SitemapMonitor uses the jci FilesystemAlterationMonitor
> to monitor the given resources. It's now a single thread
> checking every few seconds. Filesystem changes will mark
> the ConcreteTreeProcessor to be replaced on the next request.

You should also try RunnableManager.ROLE instead of private Thread...

Vadim

Re: Experimental per-sitemap reloadable classloader

Posted by Sylvain Wallez <sy...@apache.org>.
Torsten Curdt wrote:

>Torsten Curdt wrote:
>  
>
>>>The only thing missing is the automatic reload of classes (you still
>>>need to touch the sitemap, which I sometimes forget),
>>>      
>>>
>>Nah... almost there. Will finish that up over Easter.
>>    
>>
>
>Tadaaa! :)
>
>...ok - now if you use the "classpath" directive
>the ConcreteTreeProcessor will be subscribed
>to the SitemapMonitor.
>
>The SitemapMonitor uses the jci FilesystemAlterationMonitor
>to monitor the given resources. It's now a single thread
>checking every few seconds. Filesystem changes will mark
>the ConcreteTreeProcessor to be replaced on the next request.
>
>So just point it to you eclipse build directory and
>you don't need to bother about the reloads anymore :)
>  
>

Yeah, easter gift! Thanks mate!

>Sylvain, I noticed a problem with the classpath
>directive though. As soon as I have component
>declaration in the map:components section I get
>an exception:
>
>A DefaultServiceSelector can only be hosted by a CoreServiceManager
>(Key='DefaultServiceSelector')
>  
>

?? Can you elaborate? What kind of component are you adding? Do you have 
a stacktrace?

Sylvain

-- 
Sylvain Wallez                        Anyware Technologies
http://apache.org/~sylvain            http://anyware-tech.com
Apache Software Foundation Member     Research & Technology Director


Re: Experimental per-sitemap reloadable classloader

Posted by Stefano Mazzocchi <st...@apache.org>.
Torsten Curdt wrote:
> Torsten Curdt wrote:
> 
>>>The only thing missing is the automatic reload of classes (you still
>>>need to touch the sitemap, which I sometimes forget),
>>
>>
>>Nah... almost there. Will finish that up over Easter.
> 
> 
> Tadaaa! :)
> 
> ...ok - now if you use the "classpath" directive
> the ConcreteTreeProcessor will be subscribed
> to the SitemapMonitor.
> 
> The SitemapMonitor uses the jci FilesystemAlterationMonitor
> to monitor the given resources. It's now a single thread
> checking every few seconds. Filesystem changes will mark
> the ConcreteTreeProcessor to be replaced on the next request.
> 
> So just point it to you eclipse build directory and
> you don't need to bother about the reloads anymore :)
> 
> Sylvain, I noticed a problem with the classpath
> directive though. As soon as I have component
> declaration in the map:components section I get
> an exception:
> 
> A DefaultServiceSelector can only be hosted by a CoreServiceManager
> (Key='DefaultServiceSelector')

YESSS!!!!!!! YOU ROCK!!!!

Ah, btw, I can confirm the starange behavior (I would call it "bug") of 
the sitemap context being relative to the main cocoon context in case 
symlinks are used to mount subsitemaps. This is both on Sun's 1.4.2 JVM 
and BEA's JVM 1.5 on linux. Using mount-table (as suggested by 
Sylvain... but I still don't like it ;-) make the problem go away.

-- 
Stefano.


Re: Experimental per-sitemap reloadable classloader

Posted by Torsten Curdt <tc...@apache.org>.
Torsten Curdt wrote:
>>The only thing missing is the automatic reload of classes (you still
>>need to touch the sitemap, which I sometimes forget),
> 
> 
> Nah... almost there. Will finish that up over Easter.

Tadaaa! :)

...ok - now if you use the "classpath" directive
the ConcreteTreeProcessor will be subscribed
to the SitemapMonitor.

The SitemapMonitor uses the jci FilesystemAlterationMonitor
to monitor the given resources. It's now a single thread
checking every few seconds. Filesystem changes will mark
the ConcreteTreeProcessor to be replaced on the next request.

So just point it to you eclipse build directory and
you don't need to bother about the reloads anymore :)

Sylvain, I noticed a problem with the classpath
directive though. As soon as I have component
declaration in the map:components section I get
an exception:

A DefaultServiceSelector can only be hosted by a CoreServiceManager
(Key='DefaultServiceSelector')

cheers
--
Torsten

Re: Experimental per-sitemap reloadable classloader

Posted by Torsten Curdt <tc...@apache.org>.
> The only thing missing is the automatic reload of classes (you still
> need to touch the sitemap, which I sometimes forget),

Nah... almost there. Will finish that up over Easter.

cheers
--
Torsten

Re: Experimental per-sitemap reloadable classloader

Posted by Sylvain Wallez <sy...@apache.org>.
Stefano Mazzocchi wrote:

> Sylvain Wallez wrote:
>
>> So I wrote in 2.2 an experimental per-sitemap classpath that allows 
>> each sitemap to define its own specific classpath for the components 
>> defined by <map:components>.
>>
>> The syntax is as follows (the sitemap is in src/webapp hence the 
>> "../..").
>> <map:components>
>>  <map:classpath>
>>    <class-dir src="../../build/eclipse"/>
>>    <lib-dir src="../../lib"/>
>>  </map:classpath>
>>  <!-- other components -->
>> </map:components>
>
>
> Hmmm, I've used this for the first time today and I have to say that I 
> would love my cocoon application to be 'self-contained', so to speak, 
> so that I can move it around at best.
>
> What I've done is:
>
>  1) package my stuff so that it looks like a real block
>
>     README.txt
>     INSTALL.txt
>     sitemap.xmap <-- this is my block sitemap
>     stylesheets <-- this is the block resources
>     * <-- add other resources at will
>     src/java <-- this is the components sources
>     lib <-- this contains the jar my code depends on
>     build/eclipse <-- here is where eclipse compiles stuff
>
>  2) add
>
>     <map:classpath>
>      <class-dir src="./build/eclipse"/>
>      <lib-dir src="./lib"/>
>     </map:classpath>
>
>     to the sitemap above
>
>  3) add a symlink
>
>       $COCOON_HOME/build/webapp/mycocoonapp -> /code/mycocoonapp
>
> et voila', you are able to 'mount' stuff in cocoon without even 
> touching a single line in your cocoon installation, then you just have 
> to have your proxypass setup so that http://host/mycocoonapp points to 
> http://127.0.0.1:8888/mycocoonapp.
>
> Easy, fast and secure.
>
> Too bad it doesn't work! since 'lib-dir' resolves the '.' in './lib' 
> as local to the cocoon context, instead of the location of the sitemap 
> it's found in.
>
> This is a mistake, IMO: a real block should *NOT* contain any 
> information about where it has been mounted and this behavior requires 
> it to do so, preventing the block to be mounted somewhere else 
> transparently.
>
> Is there any need for this behavior that I didn't consider?


I will check the lib problem. If it behaves as you state, this is 
clearly a bug.

I've been using the per-classpath feature extensively lately, but 
without additional libs (just a class-dir), and it works like a charm. 
What a productivity boost!

Here's my classpath declaration :

<map:classpath>
    <class-dir src="BLOCK-INF/classes"/>
</map:classpath>

IMO the name "eclipse" should not appear, as the contents of the classes 
dir can be generated equally by saving your file in Eclipse or running 
an Ant build (I use both). My sample was the first layout I used, but I 
quickly changed to self-contained mini-apps as you describe. I think in 
a near future we'll have a "src-dir" configuration as well using the 
compiling classloader.

Also, I don't use symlinks in build/webapp that can be destroyed by a 
build clean, but use the mount-table matcher. Copy 
mount-table.xml.sample in the main Cocoon dir to mount-table.xml and 
mount your external mini-apps there.

The only thing missing is the automatic reload of classes (you still 
need to touch the sitemap, which I sometimes forget), but other than 
this minor annoyance, what a pleasure!

Sylvain

-- 
Sylvain Wallez                        Anyware Technologies
http://apache.org/~sylvain            http://anyware-tech.com
Apache Software Foundation Member     Research & Technology Director


Re: Experimental per-sitemap reloadable classloader

Posted by Stefano Mazzocchi <st...@apache.org>.
Sylvain Wallez wrote:
> So I wrote in 2.2 an experimental per-sitemap classpath that allows each 
> sitemap to define its own specific classpath for the components defined 
> by <map:components>.
> 
> The syntax is as follows (the sitemap is in src/webapp hence the "../..").
> <map:components>
>  <map:classpath>
>    <class-dir src="../../build/eclipse"/>
>    <lib-dir src="../../lib"/>
>  </map:classpath>
>  <!-- other components -->
> </map:components>

Hmmm, I've used this for the first time today and I have to say that I 
would love my cocoon application to be 'self-contained', so to speak, so 
that I can move it around at best.

What I've done is:

  1) package my stuff so that it looks like a real block

     README.txt
     INSTALL.txt
     sitemap.xmap <-- this is my block sitemap
     stylesheets <-- this is the block resources
     * <-- add other resources at will
     src/java <-- this is the components sources
     lib <-- this contains the jar my code depends on
     build/eclipse <-- here is where eclipse compiles stuff

  2) add

     <map:classpath>
      <class-dir src="./build/eclipse"/>
      <lib-dir src="./lib"/>
     </map:classpath>

     to the sitemap above

  3) add a symlink

       $COCOON_HOME/build/webapp/mycocoonapp -> /code/mycocoonapp

et voila', you are able to 'mount' stuff in cocoon without even touching 
a single line in your cocoon installation, then you just have to have 
your proxypass setup so that http://host/mycocoonapp points to 
http://127.0.0.1:8888/mycocoonapp.

Easy, fast and secure.

Too bad it doesn't work! since 'lib-dir' resolves the '.' in './lib' as 
local to the cocoon context, instead of the location of the sitemap it's 
found in.

This is a mistake, IMO: a real block should *NOT* contain any 
information about where it has been mounted and this behavior requires 
it to do so, preventing the block to be mounted somewhere else 
transparently.

Is there any need for this behavior that I didn't consider?

-- 
Stefano.


Re: Experimental per-sitemap reloadable classloader

Posted by Stefano Mazzocchi <st...@apache.org>.
Sylvain Wallez wrote:
> Hi all,
> 
> Having to often write quick prototypes with Cocoon, I have on my laptop 
> one main Cocoon installation and a lot of subsitemap directories in 
> various locations, all mounted into the main Cocoon using the 
> mount-table matcher.
> 
> That works fine until the prototypes need some specific classes, as I 
> then hit the problem of deploying these classes. Some ant tasks 
> automatically copy the corresponding jars in the main WEB-INF/lib, but 
> that's really not convenient.
> 
> So I wrote in 2.2 an experimental per-sitemap classpath that allows each 
> sitemap to define its own specific classpath for the components defined 
> by <map:components>.
> 
> The syntax is as follows (the sitemap is in src/webapp hence the "../..").
> <map:components>
>  <map:classpath>
>    <class-dir src="../../build/eclipse"/>
>    <lib-dir src="../../lib"/>
>  </map:classpath>
>  <!-- other components -->
> </map:components>
> 
> A side benefit, tremedously useful, is that the classloader is 
> re-created when the sitemap is reloaded. So this allows, by setting a 
> class-dir, to reload changed classes simply by touching the sitemap.
> 
> Maybe not as smart as an automatic compiling classloader, but as saving 
> in Eclipse automatically recompiles the classes, the productivity boost 
> is impressive, especially when combined with the component lazy-loading 
> mode.
> 
> This feature is intended for application development-time, as it doesn't 
> take into consideration instances of the previous versions of the 
> reloaded classes that may be stored here and there such as in session 
> attributes. That means that you may get some ClassCastException whenever 
> such a cases arises. This is the current price to pay for fast roundtrips.

YES!!!!!!!!!!!!!!!!!!!!!!!!!!!!

-- 
Stefano.