AOP and DI

4 views
Skip to first unread message

Jonathan Logue

unread,
Jan 22, 2008, 5:06:13 AM1/22/08
to ColdSpring-Users
I am getting some behavior that I am not sure is expected.

I have set up proxies on all my services and I am using autowire by
name to inject them into other services. This works well when I ask
for a bean from the MG framework, but when I access one that has been
injected, I get the proxy object which does not appear to have
correctly initialized dependency beans using the
getService().getObject() method. So - I am just curious about the
proper implementation of injecting proxied beans and using them.

Thanks

Tom Chiverton

unread,
Jan 22, 2008, 8:37:11 AM1/22/08
to coldspri...@googlegroups.com
On 22/01/2008, Jonathan Logue <jonath...@gmail.com> wrote:
> I have set up proxies on all my services and I am using autowire by
> name to inject them into other services. This works well when I ask

I would inject the underlying Manager into other Managers that require
them, rather than injecting Services.
You're mixing your layers otherwise.

--
Tom

Brian Kotek

unread,
Jan 22, 2008, 8:44:39 AM1/22/08
to coldspri...@googlegroups.com
I'm a bit confused because what I call Services are what other people call Managers. Even so, I inject Services into non-Services all the time. I usually *want* things to have to go through the Service layer, even if the caller is some other component in the Model.

To Jonathan, I don't really follow what you are saying. If you aren't using AOP, then calling a method on the proxied object should just forward that method call to the original, underlying object. I think you'll have to explain further or provide a few code snippets.

Tom Chiverton

unread,
Jan 22, 2008, 9:02:00 AM1/22/08
to coldspri...@googlegroups.com
On 22/01/2008, Brian Kotek <bria...@gmail.com> wrote:
> I'm a bit confused because what I call Services are what other people call
> Managers. Even so, I inject Services into non-Services all the time. I

To be clear:
By 'Manager' I mean a Bean that is not called by the end-user
application (CFML page or Flex RemoteObject).
'Services' wrap Managers and do things like converting argument/result
types and implementing secutiry.

If I call barService.foo(), I wouldn't want those (expensive)
conversions etc. done multiple times, so if the barManager needs to
use something from fooManager, it uses the Manager, not the Service.

--
Tom

Jonathan Logue

unread,
Jan 22, 2008, 10:30:54 AM1/22/08
to ColdSpring-Users
Sorry for the confusion - I am referring to managers which are
primarily designed to deal with one class of object. For example, I
want the Company manager to be aware of an Employee manager. I use
this for returning hierarchical XML data as well as supporting
cascading deletes programmatically. But, when I call
getEmployeeManager() from within the CompanyManager, I get the issue I
am describing.


On Jan 22, 6:02 am, "Tom Chiverton" <tom.chiver...@gmail.com> wrote:

Brian Kotek

unread,
Jan 22, 2008, 12:37:21 PM1/22/08
to coldspri...@googlegroups.com
On Jan 22, 2008 9:02 AM, Tom Chiverton <tom.ch...@gmail.com> wrote:

To be clear:
By 'Manager' I mean a Bean that is not called by the end-user
application (CFML page or Flex RemoteObject).
'Services' wrap Managers and do things like converting argument/result
types and implementing secutiry.

Yeah I think here you may want to reconsider this definition, because I beleive that you are defining a Manager in a very different way than most people would. Managers and Services are used interchangeably as a description of the interface to the Model. I like the term "service" because of the prevalence of the "service-oriented architecture" idea. In that context, most people would understand what a Service is supposed to do (encapsulate and provide an interface to the Model). It sounds like you are using the term "manager" to describe your Business Objects/Domain Objects. If I'm understanding you correctly and this is indeed what you mean, I think you're going to encounter a lot of confusion when trying to communicate this to other people. Am I misunderstanding you on this?
 

If I call barService.foo(), I wouldn't want those (expensive)
conversions etc. done multiple times, so if the barManager needs to
use something from fooManager, it uses the Manager, not the Service.

This might be a totally separate discussion. I suppose it depends on whether the Service is doing other things (Logging, transaction management, etc.) that need to be maintained even for an internal method call.

Dinner

unread,
Jan 22, 2008, 1:23:45 PM1/22/08
to coldspri...@googlegroups.com

Wow. This is the reason I signed up to this group! (Hello People!)

When Sean, on another list, said something about having "fat" business
objects, vs. "fat" services, it got me to wondering...

I'm digging AOP-- I use it in dojo and it's really swell, and I use it
in CF and it's really swell, but I'm concerned about the overhead of
using ColdSpring on transient objects.

I haven't tried using it on transient stuff yet, and I haven't set up
the eclipse profiling tools, which would make it a bit easier to see
what happens when I try X...

Anyways, maybe I'm interpreting what Sean meant incorrectly-- I doubt
he was referring to fat transient objects (?), but -- I'm trying to
think of the "best places" to do AOP with CF, what level, sotospeak.

I've mostly been using AOP for "Services", and passing the services
around to other services, so far.

So, in a round about way, I'm wondering if it's better to "aspect-ize"
at the service level, or "lower".

I think lower would give more control, but it would require a lot of
advice, and I also wonder about CF object instantiation-- how much
overhead is there?

Should I keep the bulk of things that "do stuff" around in the
application scope? Pass a user ID instead of a user object, so to
speak?

Man, I'm sorry I can't be more clear (or specific) in what I'm asking about.
Probably the answers totally depend on what you're trying to
achieve, or somesuch. :-P

I need more coffee. =]

--
Fortune does not change men, it unmasks them.
Suzanne Necker

Dinner

