Some questions from a Java developer

9 views
Skip to first unread message

Jamie

unread,
Dec 10, 2007, 5:22:24 PM12/10/07
to liftweb
Hi all,

Liftweb looks great but there are a few things that are making me
nervous / confusing me a little:

- Could the Boot class and package be configurable in the LiftFilter?
- Could the Boot class get given a reference of the LiftServlet
instead of referring to it as a Singleton?
- What is the lifecycle of a snippet? Specifically around forms. In
the hellodarwin example, we're led astray at first before being
introduced to the "RequestVar" type, the explanation for why this is
needed and what it does confused me somewhat.
- Why AMQP instead of JMS?
- Why is the "S" class called "S"?
- Singletons are scattered liberally around which would make me
nervous in a Java context because of coupling and difficulty in
testing (e.g. use of LiftServlet in Boot or Users.findAll(...) etc.).
What am I missing?
- This pattern is used a lot:

class SomeClass {
object someProperty extends SomeObject;
}

and I have no idea why... (I suspect it's my lack of Scala knowledge)
- If someone out there is using liftweb with Hibernate, some best
practices would be great!
- The singletons with the same name as classes is a little confusing
but I think I'd get used to it pretty quick


Templating and snippets work really well.
Maven 2 / Eclipse / Jetty integration "Just Works" which is awesome.

David Pollak

unread,
Dec 10, 2007, 8:47:24 PM12/10/07
to lif...@googlegroups.com
Jamie,

Thanks for the questions, they're excellent.

Pardon my sometimes flip answers, but I've spend 12 hours with 3 year
old twins taking trains, eating in Chinatown, and watching a building
get demolished... plus I've had a glass of wine.

On Dec 10, 2007, at 2:22 PM, Jamie wrote:

>
> Hi all,
>
> Liftweb looks great but there are a few things that are making me
> nervous / confusing me a little:
>
> - Could the Boot class and package be configurable in the LiftFilter?

There's a way (Viktor, please jump in) of defining an alternate Boot
class in your web.xml file. But, not in LiftFilter.

> - Could the Boot class get given a reference of the LiftServlet
> instead of referring to it as a Singleton?

No. And why? Lots of stuff in lift references LiftServlet. It's a
Singleton. If we have to have a stupid-ass factory paradigm that's
implemented a different way for vended Singleton, then we're back to
Java hell. We're at the meta-meta-factory-factory blah blah blah
stuff. Sorry for coming down on this question, but in many cases,
Java stuff is over-thought out for no understandable reason. For
example, how many times do you substitute the XML parser in Java?

> - What is the lifecycle of a snippet? Specifically around forms. In
> the hellodarwin example, we're led astray at first before being
> introduced to the "RequestVar" type, the explanation for why this is
> needed and what it does confused me somewhat.

It depends on whether the snippet is a StatefulSnippet or not.

If it's not stateful, then a new instance of the snippet is created
each time the snippet is referenced during a render cycle.

However, functions that appear in the snippet may be bound to
instance or local variables in the snippet and those variables (and
the instance of the snippet that they're bound to) may have a life
beyond the current page rendering.

Sound confusing? Spend a little time familiarizing yourself with the
subtleties of how anonymous Scala functions are bound to variable
scope and then I think the answer may be more obvious.

> - Why AMQP instead of JMS?

Because AMQP is a wire standard rather than an API standard and I
believe the folks at LShift/Cohesive have a drop dead, kick ass
solution to messaging in RabbitMQ.

> - Why is the "S" class called "S"?

S is short for Stateful or State. All the Stateful stuff that
happens in a request goes through S. I wanted a short name because
it was used a lot, so I chose S.

> - Singletons are scattered liberally around which would make me
> nervous in a Java context because of coupling and difficulty in
> testing (e.g. use of LiftServlet in Boot or Users.findAll(...) etc.).
> What am I missing?

For the model related stuff, you need a Singleton to access the
appropriate methods for doing queries. If you did it with something
like "QueryManagerFactory.getQueryManager("user").findAll() it would
not be type safe.

Before you start jumping up and down yelling dependency injection,
consider that most of the actual dependencies are managed with
functions and partial functions. These are type safe. Stuff like
LiftServlet is a repository for functions, so in many ways,
LiftServlet is a factory, not a Singleton. For more, see http://
onestepback.org/articles/depinj/index.html

> - This pattern is used a lot:
>
> class SomeClass {
> object someProperty extends SomeObject;
> }
>
> and I have no idea why... (I suspect it's my lack of Scala knowledge)

objects are Singletons. This is kind of like saying:

class SomeClass {
val someProperty = new SomeObject
}

However, there are subtle reasons (mainly having to do with
reflection, but also having to do with class naming) why the object
syntax is preferred. For the reason that values are carried around
in heavier weight objects, see: http://blog.lostlake.org/index.php?/
archives/19-Keeping-the-meaning-with-the-bytes.html


> - If someone out there is using liftweb with Hibernate, some best
> practices would be great!

+1

> - The singletons with the same name as classes is a little confusing
> but I think I'd get used to it pretty quick

Yeah... it was tough for me for a while and I came to Scala via Ruby
(from Java) and Singletons are a lot more like Ruby classes... but
they're not.


>
>
> Templating and snippets work really well.

:-)

> Maven 2 / Eclipse / Jetty integration "Just Works" which is awesome.

Servlets were really well thought out. I've been using them for a
long long time and they just work. Given that Scala works like Java,
integration was a breeze.

Thanks,

David

>
> >

--
David Pollak
http://blog.lostlake.org

David Bernard

unread,
Dec 11, 2007, 4:22:35 AM12/11/07
to lif...@googlegroups.com
To Jamie,

Thanks for questions and answer, I copied/pasted into the wiki.

As you, I'm a java developper, and I've got lot of questions. and a lot of them are related to scala itself.
Scala isn't an other syntax for java, it's a full language with its idioms and paradigms. I suggest you a lot to take a look at the scala wiki, and to read scala by example (not finished yet myself).
You will learn that singleton could be "contextualizable" in scala...

As you, I've lot of interrogation about testability. And I'll do some exploration.

Thanks for you feedback and your interest.

To David P.,

FYI, dependency injection could be type safe (Guice is type safe, pico is type safe). IoC != Spring

/davidB

Viktor Klang

unread,
Dec 11, 2007, 7:15:03 AM12/11/07
to lif...@googlegroups.com
Hello Jamie, sorry for the long response time!
 
There is a perfectly nice way to define your own custom Bootloaders and place them anywhere you want on the classpath,
 
I recently added it to the wiki: http://www.liftweb.net/index.php/Web.xml check the bootloader section. :)
 
Cheers man!
 
-Viktor

 
--
_____________________________________
/                                                                 \
        /lift/ committer (www.liftweb.net )
      SGS member (Scala Group Sweden)
  SEJUG member (Swedish Java User Group)
            Coffee drinker (Skånerost)
\_____________________________________/

Jamie McCrindle

unread,
Dec 12, 2007, 5:31:46 AM12/12/07
to lif...@googlegroups.com
Hiya,

Thanks for taking the time to answer the questions.

I guess, for me, the biggest mental hurdle to overcome is the use of
Singletons (reflected in at least two of my questions). From a Java
perspective, I'm pretty comfortable that Dependency Injection trumps
Singletons by some margin. From your and David Bernard's answers it
sounds like it's not that clear cut in Scala. Apologies if this
becomes a DI vs. Singleton debate...

Other responses inline.

On Dec 11, 2007 1:47 AM, David Pollak <d...@athena.com> wrote:
>
> Jamie,
>
> Thanks for the questions, they're excellent.
>
> Pardon my sometimes flip answers, but I've spend 12 hours with 3 year
> old twins taking trains, eating in Chinatown, and watching a building
> get demolished... plus I've had a glass of wine.
>
>
> On Dec 10, 2007, at 2:22 PM, Jamie wrote:
>
> >
> > Hi all,
> >
> > Liftweb looks great but there are a few things that are making me
> > nervous / confusing me a little:
> >
> > - Could the Boot class and package be configurable in the LiftFilter?
>
> There's a way (Viktor, please jump in) of defining an alternate Boot
> class in your web.xml file. But, not in LiftFilter.
>
>
> > - Could the Boot class get given a reference of the LiftServlet
> > instead of referring to it as a Singleton?
>
> No. And why? Lots of stuff in lift references LiftServlet. It's a
> Singleton. If we have to have a stupid-ass factory paradigm that's
> implemented a different way for vended Singleton, then we're back to
> Java hell. We're at the meta-meta-factory-factory blah blah blah
> stuff. Sorry for coming down on this question, but in many cases,
> Java stuff is over-thought out for no understandable reason. For
> example, how many times do you substitute the XML parser in Java?

XML parsers are a sore point, oddly enough, as I had some code that
depended on a particular version (or above) of an XML parser and the
one that shipped with the JVM was different from the one that shipped
with the container was different from the one that another library in
the same project needed, but I try not to think about that... :)

> > - What is the lifecycle of a snippet? Specifically around forms. In
> > the hellodarwin example, we're led astray at first before being
> > introduced to the "RequestVar" type, the explanation for why this is
> > needed and what it does confused me somewhat.
>
> It depends on whether the snippet is a StatefulSnippet or not.
>
> If it's not stateful, then a new instance of the snippet is created
> each time the snippet is referenced during a render cycle.
>
> However, functions that appear in the snippet may be bound to
> instance or local variables in the snippet and those variables (and
> the instance of the snippet that they're bound to) may have a life
> beyond the current page rendering.
>
> Sound confusing? Spend a little time familiarizing yourself with the
> subtleties of how anonymous Scala functions are bound to variable
> scope and then I think the answer may be more obvious.

Being able to reuse snippets in different contexts on the same page
sounds great. I'll spend some more time looking into anonymous
functions and how they're bound to variable scope.

Does it mean that if you use RequestVar you can only have a single
instance of that snippet on a page? I definitely need to look more
deeply at it. *goes through Scala by Example and the Scala Reference
looking for anonymous functions and scope...* *some time later without
success*... *attempts a lot of println's, debugging and varied code*

Ok, so, in those examples, param("whoField") doesn't ever come up with
a value since the name of the field is something like
"F1197399626136527000_HZB" (as in println(param("whoField")))

The results of the post are somehow "routed" through to the anonymous
functions, I'm guessing that the strange name is a hash used to look
them up?

_functionsMap? How does it stay alive between requests? *searches for
some time, experiments some more... SFuncHolder... ThreadGlobal...*
it's clearly magic...

Ah, worked out what RequestVar is. I think the anonymous function
scope may have been a red herring, it's more that RequestVar is backed
by the requestState hash in S, so it behaves a little like
request.setAttribute("") in servlet terms.

Experimented putting two snippets that use RequestVar on the same page
and they come up with the same value. Another downside to using
Singletons is that it makes it less clear where the dependencies are
i.e. without looking at what RequestVar code, it's not clear that it
has a dependency on S. and the side effect of storing state in S.

> > - Why AMQP instead of JMS?
>
> Because AMQP is a wire standard rather than an API standard and I
> believe the folks at LShift/Cohesive have a drop dead, kick ass
> solution to messaging in RabbitMQ.

Heh, I get it. With a Java hat on, I think JMS would be the obvious
choice. With a liftweb hat on, wire protocol with interoperability
outside of Java makes sense (there are things outside of Java???
rediculous).

> > - Why is the "S" class called "S"?
>
> S is short for Stateful or State. All the Stateful stuff that
> happens in a request goes through S. I wanted a short name because
> it was used a lot, so I chose S.

JavaDevelopersLoveReallyLongClassNames jCtrl+space

> > - Singletons are scattered liberally around which would make me
> > nervous in a Java context because of coupling and difficulty in

> > testing ( e.g. use of LiftServlet in Boot or Users.findAll(...) etc.).


> > What am I missing?
>
> For the model related stuff, you need a Singleton to access the
> appropriate methods for doing queries. If you did it with something
> like "QueryManagerFactory.getQueryManager("user").findAll() it would
> not be type safe.
>
> Before you start jumping up and down yelling dependency injection,
> consider that most of the actual dependencies are managed with
> functions and partial functions. These are type safe. Stuff like
> LiftServlet is a repository for functions, so in many ways,
> LiftServlet is a factory, not a Singleton. For more, see http://
> onestepback.org/articles/depinj/index.html

Dependency Injection!

I can see how in more expressive languages some of the advantages of
DI for testing fall away. I have been in quite a few projects where it
has been handy to substitute the implementation of a particular class
for another one. I think I need to go and look at the Scala docs about
"contextualizable" singletons.

Again, I may have been coming from the wrong angle, I was hoping that
Scala / lift would make DI less verbose when I may need to look at it
removing the need for DI. I'm not quite sold, though...

> > - This pattern is used a lot:
> >
> > class SomeClass {
> > object someProperty extends SomeObject;
> > }
> >
> > and I have no idea why... (I suspect it's my lack of Scala knowledge)
>
> objects are Singletons. This is kind of like saying:
>
> class SomeClass {
> val someProperty = new SomeObject
> }
>
> However, there are subtle reasons (mainly having to do with
> reflection, but also having to do with class naming) why the object
> syntax is preferred. For the reason that values are carried around
> in heavier weight objects, see: http://blog.lostlake.org/index.php?/
> archives/19- Keeping-the-meaning-with-the-bytes.html

+1 for keeping the meaning with the bytes.

David Pollak

unread,
Dec 12, 2007, 7:57:38 AM12/12/07
to lif...@googlegroups.com
Jamie,

There's the lift Model Singletons which are Singletons in the Java
kind of way. There's one and there's a fair amount of hard coded
functionality: they access a database table named foo, etc. You can
change the database it goes to, but the fact remains that backing
store is an RDBMS. I'm not sure how DI would help here?

Helpers is a singleton, but Helpers carries no state and quite
frankly, you should not change the behavior of toInt, etc.

LiftServlet is a singleton, but it is there to be the place that
holds function pointers to define behaviors in your application. It
is in reality a factory that vends the behaviors defined in Boot.

So, then there's S.

S manages state. But it does it in a fairly clever (if I do say so
myself) way. All the state is managed in thread local variables.
S.init() is called and it sets up the thread local variables and then
executes a passed function. It also does some brokering to the
HttpContext (this is a hard-coded dependency that could be changed.)
In some cases, at the end of S.init stuff is shuttled from thread
local variables back into HttpContext. I'm not sure if I can
conceive of a reason to change S up to be something else.

>
>>> - What is the lifecycle of a snippet? Specifically around forms. In
>>> the hellodarwin example, we're led astray at first before being
>>> introduced to the "RequestVar" type, the explanation for why this is
>>> needed and what it does confused me somewhat.
>>
>> It depends on whether the snippet is a StatefulSnippet or not.
>>
>> If it's not stateful, then a new instance of the snippet is created
>> each time the snippet is referenced during a render cycle.
>>
>> However, functions that appear in the snippet may be bound to
>> instance or local variables in the snippet and those variables (and
>> the instance of the snippet that they're bound to) may have a life
>> beyond the current page rendering.
>>
>> Sound confusing? Spend a little time familiarizing yourself with the
>> subtleties of how anonymous Scala functions are bound to variable
>> scope and then I think the answer may be more obvious.
>
> Being able to reuse snippets in different contexts on the same page
> sounds great. I'll spend some more time looking into anonymous
> functions and how they're bound to variable scope.
>
> Does it mean that if you use RequestVar you can only have a single
> instance of that snippet on a page? I definitely need to look more
> deeply at it. *goes through Scala by Example and the Scala Reference
> looking for anonymous functions and scope...* *some time later without
> success*... *attempts a lot of println's, debugging and varied code*

RequestVars share their value through the scope of the current HTTP
request. They have no value at the beginning of request servicing
and their value is discarded at the end of request processing. They
are helpful to share values across many snippets.

SessionVars are type-safe variables that map pretty directly to
HttpSession attributes. Put stuff in and they are available for the
life of the Session.

Snippet instance variables are only available to that snippet
instance. If you've got multiple functions bound to instance (or
local) variables in a snippet, they can share those variables as part
of a form submission.

>
> Ok, so, in those examples, param("whoField") doesn't ever come up with
> a value since the name of the field is something like
> "F1197399626136527000_HZB" (as in println(param("whoField")))

Right. lift chooses random numbers to represent the names of form
elements and binds the form elements to functions. This is for
security and to abstract away the concept of an HTTP parameter.

>
> The results of the post are somehow "routed" through to the anonymous
> functions, I'm guessing that the strange name is a hash used to look
> them up?

Yep.

>
> _functionsMap? How does it stay alive between requests? *searches for
> some time, experiments some more... SFuncHolder... ThreadGlobal...*
> it's clearly magic...

It's in the LiftSession (on instance per HTTP Session, and yes, you
can define session factories so you can subclass LiftSession).
LiftSession is bound into the HTTP Session.

>
> Ah, worked out what RequestVar is. I think the anonymous function
> scope may have been a red herring, it's more that RequestVar is backed
> by the requestState hash in S, so it behaves a little like
> request.setAttribute("") in servlet terms.

Not really. The values are thrown away at the end of servicing the
current request.

>
> Experimented putting two snippets that use RequestVar on the same page
> and they come up with the same value. Another downside to using
> Singletons is that it makes it less clear where the dependencies are
> i.e. without looking at what RequestVar code, it's not clear that it
> has a dependency on S. and the side effect of storing state in S.

In the case of RequestVars and SessionVars, the logic is simple: they
store something that has is available for a certain lifetime. There
are other ways to store stuff (e.g., Snippet instance variables). I
can't imagine using DI or something to change the behavior of
RequestVars or SessionVars.

All state in lift is stored in S or the database or managed by you
(e.g. filesystem.) It's not as pure as Haskell, but it's pretty well
defined (I got into a discussion with some other Java guys who were
complaining about the amount of stuff in S. I took the position that
I still hold: all state is in S.)

The place where we might need to change behavior what S does for
"session" backing store. Right now, it's tied to HttpSession. As we
work on the testing framework more, it may turn out that we need to
have mocks for the session and these mocks will have to be supported
in S (or we can just write mock HttpSession).

The questions are good, but go with the Scala and lift flow for a
couple of months and I think things will make more sense.


>
>>> - Why AMQP instead of JMS?
>>
>> Because AMQP is a wire standard rather than an API standard and I
>> believe the folks at LShift/Cohesive have a drop dead, kick ass
>> solution to messaging in RabbitMQ.
>
> Heh, I get it. With a Java hat on, I think JMS would be the obvious
> choice. With a liftweb hat on, wire protocol with interoperability
> outside of Java makes sense (there are things outside of Java???
> rediculous).

:-)

>
>>> - Why is the "S" class called "S"?
>>
>> S is short for Stateful or State. All the Stateful stuff that
>> happens in a request goes through S. I wanted a short name because
>> it was used a lot, so I chose S.
>
> JavaDevelopersLoveReallyLongClassNames jCtrl+space

Scala has weak IDE support and my fingers like to type short things :-)

