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.