unread,
Jan 22, 2008, 2:29:42 PM1/22/08
to coldspri...@googlegroups.com
On Jan 22, 2008 8:30 AM, Jonathan Logue <jonath...@gmail.com> wrote:
>
> Sorry for the confusion - I am referring to managers which are
> primarily designed to deal with one class of object. For example, I
> want the Company manager to be aware of an Employee manager. I use
> this for returning hierarchical XML data as well as supporting
> cascading deletes programmatically. But, when I call
> getEmployeeManager() from within the CompanyManager, I get the issue I
> am describing.

Apologies for the total hijack! *blush*

You said it worked from "within the MG framework" but not from somewhere else?

Could it be a beanfactory issue?

Could you give some more info as to what works and what doesn't?

--
Actions lie louder than words.
Carolyn Wells

Jonathan Logue

unread,
Jan 22, 2008, 3:49:39 PM1/22/08
to ColdSpring-Users
>Apologies for the total hijack! *blush*

Happens to the best of us ;-)

I am trying to understand how to use proxied singleton objects when
they are injected using the autowire feature.

So in my ColdSpring config file, an example would be this....

<bean id="BeanA class="coldspring.aop.framework.ProxyFactoryBean">
<property name="target">
<bean class="path.to.BeanA" autowire="byName" />
</property>
</bean>

<bean id="BeanB class="coldspring.aop.framework.ProxyFactoryBean">
<property name="target">
<bean class="path.to.BeanB" autowire="byName" />
</property>
</bean>

In BeanB, I have...

<cffunction name="setBeanA" returnType="void" access="public"
output="false">
<cfargument name="BeanA" type="any" required="yes" />
<cfset variables.BeanA = arguments.BeanA />
</cffunction>

<cffunction name="getBeanA" returnType="any" access="public"
output="false">
<cfreturn variables.BeanA />
</cffunction>

When I call getBeanA() from within BeanB, it is returning the proxy
object, which makes sense. So, if I use getBeanA().getObject() I get
an instance of my unvarnished bean, but it has not been properly
initialized and errors on any methods that rely upon injection into
it. The whole thing works without using proxy objects, so I don't know
if it is a bug, or if that usage is unsupported, or if there is some
correct way to do what I need to do.



On Jan 22, 11:29 am, Dinner <valliants...@gmail.com> wrote:

Jonathan Logue

unread,
Jan 22, 2008, 4:32:30 PM1/22/08
to ColdSpring-Users
>then calling a method on the proxied object should just forward that method call to the original, underlying object.

Brian - it does not appear to be working this way. In the example
above, if ( inside BeanB ) I ask for getBeanA().beanAMethod(), it
tells me the latter method does not exist. Again, it works when I use
MG's mechanism for retrieving a bean: getModelGlue().getBean("BeanA").

These beans extend base classes in my application, so it is entirely
possible that my usage is not expected or supported.

Tom Chiverton

unread,
Jan 23, 2008, 2:45:41 PM1/23/08
to coldspri...@googlegroups.com
On 22/01/2008, Brian Kotek <bria...@gmail.com> wrote:
> Yeah I think here you may want to reconsider this definition, because I
> beleive that you are defining a Manager in a very different way than most
> people would. Managers and Services are used interchangeably as a
> description of the interface to the Model. I like the term "service" because
> of the prevalence of the "service-oriented architecture" idea.

OK, I'm open to getting my words corrected :-)
So the things that RemoteFactoryBean makes are Services, we agree there, right ?
What's the correct term for the objects that they 'wrap' ?

> using the term "manager" to describe your Business Objects/Domain Objects.
> If I'm understanding you correctly and this is indeed what you mean, I think
> you're going to encounter a lot of confusion when trying to communicate this
> to other people. Am I misunderstanding you on this?

Ahh, answer my own question ... I think we're just having a
terminology clash, not a misunderstanding.
So I'd have com.falkensweb.project.services.fooService and that would
be an AOP'ing facade to com.falkensweb.project.buisnessObject.foo ? I
find com.falkensweb.project.manager.fooManager more obvious as to
what is what, esp if there are a half dozen BO and Servicess.

> > If I call barService.foo(), I wouldn't want those (expensive)
> > conversions etc. done multiple times, so if the barManager needs to
> > use something from fooManager, it uses the Manager, not the Service.
>
> This might be a totally separate discussion. I suppose it depends on whether
> the Service is doing other things (Logging, transaction management, etc.)
> that need to be maintained even for an internal method call.

In my current production usage of AOP, the buisness objects
('managers') are fairly simple, mostly just wrappers around Reactor
CRUD, search or custom Gateway methods.
AOP provides try/catch and security via tokens (i.e. sessions without
the CF scope), as such no I don't *think* that needs to be done in
calls between BOs...

--
Tom
Damn, I thought I had this sussed :-)

Peter J. Farrell

unread,
Jan 23, 2008, 3:08:13 PM1/23/08
to coldspri...@googlegroups.com
Tom Chiverton said the following on 1/23/2008 1:45 PM:
On 22/01/2008, Brian Kotek <bria...@gmail.com> wrote:
  
Yeah I think here you may want to reconsider this definition, because I
beleive that you are defining a Manager in a very different way than most
people would. Managers and Services are used interchangeably as a
description of the interface to the Model. I like the term "service" because
of the prevalence of the "service-oriented architecture" idea.
    
OK, I'm open to getting my words corrected :-)
So the things that RemoteFactoryBean makes are Services, we agree there, right ?
What's the correct term for the objects that they 'wrap' ?

  
No, RemoteFactoryBean creates a proxy to your service  (a.k.a. manager).

.pjf

Tom Chiverton