>
>>> - Singletons are scattered liberally around which would make me
>>> nervous in a Java context because of coupling and difficulty in
>>> testing ( e.g. use of LiftServlet in Boot or Users.findAll(...)
>>> etc.).
>>> What am I missing?
>>
>> For the model related stuff, you need a Singleton to access the
>> appropriate methods for doing queries. If you did it with something
>> like "QueryManagerFactory.getQueryManager("user").findAll() it would
>> not be type safe.
>>
>> Before you start jumping up and down yelling dependency injection,
>> consider that most of the actual dependencies are managed with
>> functions and partial functions. These are type safe. Stuff like
>> LiftServlet is a repository for functions, so in many ways,
>> LiftServlet is a factory, not a Singleton. For more, see http://
>> onestepback.org/articles/depinj/index.html
>
> Dependency Injection!
>
> I can see how in more expressive languages some of the advantages of
> DI for testing fall away. I have been in quite a few projects where it
> has been handy to substitute the implementation of a particular class
> for another one. I think I need to go and look at the Scala docs about
> "contextualizable" singletons.
>
> Again, I may have been coming from the wrong angle, I was hoping that
> Scala / lift would make DI less verbose when I may need to look at it
> removing the need for DI. I'm not quite sold, though...

Most of the stuff that you think of DI is handled in many cases more
subtly by functions. The stuff that looks like Singletons in lift
are often more like factories (or repositories) for the functions
that do the actual work.

