reloadApplicationOnEveryRequest is not working for me

93 views
Skip to first unread message

Jason Dean

unread,
Apr 8, 2012, 7:24:34 PM4/8/12
to framew...@googlegroups.com
So I am not sure if I am doing something wrong or if it is is FW/1 (I suspect the former), but when I use reloadApplicationOnEveryRequest I get errors because FW/1 is wiping out what I am doing in setUpApplication(). 

Here is what my setUpApplication() looks like:

<cffunction name="setupApplication" access="public" returntype="void" output="false">

     <cfset application.dsn = "BlogJason" />

     <cfset var blogService = variables.getService("BlogService") />

     <cfset var blogGateway = createObject("component", "model.blog.BlogGateway").init(application.dsn) />

     <cfset blogService.setBlogGateway(blogGateway) />

</cffunction>

The code in Framework 1 that is causing me trouble starts at line 1580: https://github.com/seancorfield/fw1/blob/master/org/corfield/framework.cfc#L1580

if ( isReload ) {
frameworkCache = { };
frameworkCache.lastReload = now();
frameworkCache.fileExists = { };
frameworkCache.controllers = { };
frameworkCache.services = { };
application[variables.framework.applicationKey].cache = frameworkCache;
application[variables.framework.applicationKey].subsystems = { };
}

This happens immediately *after* setUpApplication() is called. That means that my service into which I am setting my blogGateway is wiped out and recreated. So any attempts to use that gateway within the object result in errors.

Shouldn't I be able to do this in FW/1? Should I be able to modify services or any other objects in setUpApplication()? Or should I be doing it somewhere else.

NOTE: No doubt someone will tell me I should be using some sort of DI to inject my gateway into my service. But this is for a class I am teaching to students who are new to web development. Teaching them an MVC framework is going to be confusing enough without having to teach them all about DI as well, so I would like to be able to build the app this way.

Thanks,

Jason



Seth Johnson

unread,
Apr 8, 2012, 7:39:05 PM4/8/12
to framew...@googlegroups.com
Jason,

I have code that is virtually the same to this in my app and it is working well. I would be interested in seeing what/where you are calling your service from and the error is that is being generated.

Seth 



--
FW/1 on RIAForge: http://fw1.riaforge.org/
 
FW/1 on github: http://github.com/seancorfield/fw1
 
FW/1 on Google Groups: http://groups.google.com/group/framework-one

Jason Dean

unread,
Apr 8, 2012, 9:10:28 PM4/8/12
to framew...@googlegroups.com
I am calling the service from one of my controllers. 

<cffunction name="default">

<cfset variables.fw.service("BlogService.getEntries", "posts") />

</cffunction>

The error I get is: Its possible that a method called on a Java object created by CreateObject returned null.

Value must be initialized before use.

If I modify FW/1 to move the call to setUpApplication() to *after* that section, it works fine. 

Jason


Matt Quackenbush

unread,
Apr 8, 2012, 9:47:58 PM4/8/12
to framew...@googlegroups.com

I've just skimmed, but it seems like maybe you're expecting the service method to be fired right away. However, fw.service () merely queues the service call, which would then execute _after_ the controller method(s) finish.

Have you tried getting the service from the bean factory and calling it directly?

Sent from my Samsung Galaxy SII

Jason Dean

unread,
Apr 8, 2012, 10:08:16 PM4/8/12
to framew...@googlegroups.com
Sorry, I don't understand what you are saying. 

The documentation shows calling a service like this. Why would I want to call it any other way? I don't need it to run right away, I just need it to run before the view is displayed. 

Also, the only references I see to bean factories in the documentation involve ColdSpring, which I am not using for the reasons provided in my original post, so I am not sure if this advices even applies, and if it does, how to follow it. 

Thanks,

Jason


Sean Corfield

unread,
Apr 8, 2012, 10:54:56 PM4/8/12
to framew...@googlegroups.com
On Sunday, April 8, 2012 4:24:34 PM UTC-7, Jason Dean wrote:

<cffunction name="setupApplication" access="public" returntype="void" output="false">

     <cfset application.dsn = "BlogJason" />

     <cfset var blogService = variables.getService("BlogService") />

     <cfset var blogGateway = createObject("component", "model.blog.BlogGateway").init(application.dsn) />

     <cfset blogService.setBlogGateway(blogGateway) />

</cffunction>


The problem here is you're attempting to mix FW/1's service management with your own and that's just not going to work, I'm afraid. Since your service depends on other services and those depend on other variables, you're into territory where you need a DI framework like ColdSpring or DI/1 to manage your services.