unread,
Jan 23, 2008, 3:35:12 PM1/23/08
to coldspri...@googlegroups.com
On 23/01/2008, Peter J. Farrell <pe...@mach-ii.com> wrote:
> No, RemoteFactoryBean creates a proxy to your service (a.k.a. manager).

OK.
So I should say 'remote facade' or 'proxy' or similar instead of 'Service' ?

--
Tom

Brian Kotek

unread,
Jan 23, 2008, 4:42:39 PM1/23/08
to coldspri...@googlegroups.com
On Jan 23, 2008 2:45 PM, Tom Chiverton <tom.ch...@gmail.com> wrote:

On 22/01/2008, Brian Kotek <bria...@gmail.com> wrote:
> Yeah I think here you may want to reconsider this definition, because I
> beleive that you are defining a Manager in a very different way than most
> people would. Managers and Services are used interchangeably as a
> description of the interface to the Model. I like the term "service" because
> of the prevalence of the "service-oriented architecture" idea.

OK, I'm open to getting my words corrected :-)
So the things that RemoteFactoryBean makes are Services, we agree there, right ?
What's the correct term for the objects that they 'wrap' ?

The RemoteFactoryBean creates a Remote Proxy. The Proxy is wrapping calls to the underlying Service.
 

> using the term "manager" to describe your Business Objects/Domain Objects.
> If I'm understanding you correctly and this is indeed what you mean, I think
> you're going to encounter a lot of confusion when trying to communicate this
> to other people. Am I misunderstanding you on this?

Ahh, answer my own question ... I think we're just having a
terminology clash, not a misunderstanding.
So I'd have com.falkensweb.project.services.fooService and that would
be an AOP'ing facade to com.falkensweb.project.buisnessObject.foo ? I
find  com.falkensweb.project.manager.fooManager more obvious as to
what is what, esp if there are a half dozen BO and Servicess.

No, the Advice is usually applied to the Service. What the Service does (interacting with business objects, etc.) is internal to the Service and doesn't affect the Advice.
 

> > If I call barService.foo(), I wouldn't want those (expensive)
> > conversions etc. done multiple times, so if the barManager needs to
> > use something from fooManager, it uses the Manager, not the Service.
>
> This might be a totally separate discussion. I suppose it depends on whether
> the Service is doing other things (Logging, transaction management, etc.)
> that need to be maintained even for an internal method call.

In my current production usage of AOP, the buisness objects
('managers') are fairly simple, mostly just wrappers around Reactor
CRUD, search or custom Gateway methods.
AOP provides try/catch and security via tokens ( i.e. sessions without

the CF scope), as such no I don't *think* that needs to be done in
calls between BOs...

Yeah, then those aren't business objects. A business object is meant to model one entity (a User, a Product, etc.). If your Manager is doing CRUD and Gateway (bulk) queries, that's not what would normally be called a business object since it is dealing with data for many objects. In fact, being a Singleton as I assume it is, the Manager has no state of its own as a business object almost always would.

Hope that helps.

Tom Chiverton

unread,
Jan 24, 2008, 3:22:46 AM1/24/08
to coldspri...@googlegroups.com
So buisness/domain object == value/transfer object ?

Yes, the
Service/Manager is a stateless singleton.

> > AOP provides try/catch and security via tokens (i.e. sessions without


> > the CF scope), as such no I don't *think* that needs to be done in
> > calls between BOs...
>
>
> Yeah, then those aren't business objects. A business object is meant to
> model one entity (a User, a Product, etc.). If your Manager is doing CRUD
> and Gateway (bulk) queries, that's not what would normally be called a
> business object since it is dealing with data for many objects. In fact,
> being a Singleton as I assume it is, the Manager has no state of its own as
> a business object almost always would.
>
> Hope that helps.
>
> >
>


--
Tom

Brian Kotek

unread,
Jan 24, 2008, 10:20:48 AM1/24/08
to coldspri...@googlegroups.com
On Jan 24, 2008 3:22 AM, Tom Chiverton <tom.ch...@gmail.com> wrote:
So buisness/domain object == value/transfer object ?



No, not usually. A VO/TO is "an object that carries data between processes", and is usually a very flat, small, and simple object that does nothing but wrap public properties. For example, when you return data from CF to Flex, this is usually done with a Value Object that has nothing but public properties (using the this scope). This is quite different from a business object, which is usually a bean (properties hidden behind getters and setters) and has rich behavior.

Tom Chiverton

unread,
Jan 24, 2008, 12:20:21 PM1/24/08
to coldspri...@googlegroups.com
On 24/01/2008, Brian Kotek <bria...@gmail.com> wrote:
> this is usually done with a Value Object that has nothing but public
> properties (using the this scope). This is quite different from a business
> object, which is usually a bean (properties hidden behind getters and
> setters) and has rich behavior.

Uh huh, OK.
Typically the service/manager that I'm exposing does only deal with
one type of data (say 'comments' or 'cases').
So that'd be a buisness object, right ? A bean with complicated things
inside (like Reactor calls) ?

remote facade -> buisness object -> ORM (i.e. Reactor) -> database ?

--
Tom

Brian Kotek

unread,
Jan 24, 2008, 1:03:33 PM1/24/08
to coldspri...@googlegroups.com
But the service doesn't model an individual entity, correct? It has no state. If so, it's not a business object. I'd say it would go:

remote proxy > service > business object

Now whether the business object itself deals with the database (ie Reactor via record.load()) or whether the service handles calls to the ORM (ie Transfer via transfer.get(objectName)) does not matter. The real point is that the service is stateless and just acts as an interface to the model, and the business object (whether you roll your own, use a Reactor record, a Transfer Object, etc.) has state and models a single, concrete entity.