Please keep on asking questions.

Jamie McCrindle

unread,
Dec 12, 2007, 5:34:02 AM12/12/07
to lif...@googlegroups.com
Great stuff, thanks Viktor

Viktor Klang

unread,
Dec 12, 2007, 5:10:11 PM12/12/07
to lif...@googlegroups.com
Glad you like it :)

Cheers,
Viktor

Sent from my iPhone

On Dec 12, 2007, at 11:34, "Jamie McCrindle"

adyut

unread,
Dec 13, 2007, 5:37:32 AM12/13/07
to liftweb
Hi everybody,

I have some questions regarding life-cycle of instance(class level)
variables
declared in .scala files of snippet package

in my one .scala file I've


class ClassName1{

var objClass2: ClassName2 = null

def def1(xhtml: Group): NodeSeq ={
objClass2 = new ClassName2

//some code
}

def def2(xhtml: Group): NodeSeq ={
if(objClass2 == Null){
Console.println("Object Null");
}else{
Console.println("Object Not Null");
}

//some code
}

and in html file I've code snippet like -

<lift:snippet type="ClassName1:def1">
<lift:snippet type="ClassName1:def2">
</lift:snippet>
</lift:snippet>

on execution this gives me output
Object Null

the result is same even if I change html snippet as follows -

<lift:snippet type="ClassName1:def1">
</lift:snippet>

<lift:snippet type="ClassName1:def2">
</lift:snippet>

Is, each execution of "<lift:snippet type="ClassName1:def2">"
creating new instance of ClassName1 class and calls def??

how to keep data persist between such two snippet call of same
snippet class???
I used RequestVar to get value of variable objClass2 in next snippet
call
Is there any other way?




On Dec 13, 3:10 am, Viktor Klang <viktor.kl...@gmail.com> wrote:
> Glad you like it :)
>
> Cheers,
> Viktor
>
> Sent from my iPhone
>
> On Dec 12, 2007, at 11:34, "Jamie McCrindle"
>
> <jamiemccrin...@gmail.com> wrote:
>
> > Great stuff, thanks Viktor
>
> > On Dec 11, 2007 12:15 PM, Viktor Klang <viktor.kl...@gmail.com> wrote:
> >> Hello Jamie, sorry for the long response time!
>
> >> There is a perfectly nice way to define your own custom Bootloaders
> >> and
> >> place them anywhere you want on the classpath,
>
> >> I recently added it to the wiki:http://www.liftweb.net/index.php/Web.xml
> >> check the bootloader section. :)
>
> >> Cheers man!
>
> >> -Viktor
>