This happens immediately *after* setUpApplication() is called. That means that my service into which I am setting my blogGateway is wiped out and recreated. So any attempts to use that gateway within the object result in errors.

If you look in the Reference Manual, it says this of getService():

"At present, this method is actually public but it should not be called, nor overridden. It may become private or be renamed in the future."

NOTE: No doubt someone will tell me I should be using some sort of DI to inject my gateway into my service. But this is for a class I am teaching to students who are new to web development. Teaching them an MVC framework is going to be confusing enough without having to teach them all about DI as well, so I would like to be able to build the app this way.

Either you need to manage all the services or let a DI framework do it (since you've gone beyond what FW/1 is designed to do in terms of service management). You can't mix'n'match between FW/1's management and either your own or a DI framework's.

Sean

Jason Dean

unread,
Apr 8, 2012, 11:00:09 PM4/8/12
to framew...@googlegroups.com
OK, Thanks Sean. That makes sense. I missed that in the docs.

I will go with managing the services myself. 

Jason

Sean Corfield

unread,
Apr 8, 2012, 11:07:47 PM4/8/12
to framew...@googlegroups.com
On Sun, Apr 8, 2012 at 8:00 PM, Jason Dean <dean...@gmail.com> wrote:
> I will go with managing the services myself.

Since I suspect you only need the service in the blog controller
(yes?), the simplest solution is to create the gateway and then the
service in the init() of your controller.

I'd question using application.dsn since it's a global variable and
you probably want to avoid such practices in a course teaching MVC but
then your choices are something like:
* Application.cfc: this.dsn = "foo"; controllers/blog.cfc: init( fw )
{ ... variables.fw.dsn ... }
* Application.cfc: variables.framework = { ... dsn = "foo", ... };
controllers/blog.cfc: init( fw ) { ... variables.fw.getConfig().dsn
... }

Or just use the DSN name directly when initializing the gateway in the
blog controller init() - and point out that as the program gets more
complex, you'd want to move all of that initialization to a DI
framework.

I don't think there's any way of escaping a DI framework at some point
in the process unless you're really only teaching them toy apps?
--
Sean A Corfield -- (904) 302-SEAN
An Architect's View -- http://corfield.org/
World Singles, LLC. -- http://worldsingles.com/

"Perfection is the enemy of the good."
-- Gustave Flaubert, French realist novelist (1821-1880)

Jason Dean

unread,
Apr 9, 2012, 12:22:08 AM4/9/12
to framew...@googlegroups.com

Thanks for the advice. At this point, I really am only teaching the, "toy apps". They are just getting their feet wet in anything web-app related. They've only had the basics of OO and I only have 16 weeks to teach them all of this. 

This is not part of a 4 year CS program or anything like that, this is part of a 2-year software development A.A.S. degree, so we only have so much time. I think what I am able to give them will certainly help them when they go on to a 4 year degree or become Junior developers somewhere.  There is only so much we can accomplish in a short time without pushing too hard. 

I will probably just pass create a function-local variable and pass that in to the needed Gateways (there will be two) instead of application.dsn. 

Jason

Jason Dean

unread,
Apr 9, 2012, 9:00:51 PM4/9/12
to framew...@googlegroups.com
Actually, I really only have 5 weeks to teach them all of this. It has taken 11 weeks to get them up to this point. 

Again, thanks for the advice. I have things working in a way that I think is acceptable and is not teaching them terrible practices. They may not be the best practices, but I can't build Rome in a day.  It's HEAPS better than the way I learned. 

Previous graduates from this program had not been taught MVC at all. Their one web app class only covered procedural programming with classic ASP, so I hope that I am improving the overall quality of their education and their employability with this course. 

Jason

James Holmes

unread,
Apr 9, 2012, 9:13:32 PM4/9/12
to framew...@googlegroups.com
Christ. I guarantee that anything you are doing with MVC is a massive improvement on that mess.

--
Shu Ha Ri: Agile and .NET blog
http://www.bifrost.com.au/

Sean Corfield

unread,
Apr 9, 2012, 11:15:37 PM4/9/12
to framew...@googlegroups.com
On Mon, Apr 9, 2012 at 6:00 PM, Jason Dean <dean...@gmail.com> wrote:
> Again, thanks for the advice. I have things working in a way that I think is
> acceptable and is not teaching them terrible practices. They may not be the
> best practices, but I can't build Rome in a day.  It's HEAPS better than the
> way I learned.

You're doing good work! Keep it up!

Reply all
Reply to author
Forward
0 new messages