remote facade -> buisness object -> ORM ( i.e. Reactor) -> database ?

--
Tom

Jonathan Logue

unread,
Jan 24, 2008, 1:39:10 PM1/24/08
to ColdSpring-Users
So, does anyone have any input on referencing aop proxies that are
being injected as dependencies?

On Jan 24, 10:03 am, "Brian Kotek" <brian...@gmail.com> wrote:
> But the service doesn't model an individual entity, correct? It has no
> state. If so, it's not a business object. I'd say it would go:
>
> remote proxy > service > business object
>
> Now whether the business object itself deals with the database (ie Reactor
> via record.load()) or whether the service handles calls to the ORM (ie
> Transfer via transfer.get(objectName)) does not matter. The real point is
> that the service is stateless and just acts as an interface to the model,
> and the business object (whether you roll your own, use a Reactor record, a
> Transfer Object, etc.) has state and models a single, concrete entity.
>
> On Jan 24, 2008 12:20 PM, Tom Chiverton <tom.chiver...@gmail.com> wrote:
>
>
>
>
>
> > On 24/01/2008, Brian Kotek <brian...@gmail.com> wrote:
> > > this is usually done with a Value Object that has nothing but public
> > > properties (using the this scope). This is quite different from a
> > business
> > > object, which is usually a bean (properties hidden behind getters and
> > > setters) and has rich behavior.
>
> > Uh huh, OK.
> > Typically the service/manager that I'm exposing does only deal with
> > one type of data (say 'comments' or 'cases').
> > So that'd be a buisness object, right ? A bean with complicated things
> > inside (like Reactor calls) ?
>
> > remote facade -> buisness object -> ORM (i.e. Reactor) -> database ?
>
> > --
> > Tom- Hide quoted text -
>
> - Show quoted text -

Brian Kotek

unread,
Jan 24, 2008, 2:26:53 PM1/24/08
to coldspri...@googlegroups.com
I'm not sure what you mean. You inject a proxied object the same way you would inject any other ColdSpring-manged bean (typically setter injection).

Dinner

unread,
Jan 24, 2008, 2:40:40 PM1/24/08
to coldspri...@googlegroups.com
On Jan 24, 2008 11:39 AM, Jonathan Logue <jonath...@gmail.com> wrote:
>
> So, does anyone have any input on referencing aop proxies that are
> being injected as dependencies?

It should "just work". :-)

I've found that whipping up a cfunit test is the best for troubleshooting stuff.

Think you can set up a simple version of what you're trying to do as a
unit test? Just doing that may give you an "ah ha" moment...

Force be with you!

--
A cynic is a man who, when he smells flowers, looks around for a coffin.
H. L. Mencken

Jonathan Logue

unread,
Jan 24, 2008, 8:07:19 PM1/24/08
to ColdSpring-Users
>It should "just work". :-)

That is what I am trying to get at... yes, I am using typical CS
injection... it is just not working the way I would expect when I use
beans that are injected further down the food chain:
Proxied BeanA contains proxied BeanB contains proxied BeanC

I will do more testing and get back to you if I figure out what is
going on. I was just hoping that someone was successfully doing what I
am trying to do and could provide some insight before I spend a lot of
time finding out I can't do what I am trying to do... which I am
hoping is not the case.

As an aside, I think I am going to move away from the suggestion of
creating proxies for all my managers as Chris and Barney suggested in
another thread. The time to load the application is way too long. I
get a lot of timeout errors when it initializes. This might be due to
the inheritance chain of the managers. Anyway - I love the idea, but
when I am coding and have to wait 30 seconds to run some code it can
be frustrating.

Thanks.


On Jan 24, 11:40 am, Dinner <valliants...@gmail.com> wrote:

Brian Kotek

unread,
Jan 24, 2008, 11:22:03 PM1/24/08
to coldspri...@googlegroups.com
On Jan 24, 2008 8:07 PM, Jonathan Logue <jonath...@gmail.com> wrote:

>It should "just work".  :-)

That is what I am trying to get at... yes, I am using typical CS
injection... it is just not working the way I would expect when I use
beans that are injected further down the food chain:
Proxied BeanA contains proxied BeanB contains proxied BeanC

I still don't understand what you're saying. Proxied BeanA is extended by proxied BeanB? Or Proxied BeanA has an instance of Proxied BeanB composed into it? You'll have to clarify or provide some kind of concrete example because I'm lost.
 

I will do more testing and get back to you if I figure out what is
going on. I was just hoping that someone was successfully doing what I
am trying to do and could provide some insight before I spend a lot of
time finding out I can't do what I am trying to do... which I am
hoping is not the case.

The problem is I can't answer you because I don't know what you're trying to do.
 

As an aside, I think I am going to move away from the suggestion of
creating proxies for all my managers as Chris and Barney suggested in
another thread. The time to load the application is way too long. I
get a lot of timeout errors when it initializes. This might be due to
the inheritance chain of the managers. Anyway - I love the idea, but
when I am coding and have to wait 30 seconds to run some code it can
be frustrating.

Any performance impact of using proxies should only be taken on the first request to the application. If you're having performance issues on every request then you're doing something wrong.
 

Dinner

unread,
Jan 25, 2008, 12:52:37 AM1/25/08
to coldspri...@googlegroups.com
On Jan 24, 2008 6:07 PM, Jonathan Logue <jonath...@gmail.com> wrote:
>
> >It should "just work".  :-)
>
> That is what I am trying to get at... yes, I am using typical CS
> injection... it is just not working the way I would expect when I use
> beans that are injected further down the food chain:
> Proxied BeanA contains proxied BeanB contains proxied BeanC