David Bernard

unread,
Dec 13, 2007, 5:58:55 AM12/13/07
to lif...@googlegroups.com
Hi,

I don't the response, but I expect it should create one instance by <lift:snippet> tag.
About your second example, do you want the display layout have impact on the code flow ?
Me no, image you change the display layout, you don't want that impact the code flow.

> how to keep data persist between such two snippet call of same
> snippet class???
> I used RequestVar to get value of variable objClass2 in next snippet
> call
> Is there any other way?

Why don't you use bind() ?
bind allow you do replace node into your template

something like (not tested)

<lift:snippet type="ClassName1:def1">

<ClassName1:def2>
</lift:snippet>

...
import net.liftweb.util.Helpers._

class ClassName1{
var objClass2: ClassName2 = null

def def1(xhtml: Group): NodeSeq ={
objClass2 = new ClassName2

//some code
bind("ClassName1", xhtml,
"def2" --> def2(xhtml)
)
}

def def2(xhtml: Group): NodeSeq ={
if(objClass2 == Null){
Console.println("Object Null");
}else{
Console.println("Object Not Null");
}

//some code
}

if def2 don't manipulate xhtml, then remove it from the parameter list.

Is it clear ?

/davidB

Jamie McCrindle

unread,
Dec 13, 2007, 5:39:02 AM12/13/07
to lif...@googlegroups.com
Hiya,

Thanks for the answers. I'll spend some more time with Lift and Scala
before asking more questions but this has been a great start.

> There's the lift Model Singletons which are Singletons in the Java
> kind of way. There's one and there's a fair amount of hard coded
> functionality: they access a database table named foo, etc. You can
> change the database it goes to, but the fact remains that backing
> store is an RDBMS. I'm not sure how DI would help here?

"Users" would be a good example of where this could be a problem.
Quite a few organisations use LDAP (or ActiveDirectory) for storing
their user / authentication information. Any code that uses a Users
singleton that presupposes an RDBMS would not be reusable.

That said, it would only be a problem for "library" type code as it is
rare to use 2 different "Users" backing stores in the same project.

> LiftServlet is a singleton, but it is there to be the place that
> holds function pointers to define behaviors in your application. It
> is in reality a factory that vends the behaviors defined in Boot.

Does this mean that it would not be possible to have two LiftFilter's
defined in a web.xml without having them potentially clash? Not that
you'd necessarily want to...

> > Ah, worked out what RequestVar is. I think the anonymous function
> > scope may have been a red herring, it's more that RequestVar is backed
> > by the requestState hash in S, so it behaves a little like
> > request.setAttribute("") in servlet terms.
>
> Not really. The values are thrown away at the end of servicing the
> current request

request.setAttribute(...) will also throw values away at the end of
servicing the current request...?

> The questions are good, but go with the Scala and lift flow for a
> couple of months and I think things will make more sense.

Definitely. Thanks again for answering my questions in detail.

cheers,
j.

> > Experimented putting two snippets that use RequestVar on the same page

David Pollak

unread,
Dec 13, 2007, 6:22:57 AM12/13/07
to lif...@googlegroups.com
Howdy,

On Dec 13, 2007, at 2:37 AM, adyut wrote:

>
> Hi everybody,
>
> I have some questions regarding life-cycle of instance(class level)
> variables
> declared in .scala files of snippet package
>
> in my one .scala file I've
>
>
> class ClassName1{
>
> var objClass2: ClassName2 = null
>
> def def1(xhtml: Group): NodeSeq ={
> objClass2 = new ClassName2
>
> //some code
> }
>
> def def2(xhtml: Group): NodeSeq ={
> if(objClass2 == Null){
> Console.println("Object Null");
> }else{
> Console.println("Object Not Null");
> }
>
> //some code
> }

Change to ClassName1 extends StatefulSnippet and the same instance
will be used to service the page for the entire request.

>
> and in html file I've code snippet like -
>
> <lift:snippet type="ClassName1:def1">
> <lift:snippet type="ClassName1:def2">
> </lift:snippet>
> </lift:snippet>
>
> on execution this gives me output
> Object Null
>
> the result is same even if I change html snippet as follows -
>
> <lift:snippet type="ClassName1:def1">
> </lift:snippet>
>
> <lift:snippet type="ClassName1:def2">
> </lift:snippet>
>
> Is, each execution of "<lift:snippet type="ClassName1:def2">"
> creating new instance of ClassName1 class and calls def??


For snippets that are not "stateful", yes.

>
> how to keep data persist between such two snippet call of same
> snippet class???

Make the snippet stateful.

> I used RequestVar to get value of variable objClass2 in next snippet
> call
> Is there any other way?

Yes... :-) See above.

Thanks,

David

--
David Pollak
http://blog.lostlake.org

David Pollak

unread,
Dec 13, 2007, 6:59:21 AM12/13/07
to lif...@googlegroups.com

On Dec 13, 2007, at 2:39 AM, Jamie McCrindle wrote:

>
> Hiya,
>


> Thanks for the answers. I'll spend some more time with Lift and Scala
> before asking more questions but this has been a great start.

Asking how questions (putting the why questions aside for a little
bit) might be a good way to approach things. In a few months, once
you've gotten some Scala and lift idioms under your belt, there will
likely be fewer why questions.

But, questions are a great way to learn. This list is about
questions and sharing perspectives. I may be a little flip about my
answers (and others may have some fun too), but we all encourage you
to ask, explore, learn, contribute.

>
>> There's the lift Model Singletons which are Singletons in the Java
>> kind of way. There's one and there's a fair amount of hard coded
>> functionality: they access a database table named foo, etc. You can
>> change the database it goes to, but the fact remains that backing
>> store is an RDBMS. I'm not sure how DI would help here?
>
> "Users" would be a good example of where this could be a problem.
> Quite a few organisations use LDAP (or ActiveDirectory) for storing
> their user / authentication information. Any code that uses a Users
> singleton that presupposes an RDBMS would not be reusable.

In the not too distant future, you'll define backing store by mixing
in a trait. For example:

object User extends User with Proto with RDBMSBacking

object User extends User with Proto with LDAPBacking

Once we get the backing store stuff decoupled from some of the other
pieces, it will be a static code-level change, but a very simple one.

>
> That said, it would only be a problem for "library" type code as it is
> rare to use 2 different "Users" backing stores in the same project.

That's right. Plus, the semantics for manipulation of RDBMS might be
subtly different than XML (e.g., transactional vs. non-transactional)
and that has to be baked in at compile time.

>
>> LiftServlet is a singleton, but it is there to be the place that
>> holds function pointers to define behaviors in your application. It
>> is in reality a factory that vends the behaviors defined in Boot.
>
> Does this mean that it would not be possible to have two LiftFilter's
> defined in a web.xml without having them potentially clash? Not that
> you'd necessarily want to...

Maybe. LiftFilter is not a singleton. If push ever came to shove,
the same thing could be done with LiftServlet that's done with S...
using ThreadLocal storage and changing the way return values are
calculated on a thread-by-thread basis. This would likely come into
play if someone wanted to put multiple lift projects into a single
WAR file. If that becomes a requirement, lift has graduated far
beyond what it is today. :-)


