[Lift] Re: Modularization of Lift code
David, For all that you've said in defense of Lift's extensibility, answer one question: Could you override def _showAllTemplate in Crudify, without having the source at your disposal? And, this is not an isolated example. Glenn... On Aug 28, 12:05 pm, AlBlue alex.blew...@gmail.com wrote: On Jul 29, 12:55 pm, Heiko Seeberger heiko.seeber...@googlemail.com wrote: Just a quick and dirty reply: In order to get OSGi support LiftRules should delegate *everything* to a Collection of LiftModules. LiftModules can be added to and removed from this collection anytime. Yup, maintaining a collection is the easiest way to use dynamic updates in the future. That said, I've been discussing modularity of scala code generally recently: http://alblue.blogspot.com/2009/08/modularity-for-scala.html If anyone's interested helping out then please drop me a note on my blog. Hopefully we'll be able to extend the work that Heiko has already done and use that to modularise the core library. If successful, this could be used as an approach for both the lift code and apps that depend on lift. Alex --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
On Jul 29, 12:55 pm, Heiko Seeberger heiko.seeber...@googlemail.com wrote: Just a quick and dirty reply: In order to get OSGi support LiftRules should delegate *everything* to a Collection of LiftModules. LiftModules can be added to and removed from this collection anytime. Yup, maintaining a collection is the easiest way to use dynamic updates in the future. That said, I've been discussing modularity of scala code generally recently: http://alblue.blogspot.com/2009/08/modularity-for-scala.html If anyone's interested helping out then please drop me a note on my blog. Hopefully we'll be able to extend the work that Heiko has already done and use that to modularise the core library. If successful, this could be used as an approach for both the lift code and apps that depend on lift. Alex --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
David, I'll take a look at the ESME code to see if what you've done scratches my itch on this issue. I've run the war file and it looks interesting. I assume the source is also available. Thanks for the heads-up. Glenn... On Aug 27, 7:55 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Thu, Aug 27, 2009 at 2:00 PM, glenn gl...@exmbly.com wrote: David, Besides the very detailed discussion here about the problems of Boot initialization and the immutability of sitemap and liftrules, that strikes me as a sufficient barrier to real modularization. Are you talking about modularization of web apps? Are you talking about being able to plop in a JAR file and do one or two bits of configuration and have that JAR's features be part of your app? If you are, with the exception of the where do my menu items go issue, as long as you can do the configuration in Boot, Lift allows for fully modular apps. Rather than complaining the Lift doesn't offer what you need, please define what you need in very specific terms (I need to intercept a GET request to a URL, I need to intercept requests to a URL if certain conditions are met, I need to include a tag in view code that invokes code in my module, etc.) or point to another framework that allows for this plugin modularization. I hadn't thought about turning reuseable code into traits and assigning those around in jar files until you mentioned it. Not a bad idea. But I wouldn't feel comfortable incorporating third-party traits in my code unless I had the source to fall back on. Why are traits any different than objects that you subclass? As far as I can tell, traits simply give you nearly multiple inheritance without the headaches. Why would you be any less willing to mix in a trait than to subclass a class provided by another library? Example of poor encapsulation - just the fact that you can encapsulate snippets and templates. Without the source, how can a user ever hope to incorporate those. I think that snippets are a near perfect encapsulation mechanism. They are simply a transformation of XHTML - XHTML. What could be more straight forward? What could be more encapsulated? Further, Lift's mechanism of associating HTML elements with functions means that there's no need to have special URLs to handle forms or anything else. My snippet can generate a form that will be processed if it is submitted back to the server, no matter what URL the form is submitted to. In Rails and other MVC frameworks, the POST/GET must be done to a specific controller in order for the parameters to be correctly processed. Why does this matter? Well, in the ESME codebase, I just created an authentication plugin mechanism that allows a plugin to define a part of a form that is to be filled in as part of the signup process. The signup process doesn't know anything about the plugin or what fields the plugin needs. The snippet that handles the signup simply binds one element to the plugins part of the sign-up. The plugin manages its own portion of the form, manages its own validation, manages its own saving, all without having to register as being part of the controller. This is highly modular. And then, to make them private, which is done...that's turning a headache into a nightmare. Can you give me an example of a private snippet or a private template and how you would use one? Yeah, as long as you work at the source-level, there is no problem. But that, in-and-of itself, is the problem. As you suggest, some, as yet unilluminated patterns, would be most helpful. If I understood what you were trying to do, I could help you with patterns. Code works best for me. If you could put together templates and stubbed Scala and make clear what you're trying to do and what Lift is not letting you do, I could help you out. Thanks, David Glenn... On Aug 27, 12:11 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Thu, Aug 27, 2009 at 11:22 AM, glenn gl...@exmbly.com wrote: David, Returning menu items from your init function is OK, but forces the user of your module to guess on function-call order I don't understand... what function call order are you talking about? The order in which the modules are initialized? Something else? , or be forced to glean it from the source, which he should not be required to do. Putting code such as this, instead, in your init function helps, but does not eliminate that problem. What particular problem? val sitemap = LiftRules.siteMap match { case Full(sm) = LiftRules.setSiteMap(SiteMap(sm.menus ::: Role.menus:_* )) case _ = LiftRules.setSiteMap(SiteMap(Role.menus:_*)) } Where are you proposing to put this code? With it, you can sort of standardize your call-order, requiring that the init function be called immediately before
[Lift] Re: Modularization of Lift code
David, Returning menu items from your init function is OK, but forces the user of your module to guess on function-call order, or be forced to glean it from the source, which he should not be required to do. Putting code such as this, instead, in your init function helps, but does not eliminate that problem. val sitemap = LiftRules.siteMap match { case Full(sm) = LiftRules.setSiteMap(SiteMap(sm.menus ::: Role.menus:_* )) case _ = LiftRules.setSiteMap(SiteMap(Role.menus:_*)) } With it, you can sort of standardize your call-order, requiring that the init function be called immediately before S.addAround(DB.buildLoanWrapper) in Boot,scala. But, there is a larger issue at stake here, I fear, and that is that true modularization requires adherence to rules of encapsulation and complete documentation, two things that are problematic in Scala code (perhaps due to its power and complexity), unlike pure OOP. When I've written before on this subject in this group, I've gotten a lot of examples in the small purporting to dispute my contention, but falling short. If you know I'm wrong, fine ... let's see it. If you just think I am, well...think harder. This is not small potatoes There are plenty of languages on the dust heap precisely because of the extension problem. Glenn... On Aug 26, 2:53 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Wed, Aug 26, 2009 at 10:13 AM, glenn gl...@exmbly.com wrote: Timothy, I'm still not convinced that Lift applications can be modularized as simply as you suggest. Do you have any samples of your MyLib.init? How do you handle the non- PF's, like schemify and setSiteMap? I typically return my menu items from my init function. You can call schemifier from within your init function. As for templates, I've learned that you can use the templating mechanism in Loc to eliminate the need for html files, but that's only a small part of the problem. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. -- Lift, the simply functional web frameworkhttp://liftweb.net Beginning Scalahttp://www.apress.com/book/view/1430219890 Follow me:http://twitter.com/dpp Git some:http://github.com/dpp --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
On Thu, Aug 27, 2009 at 11:22 AM, glenn gl...@exmbly.com wrote: David, Returning menu items from your init function is OK, but forces the user of your module to guess on function-call order I don't understand... what function call order are you talking about? The order in which the modules are initialized? Something else? , or be forced to glean it from the source, which he should not be required to do. Putting code such as this, instead, in your init function helps, but does not eliminate that problem. What particular problem? val sitemap = LiftRules.siteMap match { case Full(sm) = LiftRules.setSiteMap(SiteMap(sm.menus ::: Role.menus:_* )) case _ = LiftRules.setSiteMap(SiteMap(Role.menus:_*)) } Where are you proposing to put this code? With it, you can sort of standardize your call-order, requiring that the init function be called immediately before Just to be precise, init() is a method on your module. It's not a function. S.addAround(DB.buildLoanWrapper) in Boot,scala. But, there is a larger issue at stake here, I fear, and that is that true modularization requires adherence to rules of encapsulation and complete documentation, two things that are problematic in Scala code (perhaps due to its power and complexity), unlike pure OOP. Ummm... as far as I know, Scala is a pure OO language. Everything in Scala is either the instance of a class (and object, but object is overloaded with Scala's use of it as a keyword for singleton) or a method. There is nothing else in Scala. In this way, Scala is like Smalltalk and Ruby. It's not like Java where things exist in Java that are neither an instance nor a method (static methods, primitive types, etc.) There is nothing that we can't do in Scala to encapsulate anything... the issue that I see is what do you want to encapsulate? When I've written before on this subject in this group, I've gotten a lot of examples in the small purporting to dispute my contention, but falling short. If you know I'm wrong, fine ... let's see it. If you just think I am, well...think harder. Let's separate Lift from Scala the language for a moment. I'm no expert in PLT so I'm not going to argue encapsulation in Scala. I can argue about Lift's modularization and what its limitations are. The following things in Lift I know to be non-modular: - Mapper: because one cannot subclass Mapper definitions, it's not really modular. Yes, I've built (and subclassed) ProtoUser, but it's a huge hack and anything serious (e.g., subclassing an existing mapper and *changing* the behavior of one on the fields) is not doable with Mapper. This is basically because I've never meant Mapper to be a serious OR mapping tool, but more of an ActiveRecord clone where you can create a mapping between an RDBMS and some sort of record. I use Mapper very successfully, but it's not meant for the same things OO is meant for (subclassing) or what Mixins are meant for. - SiteMap: SiteMap is frozen at boot time. This means that OSGi modules can't load and unload themselves and mutate the sitemap. Because the sitemap is fixed at boot time, it's also not possible for a module to insert menu items at an appropriate place in the menu hierarchy. - LiftRules: like SiteMap, the LiftRules are fixed at boot time. It's not possible for modules to load/unload dynamically and change the various PFs dynamically. I have a plan for fixing the LiftRules stuff so we can fully support OSGi modules. I will likely extend that to supporting more dynamic sitemaps. More broadly, every time I've had Scala code that's concrete and needed to be made more runtime dynamic, the process has been simple, quick, and painless. Breaking classes into traits and composing those traits into different runtime configurations has by and large been a few minute to few hour project. Yeah, it may be considered poor mans DI to use traits and the cake pattern, but I find that the type safety that Scala offers makes the small extract Scala coding effort to be worth it vs. writing more tests/configuring more runtime stuff/the weird errors that creep into the code despite tests. This is not small potatoes There are plenty of languages on the dust heap precisely because of the extension problem. Can you be very detailed about what kind of problems you're seeing. Maybe the folks on this list can help you work through them and maybe we'll all discover new Scala patterns. Thanks, David Glenn... On Aug 26, 2:53 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Wed, Aug 26, 2009 at 10:13 AM, glenn gl...@exmbly.com wrote: Timothy, I'm still not convinced that Lift applications can be modularized as simply as you suggest. Do you have any samples of your MyLib.init? How do you handle the non- PF's, like schemify and setSiteMap? I typically return my menu items from my init
[Lift] Re: Modularization of Lift code
David, Besides the very detailed discussion here about the problems of Boot initialization and the immutability of sitemap and liftrules, that strikes me as a sufficient barrier to real modularization. I hadn't thought about turning reuseable code into traits and assigning those around in jar files until you mentioned it. Not a bad idea. But I wouldn't feel comfortable incorporating third-party traits in my code unless I had the source to fall back on. Example of poor encapsulation - just the fact that you can encapsulate snippets and templates. Without the source, how can a user ever hope to incorporate those. And then, to make them private, which is done...that's turning a headache into a nightmare. Yeah, as long as you work at the source-level, there is no problem. But that, in-and-of itself, is the problem. As you suggest, some, as yet unilluminated patterns, would be most helpful. Glenn... On Aug 27, 12:11 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Thu, Aug 27, 2009 at 11:22 AM, glenn gl...@exmbly.com wrote: David, Returning menu items from your init function is OK, but forces the user of your module to guess on function-call order I don't understand... what function call order are you talking about? The order in which the modules are initialized? Something else? , or be forced to glean it from the source, which he should not be required to do. Putting code such as this, instead, in your init function helps, but does not eliminate that problem. What particular problem? val sitemap = LiftRules.siteMap match { case Full(sm) = LiftRules.setSiteMap(SiteMap(sm.menus ::: Role.menus:_* )) case _ = LiftRules.setSiteMap(SiteMap(Role.menus:_*)) } Where are you proposing to put this code? With it, you can sort of standardize your call-order, requiring that the init function be called immediately before Just to be precise, init() is a method on your module. It's not a function. S.addAround(DB.buildLoanWrapper) in Boot,scala. But, there is a larger issue at stake here, I fear, and that is that true modularization requires adherence to rules of encapsulation and complete documentation, two things that are problematic in Scala code (perhaps due to its power and complexity), unlike pure OOP. Ummm... as far as I know, Scala is a pure OO language. Everything in Scala is either the instance of a class (and object, but object is overloaded with Scala's use of it as a keyword for singleton) or a method. There is nothing else in Scala. In this way, Scala is like Smalltalk and Ruby. It's not like Java where things exist in Java that are neither an instance nor a method (static methods, primitive types, etc.) There is nothing that we can't do in Scala to encapsulate anything... the issue that I see is what do you want to encapsulate? When I've written before on this subject in this group, I've gotten a lot of examples in the small purporting to dispute my contention, but falling short. If you know I'm wrong, fine ... let's see it. If you just think I am, well...think harder. Let's separate Lift from Scala the language for a moment. I'm no expert in PLT so I'm not going to argue encapsulation in Scala. I can argue about Lift's modularization and what its limitations are. The following things in Lift I know to be non-modular: - Mapper: because one cannot subclass Mapper definitions, it's not really modular. Yes, I've built (and subclassed) ProtoUser, but it's a huge hack and anything serious (e.g., subclassing an existing mapper and *changing* the behavior of one on the fields) is not doable with Mapper. This is basically because I've never meant Mapper to be a serious OR mapping tool, but more of an ActiveRecord clone where you can create a mapping between an RDBMS and some sort of record. I use Mapper very successfully, but it's not meant for the same things OO is meant for (subclassing) or what Mixins are meant for. - SiteMap: SiteMap is frozen at boot time. This means that OSGi modules can't load and unload themselves and mutate the sitemap. Because the sitemap is fixed at boot time, it's also not possible for a module to insert menu items at an appropriate place in the menu hierarchy. - LiftRules: like SiteMap, the LiftRules are fixed at boot time. It's not possible for modules to load/unload dynamically and change the various PFs dynamically. I have a plan for fixing the LiftRules stuff so we can fully support OSGi modules. I will likely extend that to supporting more dynamic sitemaps. More broadly, every time I've had Scala code that's concrete and needed to be made more runtime dynamic, the process has been simple, quick, and painless. Breaking classes into traits and composing those traits into different runtime configurations has by and large been a few minute to few hour project. Yeah,
[Lift] Re: Modularization of Lift code
On Thu, Aug 27, 2009 at 2:00 PM, glenn gl...@exmbly.com wrote: David, Besides the very detailed discussion here about the problems of Boot initialization and the immutability of sitemap and liftrules, that strikes me as a sufficient barrier to real modularization. Are you talking about modularization of web apps? Are you talking about being able to plop in a JAR file and do one or two bits of configuration and have that JAR's features be part of your app? If you are, with the exception of the where do my menu items go issue, as long as you can do the configuration in Boot, Lift allows for fully modular apps. Rather than complaining the Lift doesn't offer what you need, please define what you need in very specific terms (I need to intercept a GET request to a URL, I need to intercept requests to a URL if certain conditions are met, I need to include a tag in view code that invokes code in my module, etc.) or point to another framework that allows for this plugin modularization. I hadn't thought about turning reuseable code into traits and assigning those around in jar files until you mentioned it. Not a bad idea. But I wouldn't feel comfortable incorporating third-party traits in my code unless I had the source to fall back on. Why are traits any different than objects that you subclass? As far as I can tell, traits simply give you nearly multiple inheritance without the headaches. Why would you be any less willing to mix in a trait than to subclass a class provided by another library? Example of poor encapsulation - just the fact that you can encapsulate snippets and templates. Without the source, how can a user ever hope to incorporate those. I think that snippets are a near perfect encapsulation mechanism. They are simply a transformation of XHTML - XHTML. What could be more straight forward? What could be more encapsulated? Further, Lift's mechanism of associating HTML elements with functions means that there's no need to have special URLs to handle forms or anything else. My snippet can generate a form that will be processed if it is submitted back to the server, no matter what URL the form is submitted to. In Rails and other MVC frameworks, the POST/GET must be done to a specific controller in order for the parameters to be correctly processed. Why does this matter? Well, in the ESME codebase, I just created an authentication plugin mechanism that allows a plugin to define a part of a form that is to be filled in as part of the signup process. The signup process doesn't know anything about the plugin or what fields the plugin needs. The snippet that handles the signup simply binds one element to the plugins part of the sign-up. The plugin manages its own portion of the form, manages its own validation, manages its own saving, all without having to register as being part of the controller. This is highly modular. And then, to make them private, which is done...that's turning a headache into a nightmare. Can you give me an example of a private snippet or a private template and how you would use one? Yeah, as long as you work at the source-level, there is no problem. But that, in-and-of itself, is the problem. As you suggest, some, as yet unilluminated patterns, would be most helpful. If I understood what you were trying to do, I could help you with patterns. Code works best for me. If you could put together templates and stubbed Scala and make clear what you're trying to do and what Lift is not letting you do, I could help you out. Thanks, David Glenn... On Aug 27, 12:11 pm, David Pollak feeder.of.the.be...@gmail.com wrote: On Thu, Aug 27, 2009 at 11:22 AM, glenn gl...@exmbly.com wrote: David, Returning menu items from your init function is OK, but forces the user of your module to guess on function-call order I don't understand... what function call order are you talking about? The order in which the modules are initialized? Something else? , or be forced to glean it from the source, which he should not be required to do. Putting code such as this, instead, in your init function helps, but does not eliminate that problem. What particular problem? val sitemap = LiftRules.siteMap match { case Full(sm) = LiftRules.setSiteMap(SiteMap(sm.menus ::: Role.menus:_* )) case _ = LiftRules.setSiteMap(SiteMap(Role.menus:_*)) } Where are you proposing to put this code? With it, you can sort of standardize your call-order, requiring that the init function be called immediately before Just to be precise, init() is a method on your module. It's not a function. S.addAround(DB.buildLoanWrapper) in Boot,scala. But, there is a larger issue at stake here, I fear, and that is that true modularization requires adherence to rules of encapsulation and complete documentation, two things that are problematic in
[Lift] Re: Modularization of Lift code
Timothy, I'm still not convinced that Lift applications can be modularized as simply as you suggest. Do you have any samples of your MyLib.init? How do you handle the non- PF's, like schemify and setSiteMap? As for templates, I've learned that you can use the templating mechanism in Loc to eliminate the need for html files, but that's only a small part of the problem. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Hey Glenn, I actually don't use those features in my libs... For reasons I wont go into that's just not what my kind of work involves... So I cant really comment from experience im afraid. Cheers, Tim On 26/08/2009 18:13, glenn gl...@exmbly.com wrote: Timothy, I'm still not convinced that Lift applications can be modularized as simply as you suggest. Do you have any samples of your MyLib.init? How do you handle the non- PF's, like schemify and setSiteMap? As for templates, I've learned that you can use the templating mechanism in Loc to eliminate the need for html files, but that's only a small part of the problem. Glenn... --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
On Wed, Aug 26, 2009 at 10:13 AM, glenn gl...@exmbly.com wrote: Timothy, I'm still not convinced that Lift applications can be modularized as simply as you suggest. Do you have any samples of your MyLib.init? How do you handle the non- PF's, like schemify and setSiteMap? I typically return my menu items from my init function. You can call schemifier from within your init function. As for templates, I've learned that you can use the templating mechanism in Loc to eliminate the need for html files, but that's only a small part of the problem. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. -- Lift, the simply functional web framework http://liftweb.net Beginning Scala http://www.apress.com/book/view/1430219890 Follow me: http://twitter.com/dpp Git some: http://github.com/dpp --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Hi all, This is a very good discussion! As I am trying to provide OSGi support for Lift, I already encountered this booting/resolving issue. If we could go for OSGi-only this would be a straightforward task (like Stephen described), but we have to support both worlds: Static monolithic non-OSGi and dynamic modular OSGi. I have not yet come up with a solution (could someone please sell me some spare time) but I know for sure there have to be some major changes to resolving/classloading and static-ness (e.g. LiftRules only lets you add stuff, but OSGi requires stuff to be removed on stopping/uninstalling bundles again) if we want proper OSGi support. Any ideas/discussions are very welcome! Go on! Cheers Heiko 2009/7/29 stephen goldbaum stephen.goldb...@gmail.com Classpath management is one of OSGi's features. Another is dynamic service registry and dependency management. So following that route, the Lift framework would define an interface that exposes much of what is currently found in Boot. Modules (OSGi bundles) would create implementations of that interface and register them during startup (fortunately the details are usually handled automatically). Lift would also define a manager class that listens to the registry and does whatever bookkeeping is required when modules come and go. Eclipse RCP is a great example of this in action. Note that defining a framework on top OSGi can also be a slippery slope. RCP is a good example of that as well; it's an extensive framework on top of OSGi. So, the question is whether it's worth turning what is currently a straightforward boot process into something that is more modular though more complicated. If so, a good first step would be to define that manager class and interface since these could be wired together by any means (Scala, OSGi, Spring, etc.) without necessarily branching too far. I can take a look if you all think it's worth it (and if Heiko hasn't already). -Stephen -- My blog: heikoseeberger.name Follow me: twitter.com/hseeberger OSGi on Scala: www.scalamodules.org Lift, the simply functional web framework: liftweb.net --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Hi all I'm completely new to Lift (and Scala) so I'm not yet very familiar with the Lift-specific needs regarding modularization. But I just come from an OSGi project and would like to share two experiences I've had: * Usually OSGi handles classloading very well. Where you can run into problems is when third-party libraries do their own classloading wizardry. I've spent quite some time hunting down exceptions like java.lang.Object Class Not Found. There are solutions and workarounds for such problems. (The most important ones would be passing along the classloader of the current thread to a library doing its own classloading stuff, importing more classes from that library in case of broken classloading chains and using the bootdelegation runtime parameter of the OSGi framework.) How well these would work in combination with Lift and Scala I don't know. * People have grown tired of keeping manually track of OSGi services and bundles by subscribing to the service registry or by using a ServiceTracker. Several solutions exist to automatically keep track of dependencies and dynamically start and stop bundles. The one I've used are OSGi's own Declarative Services. But there exist several other solutions to look at: Eclipse Extensions, Spring-OSGi, iPOJO and possibly more. I've chosen Declarative Services because they are part of the OSGi Service Compendium and seem to be comparatively lightweight, but everything else probably would have worked just as well. I do like OSGi because I think it adds modularization functionality to Java which it has really been missing. Whether it's the right tool to use for Lift I gladly let the Lift cracks decide. I clearly don't know. I hope this was at least tangentially helpful. Cheers Arthur On Wed, Jul 29, 2009 at 8:33 AM, Heiko Seebergerheiko.seeber...@googlemail.com wrote: Hi all, This is a very good discussion! As I am trying to provide OSGi support for Lift, I already encountered this booting/resolving issue. If we could go for OSGi-only this would be a straightforward task (like Stephen described), but we have to support both worlds: Static monolithic non-OSGi and dynamic modular OSGi. I have not yet come up with a solution (could someone please sell me some spare time) but I know for sure there have to be some major changes to resolving/classloading and static-ness (e.g. LiftRules only lets you add stuff, but OSGi requires stuff to be removed on stopping/uninstalling bundles again) if we want proper OSGi support. Any ideas/discussions are very welcome! Go on! Cheers Heiko 2009/7/29 stephen goldbaum stephen.goldb...@gmail.com Classpath management is one of OSGi's features. Another is dynamic service registry and dependency management. So following that route, the Lift framework would define an interface that exposes much of what is currently found in Boot. Modules (OSGi bundles) would create implementations of that interface and register them during startup (fortunately the details are usually handled automatically). Lift would also define a manager class that listens to the registry and does whatever bookkeeping is required when modules come and go. Eclipse RCP is a great example of this in action. Note that defining a framework on top OSGi can also be a slippery slope. RCP is a good example of that as well; it's an extensive framework on top of OSGi. So, the question is whether it's worth turning what is currently a straightforward boot process into something that is more modular though more complicated. If so, a good first step would be to define that manager class and interface since these could be wired together by any means (Scala, OSGi, Spring, etc.) without necessarily branching too far. I can take a look if you all think it's worth it (and if Heiko hasn't already). -Stephen --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Arthur, Thanx for sharing your experiences! Please find my comments below ... Heiko 2009/7/29 Arthur avand...@gmail.com Hi all I'm completely new to Lift (and Scala) so I'm not yet very familiar with the Lift-specific needs regarding modularization. But I just come from an OSGi project and would like to share two experiences I've had: * Usually OSGi handles classloading very well. Where you can run into problems is when third-party libraries do their own classloading wizardry. I've spent quite some time hunting down exceptions like java.lang.Object Class Not Found. There are solutions and workarounds for such problems. (The most important ones would be passing along the classloader of the current thread to a library doing its own classloading stuff, importing more classes from that library in case of broken classloading chains and using the bootdelegation runtime parameter of the OSGi framework.) How well these would work in combination with Lift and Scala I don't know. I am very focussed on Lift being a good OSGi citizen! Hence Lift itself shall use OSGi properly without workarounds. There will be enough of them for third-party libs ... * People have grown tired of keeping manually track of OSGi services and bundles by subscribing to the service registry or by using a ServiceTracker. Several solutions exist to automatically keep track of dependencies and dynamically start and stop bundles. The one I've used are OSGi's own Declarative Services. But there exist several other solutions to look at: Eclipse Extensions, Spring-OSGi, iPOJO and possibly more. I've chosen Declarative Services because they are part of the OSGi Service Compendium and seem to be comparatively lightweight, but everything else probably would have worked just as well. Internally I am planning to use the OSGi API or better ScalaModules ( www.scalamodules.org), in order to keep the footprint small and avoid bugs from DS, DM, etc. But of course people can use any declarative approach for their bundles. I do like OSGi because I think it adds modularization functionality to Java which it has really been missing. Whether it's the right tool to use for Lift I gladly let the Lift cracks decide. I clearly don't know. I hope this was at least tangentially helpful. Cheers Arthur On Wed, Jul 29, 2009 at 8:33 AM, Heiko Seebergerheiko.seeber...@googlemail.com wrote: Hi all, This is a very good discussion! As I am trying to provide OSGi support for Lift, I already encountered this booting/resolving issue. If we could go for OSGi-only this would be a straightforward task (like Stephen described), but we have to support both worlds: Static monolithic non-OSGi and dynamic modular OSGi. I have not yet come up with a solution (could someone please sell me some spare time) but I know for sure there have to be some major changes to resolving/classloading and static-ness (e.g. LiftRules only lets you add stuff, but OSGi requires stuff to be removed on stopping/uninstalling bundles again) if we want proper OSGi support. Any ideas/discussions are very welcome! Go on! Cheers Heiko 2009/7/29 stephen goldbaum stephen.goldb...@gmail.com Classpath management is one of OSGi's features. Another is dynamic service registry and dependency management. So following that route, the Lift framework would define an interface that exposes much of what is currently found in Boot. Modules (OSGi bundles) would create implementations of that interface and register them during startup (fortunately the details are usually handled automatically). Lift would also define a manager class that listens to the registry and does whatever bookkeeping is required when modules come and go. Eclipse RCP is a great example of this in action. Note that defining a framework on top OSGi can also be a slippery slope. RCP is a good example of that as well; it's an extensive framework on top of OSGi. So, the question is whether it's worth turning what is currently a straightforward boot process into something that is more modular though more complicated. If so, a good first step would be to define that manager class and interface since these could be wired together by any means (Scala, OSGi, Spring, etc.) without necessarily branching too far. I can take a look if you all think it's worth it (and if Heiko hasn't already). -Stephen -- My blog: heikoseeberger.name Follow me: twitter.com/hseeberger OSGi on Scala: www.scalamodules.org Lift, the simply functional web framework: liftweb.net --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en
[Lift] Re: Modularization of Lift code
-1 for adding modules by dropping in a jar Suppose the jar supplies multiple Lift modules and I only want to use one, or suppose I want to use some other class in the jar and don't want to use any of its Lift modules. Adding a module to a Lift app really should be an explicit action by the developer, closer to what Tim does by putting MyModule.init in Boot. However, this does have a couple shortcomings: (1) Does not provide a mechanism for supplying templates in the module and (2) Hides the LiftRules additions from the developer which could result in confusion when troubleshooting (did this module prepend or append to dispatch? which module's dispatchers are executing first? etc.) So what about putting something like this in Boot: LiftRules.modules.append(MyModule) or LiftRules.modules.prepend(new MyModule) where MyModule extends LiftModule and LiftModule is a trait like: trait LiftModule { /* * Specify where to search for snippets, views, etc */ def lookupPackage : String /* * Specify where to search for templates */ def templates : Box[String] // or maybe this has a nice default value /* * Override this to provide LoanWrappers that will be added by S.addAround */ def SWrappers : List[LoanWrapper] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.dispatch.append */ def dispatchers : List[LiftRules.DispatchPF] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.statelessDispatchTable.append */ def statelessDispatchers : List[LiftRules.DispatchPF] = List() // Etc. Basically there would be an overrideable method for each type of // thing you can add to LiftRules with nice defaults where possible. A module // developer only overrides the methods needed for their module. } On Jul 28, 4:18 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The first suggestion was reflection... I'm not pushing the idea, just throwing in an alternative. But the xml route doesn't have to be xml--it could be a plain text file like /META-INF/.liftboot etc. Or you could search all jars for net.liftweb.BootXX or net.liftweb.XX that implements a trait OnBoot... The point is, there's no shortage of ways (if there's a will :) ) but they all have a certain cost of course. Dynamic loading _means_ searching for Something. That takes time, and it puts some requirement on the library author--but it takes the requirement off the user. - Timothy Perretttimo...@getintheloop.eu wrote: Hey Naftoli, Lift has a general aversion to xml configs... Is there another route? Cheers, Tim On 28/07/2009 20:47, Naftoli Gugenheim naftoli...@gmail.com wrote: What I was suggesting is that instead of having to write Lib.init in Boot, Lift should look in Lib.jar for say /boot.xml which would tell Lift to execute Lib.init for you on startup. I think that would accomplish what you want, at the cost of lift searching through the jars. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Ryan, I agree with you for the most part - certainly making it explicit would be my preference also. Im not 100% sure that we would need to replicate all the LiftRules functionality as a trait for plugins, as that's just one aspect of how a plugin could change the environment. Your point about making the developer aware what the plugin actually did is a good one though - no one likes black boxes. Perhaps the plugin developer would need to implement some kind of descriptor trait... Meaning that their actual code just uses the normal LiftRules infrastructure, but during the loading process perhaps just Log.debug it to death showing exactly how the environment has been modified or something? Just spitballing... Cheers, Tim On 29/07/2009 12:31, Ryan Donahue donahu...@gmail.com wrote: -1 for adding modules by dropping in a jar Suppose the jar supplies multiple Lift modules and I only want to use one, or suppose I want to use some other class in the jar and don't want to use any of its Lift modules. Adding a module to a Lift app really should be an explicit action by the developer, closer to what Tim does by putting MyModule.init in Boot. However, this does have a couple shortcomings: (1) Does not provide a mechanism for supplying templates in the module and (2) Hides the LiftRules additions from the developer which could result in confusion when troubleshooting (did this module prepend or append to dispatch? which module's dispatchers are executing first? etc.) So what about putting something like this in Boot: LiftRules.modules.append(MyModule) or LiftRules.modules.prepend(new MyModule) where MyModule extends LiftModule and LiftModule is a trait like: trait LiftModule { /* * Specify where to search for snippets, views, etc */ def lookupPackage : String /* * Specify where to search for templates */ def templates : Box[String] // or maybe this has a nice default value /* * Override this to provide LoanWrappers that will be added by S.addAround */ def SWrappers : List[LoanWrapper] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.dispatch.append */ def dispatchers : List[LiftRules.DispatchPF] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.statelessDispatchTable.append */ def statelessDispatchers : List[LiftRules.DispatchPF] = List() // Etc. Basically there would be an overrideable method for each type of // thing you can add to LiftRules with nice defaults where possible. A module // developer only overrides the methods needed for their module. } On Jul 28, 4:18 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The first suggestion was reflection... I'm not pushing the idea, just throwing in an alternative. But the xml route doesn't have to be xml--it could be a plain text file like /META-INF/.liftboot etc. Or you could search all jars for net.liftweb.BootXX or net.liftweb.XX that implements a trait OnBoot... The point is, there's no shortage of ways (if there's a will :) ) but they all have a certain cost of course. Dynamic loading _means_ searching for Something. That takes time, and it puts some requirement on the library author--but it takes the requirement off the user. - Timothy Perretttimo...@getintheloop.eu wrote: Hey Naftoli, Lift has a general aversion to xml configs... Is there another route? Cheers, Tim On 28/07/2009 20:47, Naftoli Gugenheim naftoli...@gmail.com wrote: What I was suggesting is that instead of having to write Lib.init in Boot, Lift should look in Lib.jar for say /boot.xml which would tell Lift to execute Lib.init for you on startup. I think that would accomplish what you want, at the cost of lift searching through the jars. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Just a quick and dirty reply: In order to get OSGi support LiftRules should delegate *everything* to a Collection of LiftModules. LiftModules can be added to and removed from this collection anytime. Heiko 2009/7/29 Timothy Perrett timo...@getintheloop.eu Ryan, I agree with you for the most part - certainly making it explicit would be my preference also. Im not 100% sure that we would need to replicate all the LiftRules functionality as a trait for plugins, as that's just one aspect of how a plugin could change the environment. Your point about making the developer aware what the plugin actually did is a good one though - no one likes black boxes. Perhaps the plugin developer would need to implement some kind of descriptor trait... Meaning that their actual code just uses the normal LiftRules infrastructure, but during the loading process perhaps just Log.debug it to death showing exactly how the environment has been modified or something? Just spitballing... Cheers, Tim On 29/07/2009 12:31, Ryan Donahue donahu...@gmail.com wrote: -1 for adding modules by dropping in a jar Suppose the jar supplies multiple Lift modules and I only want to use one, or suppose I want to use some other class in the jar and don't want to use any of its Lift modules. Adding a module to a Lift app really should be an explicit action by the developer, closer to what Tim does by putting MyModule.init in Boot. However, this does have a couple shortcomings: (1) Does not provide a mechanism for supplying templates in the module and (2) Hides the LiftRules additions from the developer which could result in confusion when troubleshooting (did this module prepend or append to dispatch? which module's dispatchers are executing first? etc.) So what about putting something like this in Boot: LiftRules.modules.append(MyModule) or LiftRules.modules.prepend(new MyModule) where MyModule extends LiftModule and LiftModule is a trait like: trait LiftModule { /* * Specify where to search for snippets, views, etc */ def lookupPackage : String /* * Specify where to search for templates */ def templates : Box[String] // or maybe this has a nice default value /* * Override this to provide LoanWrappers that will be added by S.addAround */ def SWrappers : List[LoanWrapper] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.dispatch.append */ def dispatchers : List[LiftRules.DispatchPF] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.statelessDispatchTable.append */ def statelessDispatchers : List[LiftRules.DispatchPF] = List() // Etc. Basically there would be an overrideable method for each type of // thing you can add to LiftRules with nice defaults where possible. A module // developer only overrides the methods needed for their module. } On Jul 28, 4:18 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The first suggestion was reflection... I'm not pushing the idea, just throwing in an alternative. But the xml route doesn't have to be xml--it could be a plain text file like /META-INF/.liftboot etc. Or you could search all jars for net.liftweb.BootXX or net.liftweb.XX that implements a trait OnBoot... The point is, there's no shortage of ways (if there's a will :) ) but they all have a certain cost of course. Dynamic loading _means_ searching for Something. That takes time, and it puts some requirement on the library author--but it takes the requirement off the user. - Timothy Perretttimo...@getintheloop.eu wrote: Hey Naftoli, Lift has a general aversion to xml configs... Is there another route? Cheers, Tim On 28/07/2009 20:47, Naftoli Gugenheim naftoli...@gmail.com wrote: What I was suggesting is that instead of having to write Lib.init in Boot, Lift should look in Lib.jar for say /boot.xml which would tell Lift to execute Lib.init for you on startup. I think that would accomplish what you want, at the cost of lift searching through the jars. -- My blog: heikoseeberger.name Follow me: twitter.com/hseeberger OSGi on Scala: www.scalamodules.org Lift, the simply functional web framework: liftweb.net --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
More spitballing... Tim, I really don't know which LiftRules stuff would need to be included. For other types of environment changes, the trait could have onLoad and onUnload methods. Heiko, Maybe it is possible to make such a change without breaking API, though I am still fairly new to Lift and not at all familiar enough with LiftRules yet. All the LiftRules public methods could simply manipulate a default internal LiftModule that is always in LiftRules.modules. These are probably big changes, but I see great benefit to well- defined modules. It would facilitate sharing functionality with each other. Could even set up a LiftModule site where you can share and find modules. -Ryan On Jul 29, 7:55 am, Heiko Seeberger heiko.seeber...@googlemail.com wrote: Just a quick and dirty reply: In order to get OSGi support LiftRules should delegate *everything* to a Collection of LiftModules. LiftModules can be added to and removed from this collection anytime. Heiko 2009/7/29 Timothy Perrett timo...@getintheloop.eu Ryan, I agree with you for the most part - certainly making it explicit would be my preference also. Im not 100% sure that we would need to replicate all the LiftRules functionality as a trait for plugins, as that's just one aspect of how a plugin could change the environment. Your point about making the developer aware what the plugin actually did is a good one though - no one likes black boxes. Perhaps the plugin developer would need to implement some kind of descriptor trait... Meaning that their actual code just uses the normal LiftRules infrastructure, but during the loading process perhaps just Log.debug it to death showing exactly how the environment has been modified or something? Just spitballing... Cheers, Tim On 29/07/2009 12:31, Ryan Donahue donahu...@gmail.com wrote: -1 for adding modules by dropping in a jar Suppose the jar supplies multiple Lift modules and I only want to use one, or suppose I want to use some other class in the jar and don't want to use any of its Lift modules. Adding a module to a Lift app really should be an explicit action by the developer, closer to what Tim does by putting MyModule.init in Boot. However, this does have a couple shortcomings: (1) Does not provide a mechanism for supplying templates in the module and (2) Hides the LiftRules additions from the developer which could result in confusion when troubleshooting (did this module prepend or append to dispatch? which module's dispatchers are executing first? etc.) So what about putting something like this in Boot: LiftRules.modules.append(MyModule) or LiftRules.modules.prepend(new MyModule) where MyModule extends LiftModule and LiftModule is a trait like: trait LiftModule { /* * Specify where to search for snippets, views, etc */ def lookupPackage : String /* * Specify where to search for templates */ def templates : Box[String] // or maybe this has a nice default value /* * Override this to provide LoanWrappers that will be added by S.addAround */ def SWrappers : List[LoanWrapper] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.dispatch.append */ def dispatchers : List[LiftRules.DispatchPF] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.statelessDispatchTable.append */ def statelessDispatchers : List[LiftRules.DispatchPF] = List() // Etc. Basically there would be an overrideable method for each type of // thing you can add to LiftRules with nice defaults where possible. A module // developer only overrides the methods needed for their module. } On Jul 28, 4:18 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The first suggestion was reflection... I'm not pushing the idea, just throwing in an alternative. But the xml route doesn't have to be xml--it could be a plain text file like /META-INF/.liftboot etc. Or you could search all jars for net.liftweb.BootXX or net.liftweb.XX that implements a trait OnBoot... The point is, there's no shortage of ways (if there's a will :) ) but they all have a certain cost of course. Dynamic loading _means_ searching for Something. That takes time, and it puts some requirement on the library author--but it takes the requirement off the user. - Timothy Perretttimo...@getintheloop.eu wrote: Hey Naftoli, Lift has a general aversion to xml configs... Is there another route? Cheers, Tim On 28/07/2009 20:47, Naftoli Gugenheim naftoli...@gmail.com wrote: What I was suggesting is that instead of having to write Lib.init in Boot, Lift should look in Lib.jar for say /boot.xml which would tell Lift to execute Lib.init for you on startup.
[Lift] Re: Modularization of Lift code
Sounds good! Any ideas how class lookups (snippets at least) could be delegated to various modules. Currently Lift is using the *global* classpath in a fashion that makes it really hard / impossible for OSGi. Heiko 2009/7/29 Ryan Donahue donahu...@gmail.com More spitballing... Tim, I really don't know which LiftRules stuff would need to be included. For other types of environment changes, the trait could have onLoad and onUnload methods. Heiko, Maybe it is possible to make such a change without breaking API, though I am still fairly new to Lift and not at all familiar enough with LiftRules yet. All the LiftRules public methods could simply manipulate a default internal LiftModule that is always in LiftRules.modules. These are probably big changes, but I see great benefit to well- defined modules. It would facilitate sharing functionality with each other. Could even set up a LiftModule site where you can share and find modules. -Ryan On Jul 29, 7:55 am, Heiko Seeberger heiko.seeber...@googlemail.com wrote: Just a quick and dirty reply: In order to get OSGi support LiftRules should delegate *everything* to a Collection of LiftModules. LiftModules can be added to and removed from this collection anytime. Heiko 2009/7/29 Timothy Perrett timo...@getintheloop.eu Ryan, I agree with you for the most part - certainly making it explicit would be my preference also. Im not 100% sure that we would need to replicate all the LiftRules functionality as a trait for plugins, as that's just one aspect of how a plugin could change the environment. Your point about making the developer aware what the plugin actually did is a good one though - no one likes black boxes. Perhaps the plugin developer would need to implement some kind of descriptor trait... Meaning that their actual code just uses the normal LiftRules infrastructure, but during the loading process perhaps just Log.debug it to death showing exactly how the environment has been modified or something? Just spitballing... Cheers, Tim On 29/07/2009 12:31, Ryan Donahue donahu...@gmail.com wrote: -1 for adding modules by dropping in a jar Suppose the jar supplies multiple Lift modules and I only want to use one, or suppose I want to use some other class in the jar and don't want to use any of its Lift modules. Adding a module to a Lift app really should be an explicit action by the developer, closer to what Tim does by putting MyModule.init in Boot. However, this does have a couple shortcomings: (1) Does not provide a mechanism for supplying templates in the module and (2) Hides the LiftRules additions from the developer which could result in confusion when troubleshooting (did this module prepend or append to dispatch? which module's dispatchers are executing first? etc.) So what about putting something like this in Boot: LiftRules.modules.append(MyModule) or LiftRules.modules.prepend(new MyModule) where MyModule extends LiftModule and LiftModule is a trait like: trait LiftModule { /* * Specify where to search for snippets, views, etc */ def lookupPackage : String /* * Specify where to search for templates */ def templates : Box[String] // or maybe this has a nice default value /* * Override this to provide LoanWrappers that will be added by S.addAround */ def SWrappers : List[LoanWrapper] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.dispatch.append */ def dispatchers : List[LiftRules.DispatchPF] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.statelessDispatchTable.append */ def statelessDispatchers : List[LiftRules.DispatchPF] = List() // Etc. Basically there would be an overrideable method for each type of // thing you can add to LiftRules with nice defaults where possible. A module // developer only overrides the methods needed for their module. } On Jul 28, 4:18 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The first suggestion was reflection... I'm not pushing the idea, just throwing in an alternative. But the xml route doesn't have to be xml--it could be a plain text file like /META-INF/.liftboot etc. Or you could search all jars for net.liftweb.BootXX or net.liftweb.XX that implements a trait OnBoot... The point is, there's no shortage of ways (if there's a will :) ) but they all have a certain cost of course. Dynamic loading _means_ searching for Something. That takes time, and it puts some requirement on the library author--but it takes the requirement off the user. - Timothy
[Lift] Re: Modularization of Lift code
@Heiko: Im not sure we would need to lookup snippets, as the module creator could just register them with LiftRules right? (think DispatchSnippet etc) @all: I think we need to take a step back here a second: Everyone wants a plugin system, but not everyone wants OSGi (specifically the overhead / complexity). So we have two routes as I see it - OSGi, and non-OSGi. We need to define what we want from both and what value it will add for library implementers. Right now we have LiftRules.addToPackages(com.mypackage), we discussed having: LiftRules.addToPackages(com.mypackage) - where the argument is the actual package to add type safety. Why don't we have something like: LiftRules.addToEnviroment(com.mypackage), and the com.mypackage conforms to a known standard / format with some special traits that we call loading methods on. Thoughts? Cheers, Tim On 29/07/2009 13:59, Heiko Seeberger heiko.seeber...@googlemail.com wrote: Sounds good! Any ideas how class lookups (snippets at least) could be delegated to various modules. Currently Lift is using the *global* classpath in a fashion that makes it really hard / impossible for OSGi. Heiko 2009/7/29 Ryan Donahue donahu...@gmail.com More spitballing... Tim, I really don't know which LiftRules stuff would need to be included. For other types of environment changes, the trait could have onLoad and onUnload methods. Heiko, Maybe it is possible to make such a change without breaking API, though I am still fairly new to Lift and not at all familiar enough with LiftRules yet. All the LiftRules public methods could simply manipulate a default internal LiftModule that is always in LiftRules.modules. These are probably big changes, but I see great benefit to well- defined modules. It would facilitate sharing functionality with each other. Could even set up a LiftModule site where you can share and find modules. -Ryan --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
For that price you could write com.mypackage.Init etc. - Timothy Perretttimo...@getintheloop.eu wrote: @Heiko: Im not sure we would need to lookup snippets, as the module creator could just register them with LiftRules right? (think DispatchSnippet etc) @all: I think we need to take a step back here a second: Everyone wants a plugin system, but not everyone wants OSGi (specifically the overhead / complexity). So we have two routes as I see it - OSGi, and non-OSGi. We need to define what we want from both and what value it will add for library implementers. Right now we have LiftRules.addToPackages(com.mypackage), we discussed having: LiftRules.addToPackages(com.mypackage) - where the argument is the actual package to add type safety. Why don't we have something like: LiftRules.addToEnviroment(com.mypackage), and the com.mypackage conforms to a known standard / format with some special traits that we call loading methods on. Thoughts? Cheers, Tim On 29/07/2009 13:59, Heiko Seeberger heiko.seeber...@googlemail.com wrote: Sounds good! Any ideas how class lookups (snippets at least) could be delegated to various modules. Currently Lift is using the *global* classpath in a fashion that makes it really hard / impossible for OSGi. Heiko 2009/7/29 Ryan Donahue donahu...@gmail.com More spitballing... Tim, I really don't know which LiftRules stuff would need to be included. For other types of environment changes, the trait could have onLoad and onUnload methods. Heiko, Maybe it is possible to make such a change without breaking API, though I am still fairly new to Lift and not at all familiar enough with LiftRules yet. All the LiftRules public methods could simply manipulate a default internal LiftModule that is always in LiftRules.modules. These are probably big changes, but I see great benefit to well- defined modules. It would facilitate sharing functionality with each other. Could even set up a LiftModule site where you can share and find modules. -Ryan --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Bah, that's very true Naftoli... On 29/07/2009 16:33, Naftoli Gugenheim naftoli...@gmail.com wrote: For that price you could write com.mypackage.Init etc. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
LiftRules.addToEnviroment(com.mypackage), and the com.mypackage conforms to a known standard / format with some special traits that we call loading methods on. This isn't really any different then building a module by extending LiftModule trait except that the known standard / format' is actually documented by the LiftModule trait itself and can be checked by compiler when you add LiftRules.modules.append(MyModule) to your Boot class. Regarding OSGi, I don't see a good case for using it when you just want to build a regular Lift app. Maybe if you're trying to build the next great CMS or Wordpress, but I personally won't use OSGi w/ Lift anytime soon. However, the modules themselves could be responsible for loading snippets, views, and templates. The base LiftModule trait could define and implement a findSnippet method (and findView, findTemplate) that uses current Lift technique for finding snippets. If you want to build an OSGi module then you override findSnippet. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
This discussion has gotten beyond a simple solution for Lift plugins. Most Lift apps now don't use OSGi, and modularization means something different in a non-OSGi environment. For one thing, it's not dynamic. You still have to code to use the new module. A well-mannered Lift/OSGi marriage is a good thing, where modularization is the rule, not the exception, but that doesn't take the place of statically dropping in code/jars during development. That is what needs to be addressed foremost, I think. Glenn... On Jul 29, 4:55 am, Heiko Seeberger heiko.seeber...@googlemail.com wrote: Just a quick and dirty reply: In order to get OSGi support LiftRules should delegate *everything* to a Collection of LiftModules. LiftModules can be added to and removed from this collection anytime. Heiko 2009/7/29 Timothy Perrett timo...@getintheloop.eu Ryan, I agree with you for the most part - certainly making it explicit would be my preference also. Im not 100% sure that we would need to replicate all the LiftRules functionality as a trait for plugins, as that's just one aspect of how a plugin could change the environment. Your point about making the developer aware what the plugin actually did is a good one though - no one likes black boxes. Perhaps the plugin developer would need to implement some kind of descriptor trait... Meaning that their actual code just uses the normal LiftRules infrastructure, but during the loading process perhaps just Log.debug it to death showing exactly how the environment has been modified or something? Just spitballing... Cheers, Tim On 29/07/2009 12:31, Ryan Donahue donahu...@gmail.com wrote: -1 for adding modules by dropping in a jar Suppose the jar supplies multiple Lift modules and I only want to use one, or suppose I want to use some other class in the jar and don't want to use any of its Lift modules. Adding a module to a Lift app really should be an explicit action by the developer, closer to what Tim does by putting MyModule.init in Boot. However, this does have a couple shortcomings: (1) Does not provide a mechanism for supplying templates in the module and (2) Hides the LiftRules additions from the developer which could result in confusion when troubleshooting (did this module prepend or append to dispatch? which module's dispatchers are executing first? etc.) So what about putting something like this in Boot: LiftRules.modules.append(MyModule) or LiftRules.modules.prepend(new MyModule) where MyModule extends LiftModule and LiftModule is a trait like: trait LiftModule { /* * Specify where to search for snippets, views, etc */ def lookupPackage : String /* * Specify where to search for templates */ def templates : Box[String] // or maybe this has a nice default value /* * Override this to provide LoanWrappers that will be added by S.addAround */ def SWrappers : List[LoanWrapper] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.dispatch.append */ def dispatchers : List[LiftRules.DispatchPF] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.statelessDispatchTable.append */ def statelessDispatchers : List[LiftRules.DispatchPF] = List() // Etc. Basically there would be an overrideable method for each type of // thing you can add to LiftRules with nice defaults where possible. A module // developer only overrides the methods needed for their module. } On Jul 28, 4:18 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The first suggestion was reflection... I'm not pushing the idea, just throwing in an alternative. But the xml route doesn't have to be xml--it could be a plain text file like /META-INF/.liftboot etc. Or you could search all jars for net.liftweb.BootXX or net.liftweb.XX that implements a trait OnBoot... The point is, there's no shortage of ways (if there's a will :) ) but they all have a certain cost of course. Dynamic loading _means_ searching for Something. That takes time, and it puts some requirement on the library author--but it takes the requirement off the user. - Timothy Perretttimo...@getintheloop.eu wrote: Hey Naftoli, Lift has a general aversion to xml configs... Is there another route? Cheers, Tim On 28/07/2009 20:47, Naftoli Gugenheim naftoli...@gmail.com wrote: What I was suggesting is that instead of having to write Lib.init in Boot, Lift should look in Lib.jar for say /boot.xml which would tell Lift to execute Lib.init for you on startup. I think that would accomplish what you want, at the cost of lift searching through the jars. -- My blog: heikoseeberger.name Follow me: twitter.com/hseeberger OSGi on
[Lift] Re: Modularization of Lift code
Glenn, We have got OSGi support on the roadmap for 1.1, hence IMHO this has to be addressed right now. Heiko 2009/7/29 glenn gl...@exmbly.com This discussion has gotten beyond a simple solution for Lift plugins. Most Lift apps now don't use OSGi, and modularization means something different in a non-OSGi environment. For one thing, it's not dynamic. You still have to code to use the new module. A well-mannered Lift/OSGi marriage is a good thing, where modularization is the rule, not the exception, but that doesn't take the place of statically dropping in code/jars during development. That is what needs to be addressed foremost, I think. Glenn... On Jul 29, 4:55 am, Heiko Seeberger heiko.seeber...@googlemail.com wrote: Just a quick and dirty reply: In order to get OSGi support LiftRules should delegate *everything* to a Collection of LiftModules. LiftModules can be added to and removed from this collection anytime. Heiko 2009/7/29 Timothy Perrett timo...@getintheloop.eu Ryan, I agree with you for the most part - certainly making it explicit would be my preference also. Im not 100% sure that we would need to replicate all the LiftRules functionality as a trait for plugins, as that's just one aspect of how a plugin could change the environment. Your point about making the developer aware what the plugin actually did is a good one though - no one likes black boxes. Perhaps the plugin developer would need to implement some kind of descriptor trait... Meaning that their actual code just uses the normal LiftRules infrastructure, but during the loading process perhaps just Log.debug it to death showing exactly how the environment has been modified or something? Just spitballing... Cheers, Tim On 29/07/2009 12:31, Ryan Donahue donahu...@gmail.com wrote: -1 for adding modules by dropping in a jar Suppose the jar supplies multiple Lift modules and I only want to use one, or suppose I want to use some other class in the jar and don't want to use any of its Lift modules. Adding a module to a Lift app really should be an explicit action by the developer, closer to what Tim does by putting MyModule.init in Boot. However, this does have a couple shortcomings: (1) Does not provide a mechanism for supplying templates in the module and (2) Hides the LiftRules additions from the developer which could result in confusion when troubleshooting (did this module prepend or append to dispatch? which module's dispatchers are executing first? etc.) So what about putting something like this in Boot: LiftRules.modules.append(MyModule) or LiftRules.modules.prepend(new MyModule) where MyModule extends LiftModule and LiftModule is a trait like: trait LiftModule { /* * Specify where to search for snippets, views, etc */ def lookupPackage : String /* * Specify where to search for templates */ def templates : Box[String] // or maybe this has a nice default value /* * Override this to provide LoanWrappers that will be added by S.addAround */ def SWrappers : List[LoanWrapper] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.dispatch.append */ def dispatchers : List[LiftRules.DispatchPF] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.statelessDispatchTable.append */ def statelessDispatchers : List[LiftRules.DispatchPF] = List() // Etc. Basically there would be an overrideable method for each type of // thing you can add to LiftRules with nice defaults where possible. A module // developer only overrides the methods needed for their module. } On Jul 28, 4:18 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The first suggestion was reflection... I'm not pushing the idea, just throwing in an alternative. But the xml route doesn't have to be xml--it could be a plain text file like /META-INF/.liftboot etc. Or you could search all jars for net.liftweb.BootXX or net.liftweb.XX that implements a trait OnBoot... The point is, there's no shortage of ways (if there's a will :) ) but they all have a certain cost of course. Dynamic loading _means_ searching for Something. That takes time, and it puts some requirement on the library author--but it takes the requirement off the user. - Timothy Perretttimo...@getintheloop.eu wrote: Hey Naftoli, Lift has a general aversion to xml configs... Is there another route? Cheers, Tim On 28/07/2009 20:47, Naftoli Gugenheim naftoli...@gmail.com wrote: What I was suggesting is that instead of having to write Lib.init in Boot,
[Lift] Re: Modularization of Lift code
On Tue, Jul 28, 2009 at 12:10 PM, glenn gl...@exmbly.com wrote: Hi, Ross, So, with the changes, where would templates need to be placed in jar files in order to be found - or can they be put in any directory as long as the resource is noted in ResourceServer? ResourceServer is used exclusively for serving whole resources, but not for locating templates. If you just want to locate templates, as long as they can be found as resources, they are servable. Also, please keep in mind that each Loc can contain a function that will serve the template for that page. Glenn... On Jul 28, 9:39 am, Ross Mellgren dri...@gmail.com wrote: http://github.com/dpp/liftweb/commit/0f60807dd64b7fe1430919738b46f2eb... ... From: feeder.of.the.be...@gmail.com Subject:[Lift] Re: ResourceServer problem Date: July 22, 2009 12:07:14 PM EDT To: liftweb@googlegroups.com Reply-To: liftweb@googlegroups.com On Tue, Jul 21, 2009 at 9:55 PM, Naftoli Gugenheim naftoli...@gmail.com wrote: Now a direct call to ResourceServer does work, but the template is still not being found. Any ideas? Templates are looked up simply by using the ServletContainer Context's resource locator. I've expanded the lookup process so that stuff in JAR files will be found. I'll commit the changes up in 10 minutes or so. -Ross On Jul 28, 2009, at 12:36 PM, Timothy Perrett wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a
[Lift] Re: Modularization of Lift code
On Wed, Jul 29, 2009 at 4:31 AM, Ryan Donahue donahu...@gmail.com wrote: -1 for adding modules by dropping in a jar Dropping in JAR files that automatically become part of your app is not going to happen. I've seen too many horror show situations where people have stuff on their classpath that magically becomes part of the app. A single line init in Boot is simple enough. Suppose the jar supplies multiple Lift modules and I only want to use one, or suppose I want to use some other class in the jar and don't want to use any of its Lift modules. Adding a module to a Lift app really should be an explicit action by the developer, closer to what Tim does by putting MyModule.init in Boot. However, this does have a couple shortcomings: (1) Does not provide a mechanism for supplying templates in the module It does because the module can specify its own templates as part of the Loc and (2) Hides the LiftRules additions from the developer which could result in confusion when troubleshooting (did this module prepend or append to dispatch? which module's dispatchers are executing first? etc.) So what about putting something like this in Boot: LiftRules.modules.append(MyModule) or LiftRules.modules.prepend(new MyModule) where MyModule extends LiftModule and LiftModule is a trait like: trait LiftModule { /* * Specify where to search for snippets, views, etc */ def lookupPackage : String /* * Specify where to search for templates */ def templates : Box[String] // or maybe this has a nice default value /* * Override this to provide LoanWrappers that will be added by S.addAround */ def SWrappers : List[LoanWrapper] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.dispatch.append */ def dispatchers : List[LiftRules.DispatchPF] = List() /* * Override this to provide dispatchers that will be added by * LiftRules.statelessDispatchTable.append */ def statelessDispatchers : List[LiftRules.DispatchPF] = List() // Etc. Basically there would be an overrideable method for each type of // thing you can add to LiftRules with nice defaults where possible. A module // developer only overrides the methods needed for their module. } On Jul 28, 4:18 pm, Naftoli Gugenheim naftoli...@gmail.com wrote: The first suggestion was reflection... I'm not pushing the idea, just throwing in an alternative. But the xml route doesn't have to be xml--it could be a plain text file like /META-INF/.liftboot etc. Or you could search all jars for net.liftweb.BootXX or net.liftweb.XX that implements a trait OnBoot... The point is, there's no shortage of ways (if there's a will :) ) but they all have a certain cost of course. Dynamic loading _means_ searching for Something. That takes time, and it puts some requirement on the library author--but it takes the requirement off the user. - Timothy Perretttimo...@getintheloop.eu wrote: Hey Naftoli, Lift has a general aversion to xml configs... Is there another route? Cheers, Tim On 28/07/2009 20:47, Naftoli Gugenheim naftoli...@gmail.com wrote: What I was suggesting is that instead of having to write Lib.init in Boot, Lift should look in Lib.jar for say /boot.xml which would tell Lift to execute Lib.init for you on startup. I think that would accomplish what you want, at the cost of lift searching through the jars. -- Lift, the simply functional web framework http://liftweb.net Beginning Scala http://www.apress.com/book/view/1430219890 Follow me: http://twitter.com/dpp Git some: http://github.com/dpp --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
http://github.com/dpp/liftweb/commit/0f60807dd64b7fe1430919738b46f2ebe1758f22 ... From: feeder.of.the.be...@gmail.com Subject:[Lift] Re: ResourceServer problem Date: July 22, 2009 12:07:14 PM EDT To: liftweb@googlegroups.com Reply-To: liftweb@googlegroups.com On Tue, Jul 21, 2009 at 9:55 PM, Naftoli Gugenheim naftoli...@gmail.com wrote: Now a direct call to ResourceServer does work, but the template is still not being found. Any ideas? Templates are looked up simply by using the ServletContainer Context's resource locator. I've expanded the lookup process so that stuff in JAR files will be found. I'll commit the changes up in 10 minutes or so. -Ross On Jul 28, 2009, at 12:36 PM, Timothy Perrett wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Tim, Here's a thought. GWT uses entry-point class=some fully qualified class name / to identify and initialize modules. Perhaps something similar could be hooked into LiftFilter and an entry point class identified in web.xml. There should be little objection to xml configuration, as opposed to using Java reflection. Glenn... On Jul 28, 9:36 am, Timothy Perrett timo...@getintheloop.eu wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Tim, My last post may be dismissed as adding more complication than simply editing Boot.scala. But keep in mind that a consistent, uniform and robust procedure for modularization across the Lift universe is to be favored over the ad-hoc approach, as exists now. In my view, opening a project and editing source files should always be a last-resort option. Glenn... On Jul 28, 9:36 am, Timothy Perrett timo...@getintheloop.eu wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Hi, Ross, So, with the changes, where would templates need to be placed in jar files in order to be found - or can they be put in any directory as long as the resource is noted in ResourceServer? Glenn... On Jul 28, 9:39 am, Ross Mellgren dri...@gmail.com wrote: http://github.com/dpp/liftweb/commit/0f60807dd64b7fe1430919738b46f2eb... ... From: feeder.of.the.be...@gmail.com Subject: [Lift] Re: ResourceServer problem Date: July 22, 2009 12:07:14 PM EDT To: liftweb@googlegroups.com Reply-To: liftweb@googlegroups.com On Tue, Jul 21, 2009 at 9:55 PM, Naftoli Gugenheim naftoli...@gmail.com wrote: Now a direct call to ResourceServer does work, but the template is still not being found. Any ideas? Templates are looked up simply by using the ServletContainer Context's resource locator. I've expanded the lookup process so that stuff in JAR files will be found. I'll commit the changes up in 10 minutes or so. -Ross On Jul 28, 2009, at 12:36 PM, Timothy Perrett wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to
[Lift] Re: Modularization of Lift code
I've been having a think about this, and are we overlooking something stupid here? Perhaps OSGi could yield a good solution? Thoughts? Cheers, Tim On 28/07/2009 20:04, glenn gl...@exmbly.com wrote: Tim, My last post may be dismissed as adding more complication than simply editing Boot.scala. But keep in mind that a consistent, uniform and robust procedure for modularization across the Lift universe is to be favored over the ad-hoc approach, as exists now. In my view, opening a project and editing source files should always be a last-resort option. Glenn... On Jul 28, 9:36 am, Timothy Perrett timo...@getintheloop.eu wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
If the xml is in the jar file then it would only require the user of the library to drop thr jar in. It would only be an extra step for the library author. The question is whether the extra line saved in Boot is worth the time it takes for Lift to search the jars whenever you deploy. - glenngl...@exmbly.com wrote: Tim, My last post may be dismissed as adding more complication than simply editing Boot.scala. But keep in mind that a consistent, uniform and robust procedure for modularization across the Lift universe is to be favored over the ad-hoc approach, as exists now. In my view, opening a project and editing source files should always be a last-resort option. Glenn... On Jul 28, 9:36 am, Timothy Perrett timo...@getintheloop.eu wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
It's not related to ResourceServer. Just use the jar-relative path in the embed tag etc. - glenngl...@exmbly.com wrote: Hi, Ross, So, with the changes, where would templates need to be placed in jar files in order to be found - or can they be put in any directory as long as the resource is noted in ResourceServer? Glenn... On Jul 28, 9:39 am, Ross Mellgren dri...@gmail.com wrote: http://github.com/dpp/liftweb/commit/0f60807dd64b7fe1430919738b46f2eb... ... From: feeder.of.the.be...@gmail.com Subject: [Lift] Re: ResourceServer problem Date: July 22, 2009 12:07:14 PM EDT To: liftweb@googlegroups.com Reply-To: liftweb@googlegroups.com On Tue, Jul 21, 2009 at 9:55 PM, Naftoli Gugenheim naftoli...@gmail.com wrote: Now a direct call to ResourceServer does work, but the template is still not being found. Any ideas? Templates are looked up simply by using the ServletContainer Context's resource locator. I've expanded the lookup process so that stuff in JAR files will be found. I'll commit the changes up in 10 minutes or so. -Ross On Jul 28, 2009, at 12:36 PM, Timothy Perrett wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you
[Lift] Re: Modularization of Lift code
Im just spitballing - I knew Heiko was working on a bunch of modules and such for Lift so wondered if it was possibly a route forward (im not really up to speed with OSGi) Cheers, Tim On Jul 28, 8:20 pm, glenn gl...@exmbly.com wrote: My understanding about OSGi is that is allows for dynamic classpath dependencies through a jar's META-INF file. But wouldn't that require launching an OSGi implementation with your main Lift application. Glenn... On Jul 28, 12:11 pm, Timothy Perrett timo...@getintheloop.eu wrote: I've been having a think about this, and are we overlooking something stupid here? Perhaps OSGi could yield a good solution? Thoughts? Cheers, Tim On 28/07/2009 20:04, glenn gl...@exmbly.com wrote: Tim, My last post may be dismissed as adding more complication than simply editing Boot.scala. But keep in mind that a consistent, uniform and robust procedure for modularization across the Lift universe is to be favored over the ad-hoc approach, as exists now. In my view, opening a project and editing source files should always be a last-resort option. Glenn... On Jul 28, 9:36 am, Timothy Perrett timo...@getintheloop.eu wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this
[Lift] Re: Modularization of Lift code
The jar should be in lib I guess, and use the path relative to the jar file (the path in the jar). I added /tableeditor/default.html to lift-mapper.jar, so you would include it with lift:embed what=/tableeditor/default . - glenngl...@exmbly.com wrote: Say I just wanted to open the template, tmpl.html in my module's jar file. Since it's not in the webapp directory, what would the link have to look like in my sitemap menu? Glenn Sent from my Verizon Wireless BlackBerry -Original Message- From: Naftoli Gugenheim naftoli...@gmail.com Date: Tue, 28 Jul 2009 12:17:44 To: gl...@exmbly.com; liftweb@googlegroups.com Subject: Re: [Lift] Re: Modularization of Lift code It's not related to ResourceServer. Just use the jar-relative path in the embed tag etc. - glenngl...@exmbly.com wrote: Hi, Ross, So, with the changes, where would templates need to be placed in jar files in order to be found - or can they be put in any directory as long as the resource is noted in ResourceServer? Glenn... On Jul 28, 9:39 am, Ross Mellgren dri...@gmail.com wrote: http://github.com/dpp/liftweb/commit/0f60807dd64b7fe1430919738b46f2eb... ... From: feeder.of.the.be...@gmail.com Subject: [Lift] Re: ResourceServer problem Date: July 22, 2009 12:07:14 PM EDT To: liftweb@googlegroups.com Reply-To: liftweb@googlegroups.com On Tue, Jul 21, 2009 at 9:55 PM, Naftoli Gugenheim naftoli...@gmail.com wrote: Now a direct call to ResourceServer does work, but the template is still not being found. Any ideas? Templates are looked up simply by using the ServletContainer Context's resource locator. I've expanded the lookup process so that stuff in JAR files will be found. I'll commit the changes up in 10 minutes or so. -Ross On Jul 28, 2009, at 12:36 PM, Timothy Perrett wrote: Glenn, You have my full attention - this is something I've been sitting on for quite some time but just not quite sure what the best route forward is. When im creating these modules, I essentially just build a normal jar project with maven, and as you say, if I have JS or whatever that I need to use I just specify that with ResourceServer (in the module JAR init). To date I've not actually needed to pull a template from another JAR, but looking at ResourceServer.findResourceInClasspath I think it could do it... If memory serves DPP checked in a change to make this work about 2 weeks ago... In terms of having a defined loading pattern, its possible, but would need outlining with some very specific details... IMO, adding one line of code to Boot.scala is not a big deal so we would really need a good reason to add a bunch of reflection which can sometime feel like voodoo because its not clear what its loading and why (one of the reasons I went off ruby). Cheers, tim On 28/07/2009 17:00, glenn gl...@exmbly.com wrote: Hi, Tim, So, what you do is put all new LiftRules, Schemifier and ResourceServer stuff in an init function and run it after the Boot.scala defaults. Sounds simple enough. When creating your modules, do you just strip out all the stock webapp files (those that come with the maven lift archetypes), and put all your new resources in a toserve directory, then just jar it up? And what about any new template files? Where do those go in you module jars? You can't put them in the toserver directory. My understanding is that that would install them in the WEB-INF/classes directory of your final war file, when they need to go into the root webapp. I still see loose ends here. Also, what if you didn't have to modify Bool.scala for every module you add. Some hook function in an object that Boot.scala runs each time that would iterate through all your init functions that followed a pre- defined signature, would be a nice feature to add to Lift. Glenn... On Jul 27, 4:01 pm, Timothy Perrett timo...@getintheloop.eu wrote: Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I
[Lift] Re: Modularization of Lift code
Hey Naftoli, Lift has a general aversion to xml configs... Is there another route? Cheers, Tim On 28/07/2009 20:47, Naftoli Gugenheim naftoli...@gmail.com wrote: What I was suggesting is that instead of having to write Lib.init in Boot, Lift should look in Lib.jar for say /boot.xml which would tell Lift to execute Lib.init for you on startup. I think that would accomplish what you want, at the cost of lift searching through the jars. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Classpath management is one of OSGi's features. Another is dynamic service registry and dependency management. So following that route, the Lift framework would define an interface that exposes much of what is currently found in Boot. Modules (OSGi bundles) would create implementations of that interface and register them during startup (fortunately the details are usually handled automatically). Lift would also define a manager class that listens to the registry and does whatever bookkeeping is required when modules come and go. Eclipse RCP is a great example of this in action. Note that defining a framework on top OSGi can also be a slippery slope. RCP is a good example of that as well; it's an extensive framework on top of OSGi. So, the question is whether it's worth turning what is currently a straightforward boot process into something that is more modular though more complicated. If so, a good first step would be to define that manager class and interface since these could be wired together by any means (Scala, OSGi, Spring, etc.) without necessarily branching too far. I can take a look if you all think it's worth it (and if Heiko hasn't already). -Stephen --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---
[Lift] Re: Modularization of Lift code
Hi Glen... I actually do a lot of this - we have a product at work and i've just written a bunch of abstractions for work which just require me to do: MyLib.init In the boot file of a new application and then everything wires up - I couldn't think of anything more straightforward? The vast majority of stuff in lift is done with PF's, so you can pretty much just write them in external jars, and import them - my 3rd part stuff usually has a lift-webkit dependency so that I can just do the LiftRules.disptach.append stuff directly in the init method, but its really no biggy and saves boilerplate. So given your example, this scheme should work right? Cheers, Tim On Jul 27, 11:52 pm, glenn gl...@exmbly.com wrote: I'm interested in abstracting out useful features from my Lift applications for ease of reuse, but I haven't found an easy way to do it. I find myself creating a new Lift aplication for each feature, with all the baggage (bootstrapping, etc.), and I then have to do a lot of code modification to the application I'm adding the feature to in order to get it to work. For example, suppose I want to add role-based user login to an application that already has a User model just by dropping in a jar file with the new feature. I don't see how to do it without some boostrapping modifications. Has anyone really tried to modularize their Lift development. I'd be very interested in some suggestions. --~--~-~--~~~---~--~~ You received this message because you are subscribed to the Google Groups Lift group. To post to this group, send email to liftweb@googlegroups.com To unsubscribe from this group, send email to liftweb+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/liftweb?hl=en -~--~~~~--~~--~--~---