It looks like you're injecting the class (an un-decorated object) vs. an already configured bean... if that makes sense.

      <property name="target">
              <bean class="path.to.BeanA" autowire="byName" />
      </property>

Where I'll usually have

<bean id="BeanATarget" class=" net.klondike.component.BeanA">
   <property name="dsn">
     <value>klondike</value>
   </property>
</bean>


<bean id="BeanA class="coldspring.aop.framework.ProxyFactoryBean ">
      <property name="target">
              <ref bean="BeanATarget" />
      </property>
</bean>

But since you're auto-wiring by name... hmm...  Bah.  Can't wrap my head around it right now.

Maybe try setting up BeanA and BeanB as CS bean "targets", and then giving them to the proxy?  I'm not sure exactly what you're trying to achieve, and I'm a little tipsy, so I could be waaaay out in left field.  =]

Also, how "fresh" is your CS?  It's not like, some ancient version?  Some issue like that?  Hmm...  yup.  That's all I got.  [:

--
Nothing's better than the wind to your back, the sun in front of you, and your friends beside you.
   Aaron Douglas Trimble

Dinner

unread,
Jan 25, 2008, 12:54:24 AM1/25/08
to coldspri...@googlegroups.com
On Jan 24, 2008 9:22 PM, Brian Kotek <bria...@gmail.com> wrote:

> Any performance impact of using proxies should only be taken on the first
> request to the application. If you're having performance issues on every
> request then you're doing something wrong.

I think he may be talking about development-- you've got to re-init
every time, when you're wanking on CFCs parked in the application
scope, right? :-)

I've got one app that times out in production while re-initting, if I
don't add a requesttimeout attribute.
Doesn't do it in development, but, well, it works if I add the
timeout, so screw it for now. That server is due for a rebuild
anyways. :-)

I think a lot of this is like, ORM, etc., that's all getting fired up
when you re-initialize your application.

And as with all things Java, even re-initializing is faster the second time :-)

--
You can cover a great deal of country in books.
Andrew Lang

Jonathan Logue

unread,
Jan 25, 2008, 5:15:33 AM1/25/08
to ColdSpring-Users
Yeah - I am just talking about the hit when reinitializing the app.

I think I am going to just track this down myself. If I find out
anything useful, I will come back and post.

Thanks for your assistance.








On Jan 24, 9:54 pm, Dinner <valliants...@gmail.com> wrote:

Brian Kotek

unread,
Jan 25, 2008, 11:22:21 AM1/25/08
to coldspri...@googlegroups.com
Are you on CF8?

Jonathan Logue

unread,
Jan 25, 2008, 12:32:21 PM1/25/08
to ColdSpring-Users
7 currently.

On Jan 25, 8:22 am, "Brian Kotek" <brian...@gmail.com> wrote:
> Are you on CF8?
>

Peter J. Farrell

unread,
Jan 25, 2008, 12:37:51 PM1/25/08
to coldspri...@googlegroups.com
FYI, remember to turn off execution timings when you have debugging turned on.  Reporting those times causes debugging to add many times the actual time to process to the total request time.

Here's a FAQ for Mach-II that applies to all CFC based frameworks and applications:
http://greatbiztoolsllc-trac.cvsdude.com/mach-ii/wiki/FAQWhySlow

.pjf

Jonathan Logue said the following on 1/25/2008 11:32 AM:

Jonathan Logue

unread,
Jan 25, 2008, 2:34:03 PM1/25/08
to ColdSpring-Users
I have all debugging turned off.

It initializes just fine without all my managers proxied - takes about
6 or 7 seconds which is not bad. When I added the proxies, it must
have been at least 30 seconds. I don't have it hooked up to check
right now, but it was too long for me during development. Now, I think
it probably has a lot to do with the way I have things set up. I chose
to go with a manager for every class in the system and each manager
has 3 levels of inheritence. So, with 80 managers and counting, it is
no small task to handle all the DI and adding proxies on top of
that... It is probably unreasonable of me to expect it to load faster
- that is why I am saying that I don't think the approach of creating
an AOP proxy for each manager works in my case... although I should
probably try it on CF8 which I think Brian was getting at.

I will probably set up a mini app next week to try and distill what
( if any ) the real issue is. If I am able to reproduce the issue I am
talking about, I will zip it up and post it here.

Brian Kotek

unread,
Jan 25, 2008, 3:43:52 PM1/25/08
to coldspri...@googlegroups.com
I was asking about CF8 because there is a classloader bug in Java 6 that causes initialization slowdowns, which is why people are encouraged to revert to Java 5 until Sun can fix the bug.

Yes, if you're creating and using 80 proxies then I can see why it takes a long time to reinitialize. My first question would be whether you actually need 80 proxied service components...that is a lot. Unless the app is really so big that it requires 80 services, it sounds to me like something may be wrong with your design or the way you are using ColdSpring.

Also, even in development I usually don't reinitialize ColdSpring on every request. I have a flag that I can pass in the URL to reinit the app when I need to.

Jonathan Logue

unread,
Jan 25, 2008, 5:04:18 PM1/25/08
to ColdSpring-Users
>classloader bug in Java 6

I see - so that can't be it. Also, I don't have my app set to reload
every page request, but I do explicitly reload often.

>something may be wrong with your design or the way you are using ColdSpring

Well - I am definitely doing something wrong in regard to AOP
proxies ;-) Beyond that, I am very happy with the way things are set
up.

Let me explain a bit more about how I have things set up and you can
be the judge... much of this revolves around a code generation tool I
am building.