>
>>> Ah, worked out what RequestVar is. I think the anonymous function
>>> scope may have been a red herring, it's more that RequestVar is
>>> backed
>>> by the requestState hash in S, so it behaves a little like
>>> request.setAttribute("") in servlet terms.
>>
>> Not really. The values are thrown away at the end of servicing the
>> current request
>
> request.setAttribute(...) will also throw values away at the end of
> servicing the current request...?

Didn't even see that (it's been a long time since I've done hardcore
servlet work [8 or 9 years]... Viktor and others have been poking me
to get my head out of the ground and get with the new millennium.)
Using RequestVar is type-safe (a good thing.) The fact that it's
backed by a Hash that S manages rather than something ServletRequest
manages makes no difference to the developer.

>
>> The questions are good, but go with the Scala and lift flow for a
>> couple of months and I think things will make more sense.
>
> Definitely. Thanks again for answering my questions in detail.

Sure thing!

Thanks,

David

Viktor Klang

unread,
Dec 13, 2007, 7:22:52 AM12/13/07
to lif...@googlegroups.com


>On 12/13/07, David Pollak <d...@athena.com> wrote:

>object User extends User with Proto with RDBMSBacking

>object User extends User with Proto with LDAPBacking
 
This'd be way cool :)

>
>> LiftServlet is a singleton, but it is there to be the place that
>> holds function pointers to define behaviors in your application.  It
>> is in reality a factory that vends the behaviors defined in Boot.
>
> Does this mean that it would not be possible to have two LiftFilter's
> defined in a web.xml without having them potentially clash? Not that
> you'd necessarily want to...
 
It's possible in theory, but we'd have to do some rearrangements to allow multiple LiftFilters mapped in the same web.xml,
but it'd be perfectly doable :)


>
>>> Ah, worked out what RequestVar is. I think the anonymous function
>>> scope may have been a red herring, it's more that RequestVar is
>>> backed
>>> by the requestState hash in S, so it behaves a little like
>>> request.setAttribute("") in servlet terms.
>>
>> Not really.  The values are thrown away at the end of servicing the
>> current request
>
> request.setAttribute(...) will also throw values away at the end of
> servicing the current request...?

>Didn't even see that (it's been a long time since I've done hardcore
>servlet work [8 or 9 years]... Viktor and others have been poking me
>to get my head out of the ground and get with the new millennium.)
 
Haha, I don't remember me putting it _that_ way before... ;)

>Using RequestVar is type-safe (a good thing.)  The fact that it's
>backed by a Hash that S manages rather than something ServletRequest
>manages makes no difference to the developer.
 
Yes, and this also decouples things from HttpSession, which is A Good thing (tm)
 

 

Cheers dudes!
 
-Viktor

Jörn Zaefferer

unread,
Dec 17, 2007, 5:29:35 PM12/17/07
to liftweb
On Dec 12, 1:57 pm, David Pollak <d...@athena.com> wrote:
> The place where we might need to change behavior what S does for
> "session" backing store. Right now, it's tied to HttpSession. As we
> work on the testing framework more, it may turn out that we need to
> have mocks for the session and these mocks will have to be supported
> in S (or we can just write mock HttpSession).