I generate an abstract manager for each table in the database ( I can
customize these with a concrete manager that extends the abstract
one ). Based on an XML file that contains the database definition
along with some meta-data for ColdSpring and Transfer, I can determine
the dependencies that exist between the various classes. I can
determine that the CompanyManager will need access to the
EmployeeManager (etc.) and the autowire methods are automatically
created. I could probably generate managers around the concept of
packages, but that would take some doing.

I am also generating a gateway component for each table that also
contains generated code for sql queries. Based on the same config
file, I can generate queries that do inner joins and left joins and
can accept a bunch of comparison keywords for filtering the result.

All the managers have the same footprint, so that I can call generic
controller methods like getObjectsByClass() or getObjectByID() and it
knows how to go and retrieve the information. Here is an example of a
ModelGlue event-handler message that returns a list of companies in
the system.

<message name="getObjectsByClass">
<argument name="class" value="Company" />
<argument name="returnVariable" value="rsCompanies" />
<argument name="orderby" value="name" />
</message>

If I wanted to get employees for a certain company, it might look like
this:

<message name="getObjectsByClass">
<argument name="class" value="Employee" />
<argument name="id_company" value="$id_company" />
<argument name="returnVariable" value="rsEmployees" />
<argument name="orderby" value="last_name, first_name" />
</message>

By following a predictable pattern for each class, I can write some
very effective methods that apply to all classes. I am trying to use
AOP to apply security, auditing and some other useful things.

So... what is the verdict?




On Jan 25, 12:43 pm, "Brian Kotek" <brian...@gmail.com> wrote:
> I was asking about CF8 because there is a classloader bug in Java 6 that
> causes initialization slowdowns, which is why people are encouraged to
> revert to Java 5 until Sun can fix the bug.
>
> Yes, if you're creating and using 80 proxies then I can see why it takes a
> long time to reinitialize. My first question would be whether you actually
> need 80 proxied service components...that is a lot. Unless the app is really
> so big that it requires 80 services, it sounds to me like something may be
> wrong with your design or the way you are using ColdSpring.
>
> Also, even in development I usually don't reinitialize ColdSpring on every
> request. I have a flag that I can pass in the URL to reinit the app when I
> need to.
>

Brian Kotek

unread,
Jan 25, 2008, 5:09:55 PM1/25/08
to coldspri...@googlegroups.com
All of that sounds fine, but the big question is which of these are you creating proxies for? There is no reason to proxy the abstract superclasses since your concrete services extend them, and *those* would be proxied. Also no reason to proxy the gateways or anything else. Basically the only thing you will almost ever need to proxy are the concrete, Singleton service components. Which comes back to the question of why you've got 80 proxied beans. Do you actually have 80 concrete services?

Jonathan Logue

unread,
Jan 25, 2008, 5:57:54 PM1/25/08
to ColdSpring-Users
Yes, I have 80 concrete managers ( I sound like I am attending a
recovery group ) - each specific to a table. No, I probably don't need
to have proxies on all of them, but that was what was Chris S. and
Barney B. recommended, so I tried it out. The idea was that you could
set up the proxies and use them later as needed. I was basically just
saying that in my situation, I don't think defaulting to having all
managers proxied was a good idea... at least in terms of development
efficiency.

I am still planning on spending some time in a controlled experiment
to see if I can reproduce my original issue and provide some code -
sometime next week.


On Jan 25, 2:09 pm, "Brian Kotek" <brian...@gmail.com> wrote:
> All of that sounds fine, but the big question is which of these are you
> creating proxies for? There is no reason to proxy the abstract superclasses
> since your concrete services extend them, and *those* would be proxied. Also
> no reason to proxy the gateways or anything else. Basically the only thing
> you will almost ever need to proxy are the concrete, Singleton service
> components. Which comes back to the question of why you've got 80 proxied
> beans. Do you actually have 80 concrete services?
>

Brian Kotek

unread,
Jan 25, 2008, 7:06:53 PM1/25/08
to coldspri...@googlegroups.com
OK now we're at the root of the issue, which is that you have separate Managers that correspond to every database table. Is there a reason that you decided to take such a database-centric appraoch? Couldn't these be combined into more generalized service objects that each relate to a larger set of behavior that your application requires?

In general, I would recommend approach your service layer (Manager) in terms of the behavior they provide instead of what the underlying database schema looks like. Is there some benefit that you feel you are getting from having a "one to one" relationship between the database tables and your service layer?

Jonathan Logue

unread,
Jan 25, 2008, 8:14:49 PM1/25/08
to ColdSpring-Users
Well - some of that is explained in my post at 2:04 today, but I will
give you a bit more info. I started using Brian Rinaldi's code
generator (Illudium PU-36 Code Generator) and quickly desired the
ability to write multiple files automatically. So I was already
thinking in terms of building something that would help me develop
stuff faster. Then I participated in the following thread that was
started by none other than you :-)

http://groups.google.com/group/transfer-dev/browse_thread/thread/9ef84acc266bc187/a8cb16fef13135ab#a8cb16fef13135ab
which turned into...
http://groups.google.com/group/transfer-dev/browse_thread/thread/476bc83a0e632074/a79ca4d7b62545de#a79ca4d7b62545de

Anyway - I started out to try and make a tool that takes the pain out
of managing changes across numerous configuration files. While I
completely agree that the persistence layer should be decoupled from
the model, it is a tough place to start. It seemed very pragmatic to
just take the easy route and use the database structure... and in my
usage of the approach, it is very powerful. We do use the concept of
services as separate and distinct from managers. They are probably
more akin to what you are talking about. So, while the controllers do
access the various class managers in some cases, some more complex
areas of the application have their own services.

I am curious though - how do you organize your gateway type methods
when not using Transfer in terms of services. Let's say you need to
return both Companies and Employees - where do you put the methods? I
think we might just be talking about whether you lay your code out
horizontally or vertically... meaning more files, or more in your
files.






On Jan 25, 4:06 pm, "Brian Kotek" <brian...@gmail.com> wrote:
> OK now we're at the root of the issue, which is that you have separate
> Managers that correspond to every database table. Is there a reason that you
> decided to take such a database-centric appraoch? Couldn't these be combined
> into more generalized service objects that each relate to a larger set of
> behavior that your application requires?
>
> In general, I would recommend approach your service layer (Manager) in terms
> of the behavior they provide instead of what the underlying database schema
> looks like. Is there some benefit that you feel you are getting from having
> a "one to one" relationship between the database tables and your service
> layer?
>

Brian Kotek

unread,
Jan 26, 2008, 12:26:45 AM1/26/08
to coldspri...@googlegroups.com
On Jan 25, 2008 8:14 PM, Jonathan Logue <jonath...@gmail.com> wrote:

I am curious though - how do you organize your gateway type methods
when not using Transfer in terms of services. Let's say you need to
return both Companies and Employees - where do you put the methods? I
think we might just be talking about whether you lay your code out
horizontally or vertically... meaning more files, or more in your
files.

In the interest of clarity, I'm going to keep referring to these as Services. I don't particularly care if someone chooses to call these Managers, but now you're saying that you actually have things named both ways. I'd recommend you pick one and just stick with it, whichever way you end up preferring. But I think using both will really throw people for a loop when you talk to them and are trying to explain your architecture. :-)

Companies and Employees are probably not very good examples because Companies and Employees are concepts that are separate enough to warrant their own services and large enough to wrap what would probably be multiple underlying database tables. There might be a database table Address, but I would most likely not have an AddressService. There might be a Role table, but not a RoleManager. Same goes for a Permission, Office, Question, Answer, or many, many others.

Why? Because a Role or Permission is part of a larger set of behavior being consumed by an application: security. So a SecurityService would nicely do all of these things (and use those tables and others). Address, Office, and other related data are used by the CompanyService. Question, Answer, and others might be used by a SurveyService. Hopefully this illustrates the point I'm trying to make, which is that a single Service can easily be using multiple tables in the database. It's quite rare for me to have a Service component that is a direct analog for only one database table.

I try to forget the database completely when I'm designing my domain model. I focus on what actual *behavior* the model needs to be able to provide. Only later do I worry about how I must structure my database to support the persistence needs of the model. I suppose I'm advocating a "top down" approach, where the domain model drives the database structure, not the other way around.

Dinner

unread,
Jan 26, 2008, 3:52:09 PM1/26/08
to coldspri...@googlegroups.com
On Jan 25, 2008 10:26 PM, Brian Kotek <bria...@gmail.com> wrote:

> I try to forget the database completely when I'm designing my domain model.
> I focus on what actual *behavior* the model needs to be able to provide.
> Only later do I worry about how I must structure my database to support the
> persistence needs of the model. I suppose I'm advocating a "top down"
> approach, where the domain model drives the database structure, not the
> other way around.

Wow. I came to sorta this conclusion myself last night! Wooters.

I was thinking, "why am I trying to re-invent the wheel of my existing
project whatsit?" -- When I first did it, I did it quick and dirty,
without thinking too much about details.

While "refactoring", I realized that both my Projects, and my
Tickets, had attributes, and what was I thinking having these
"getProjectPriorityNames()" and whatnot functions? Ton of mostly
similar code. Ton of mostly similar database tables. (Normalization
made a good case for the changes too).

So I settled on an AttributeService, that has both an
AttributePersistenceService and an AttributeTypePersistenceService
(that contain gateways and DAO or whatnot). Might be overkill there,
but part of the experiment is having a data store than doesn't have to
be a database, and they're part of that (although I'm not against
storing the data schema in an ddlutils XML schema, and using it for
generation of Stuff).
I'm wondering if I can't do something like just, implement
"persistable" or something in certain objects...

Bah, I'm drifting, but I had the "top-down" thought and was like,
"wow", I can do this a /lot/ easier. Why was I stuck on having the
data-schema be the same as it had been?

Well, back to your regularly scheduled program =]

--
The statistics on sanity are that one out of every four Americans is
suffering from some form of mental illness. Think of your three best
friends. If they're okay, then it's you.
Rita Mae Brown

Jonathan Logue

unread,
Jan 26, 2008, 4:46:06 PM1/26/08
to ColdSpring-Users
I generally agree with what you are saying... I am just trying to work
within the limitations of code generation of which I am sure you can
appreciate the challenges.

However, for the sake of discussion...

We do indeed have services as you are describing. We have a
SecurityService, a LoggingService, a ReportWriterService, etc. We just
have our database-based services ( class managers ) being injected
into them... so in essence, we have 2 layers ( when we need them ).
That is the reason we use both terms... to make that distinction. So,
I might ask, what is the downside of using singletons to manage
interactions with a single type of object when these can be injected
into each other and you can group functionality into auxillary
services when it makes sense? Why force yourself to follow the pattern
you are describing rather than using both approaches?

I am going to think some more about how I might restructure my tool to
take the top-down approach which is what my initial goal was... I
should at least let the user pick the way they want to lay out their
services. I would also like work out how Transfer packages would fit
into this. Is a package synonymous with a service?

In your case, do you have a one-to-one mapping between your services
and your gateways? And if so, are you required to have redundant code
in various services? Just curious what this might look like if I had
to dump my table based managers. If not, how do you determine what
comprises a gateway?