Spring provides great mock implementations (spring-mock.jar). I
wouldn't want to reinvent the wheel there.

Jörn

Jörn Zaefferer

unread,
Dec 17, 2007, 5:33:50 PM12/17/07
to liftweb
On Dec 13, 12:59 pm, David Pollak <d...@athena.com> wrote:

> > "Users" would be a good example of where this could be a problem.
> > Quite a few organisations use LDAP (or ActiveDirectory) for storing
> > their user / authentication information. Any code that uses a Users
> > singleton that presupposes an RDBMS would not be reusable.
>
> In the not too distant future, you'll define backing store by mixing
> in a trait. For example:
>
> object User extends User with Proto with RDBMSBacking
>
> object User extends User with Proto with LDAPBacking
>
> Once we get the backing store stuff decoupled from some of the other
> pieces, it will be a static code-level change, but a very simple one.

I'm currently working on a project where user information is read from
an LDAP server, but any additional information is stored on the local
RDBMS. Could you handle that with those Backing-Traits, too?

Jörn

David Pollak

unread,
Dec 18, 2007, 11:27:34 PM12/18/07
to lif...@googlegroups.com

I think so. I'd have to see exactly how your object hierarchy looks,
but it should be doable.

>
> Jörn

Reply all
Reply to author
Forward
0 new messages