Any feedback will assist me in developing a better code generating
tool that I hope to make available at some point.

On the original AOP question, I set up a mini app and I can't
reproduce the issue I am having, so it must be something in my code
that is tripping it up.


On Jan 25, 9:26 pm, "Brian Kotek" <brian...@gmail.com> wrote:

Tom Chiverton

unread,
Jan 27, 2008, 7:31:17 AM1/27/08
to coldspri...@googlegroups.com
On 26/01/2008, Jonathan Logue <jonath...@gmail.com> wrote:
> I generally agree with what you are saying... I am just trying to work
> within the limitations of code generation of which I am sure you can
> appreciate the challenges.

You mean the limitions of Illudium ?
It sounds like you might want to take the 'generation' parts of
Illudium but apply your own logic to what inputs it uses to grind
though templates.

You mentioned you already have a config file that has metadata for
relationships betwen tables etc. Maybe that could indicate which
tables were to be made into full blown proxied services, and which
would be composed into their parents (which would be ones that were
proxied).

--
Tom

Peter Bell

unread,
Jan 27, 2008, 8:25:16 AM1/27/08
to coldspri...@googlegroups.com
+1. Unfortunately I missed the earlier part of this thread, but the only
real limitations of code generation are (i) imagination of the developer and
(ii) ROI of the solution. There are some classes of solution where 100% code
generation doesn't provide a worthwhile ROI, but there is no such thing as
code that can be hand written but not generated. If you can write a piece of
code, you can generate it.

As Tom suggested, a good starting point is usually a richer source of
metadata for your generator. Database introspection is way too limited to
make a useful source for generating real applications. If you must,
introspect your db to generate a first cut of metadata, but then use a
mechanism such as a configuration file (XML can be a good choice for this)
for adding richer metadata about your solution so you can generate code that
better fits your problem space. Broadly either use a top down approach where
you describe your solution space in terms of a Domain Specific Language and
then create a config file for entering data into the DSL, or try bottom up
where you look at commonalities between your hand coded scripts and use
those to come up with a language for describing the variability between your
scripts so you can generate them. Try Googling "code generation" and "domain
specific languages" and if you have the time for reading just one (large)
book, Generative Programming by Czarnecki et al is (at 8 years old) still
the best book on the subject.

Best Wishes,
Peter

Jonathan Logue

unread,
Jan 27, 2008, 10:57:44 AM1/27/08
to ColdSpring-Users
>but the only real limitations of code generation are (i) imagination of the developer and (ii) ROI of the solution.

That should have read "challenges". Imagination is the fun part ;-)
ROI is closer to the mark for me.

>As Tom suggested, a good starting point is usually a richer source of metadata for your generator.

I am already well on my way in creating this thing and I do indeed use
a meta-data file. It does not reverse engineer a database, but it will
do that eventually - I could probably make use of the Illudium scripts
for that portion.

>f you have the time for reading just one (large) book, Generative Programming by Czarnecki et al is (at 8 years old) still the best book on the subject.

I will plan on reading this when I get some time. Code generation is
relatively new for me and it is something I really enjoy.

I will send you both a link to a tool I am creating to see what you
think... it is not for public consumption ( yet ), but feedback is
always nice.

Thanks.



On Jan 27, 5:25 am, Peter Bell <pb...@systemsforge.com> wrote:
> +1. Unfortunately I missed the earlier part of this thread, but the only
> real limitations of code generation are (i) imagination of the developer and
> (ii) ROI of the solution. There are some classes of solution where 100% code
> generation doesn't provide a worthwhile ROI, but there is no such thing as
> code that can be hand written but not generated. If you can write a piece of
> code, you can generate it.
>
> As Tom suggested, a good starting point is usually a richer source of
> metadata for your generator. Database introspection is way too limited to
> make a useful source for generating real applications. If you must,
> introspect your db to generate a first cut of metadata, but then use a
> mechanism such as a configuration file (XML can be a good choice for this)
> for adding richer metadata about your solution so you can generate code that
> better fits your problem space. Broadly either use a top down approach where
> you describe your solution space in terms of a Domain Specific Language and
> then create a config file for entering data into the DSL, or try bottom up
> where you look at commonalities between your hand coded scripts and use
> those to come up with a language for describing the variability between your
> scripts so you can generate them. Try Googling "code generation" and "domain
> specific languages" and if you have the time for reading just one (large)
> book, Generative Programming by Czarnecki et al is (at 8 years old) still
> the best book on the subject.
>
> Best Wishes,
> Peter
>
> On 1/27/08 7:31 AM, "Tom Chiverton" <tom.chiver...@gmail.com> wrote:

Dinner

unread,
Jan 27, 2008, 11:02:29 AM1/27/08
to coldspri...@googlegroups.com
This was a good read:

http://www.theserverside.com/tt/articles/content/LightweightModeling/article.html

( http://tinyurl.com/2vn7vl )

And the supporting documentation was excellent! There's a PDF in
there for Model Driven Development-- just great stuff.

For database introspection, ddlutils seems to work pretty good, and I
think it will handle most databases.

--
The summit of happiness is reached when a person is ready to be what he is.
Desiderius Erasmu

Jonathan Logue

unread,
Jan 27, 2008, 11:10:56 AM1/27/08
to ColdSpring-Users
Thanks for the link. I will check this out.

On Jan 27, 8:02 am, Dinner <vallia...@gmail.com> wrote:
> This was a good read:
>
> http://www.theserverside.com/tt/articles/content/LightweightModeling/...
>
> (http://tinyurl.com/2vn7vl)
Reply all
Reply to author
Forward
0 new messages