[ColdBox 4.1] Interceptor not setting session bean

37 views
Skip to first unread message

Chad Baloga

unread,
May 28, 2015, 8:31:09 AM5/28/15
to col...@googlegroups.com
I am trying to set a bean with some values from a new interceptor which I created.  At first I placed the sets in the preProcess of the security interceptor (security module interceptor) and everything was working fine and values get set and stick in session.  When I created a custom interceptor and copied the code from the preProcess in the security interceptor the values no longer get set.  I dump the projectBean.getThis() and I can see them set but when I dump the it is all blank.  Any ideas why it works fine in one interceptor but not another?? Thanks!

My interceptor settings in ColdBox.cfc:

//Register interceptors as an array, we need order
interceptors = [
   // SES
   {class="coldbox.system.interceptors.SES"},
         // User interceptor
   {class="interceptors.userSession"},
      // Security - handles PKI and NONPKI logon
   {class="cbsecurity.interceptors.Security",
          name="CBSecurity",
          properties = {
             // please add the properties you want here to configure the security interceptor
             rulesFile = "/cbsecurity/config/security.json.cfm",
             rulesSource = "json"
          } 
         }
   ];


My Bean:

component accessors="true" scope="session" singleton {
  
  property name="projects";
  property name="projTitle";
  property name="projId";
  property name="parentProjId";
  property name="bannerImage";
  property name="defaultPhase";
  property name="dsn";
  property name="editDuration";
  property name="myKey";
  property name="parentDsn";
  property name="phase";
  property name="phaseTitle";
  property name="prjEngName";
  property name="projectLogo";

  /**
  * Constructor
  */
  function init(){
    return this;
  }
  
  /* Utils */
  function getThis(){
   return this;
  }

}

preProcess code:

<!--- Pre-process --->
<cffunction name="preProcess" access="public" returntype="void" hint="Executes before any event execution occurs" output="false">
<cfargument name="event" required="true" type="any" hint="The event object.">
<cfargument name="interceptData" required="true" type="struct" hint="interceptData of intercepted info.">

<cfscript>
var rc = event.getCollection();
var oSession = getInstance('SessionStorage@cbstorages');

if (StructKeyExists(rc, "project") and rc.project neq projectBean.getProjId()) {
// Set user info for this project/phase
     userBean.setUsername(oSession.getVar("username"));
// Set project settings
var qry = proj.getProjectSettings(rc.project);
  projectBean.setProjId(qry.projId);
  projectBean.setProjTitle(qry.title);
        projectBean.setParentProjId(qry.parentProjId);
        projectBean.setBannerImage(qry.bannerImage);
        projectBean.setDefaultPhase(qry.defaultPhase);
        projectBean.setDsn(qry.dsn);
        projectBean.setEditDuration(qry.editDuration);
        projectBean.setMyKey(qry.myKey);
        projectBean.setParentDsn(qry.parentDsn);
        projectBean.setPhase(qry.phase);
        projectBean.setPhaseTitle(qry.phaseTitle);
        projectBean.setPrjEngName(qry.prjEngName);
        projectBean.setProjectLogo(qry.projectLogo);

    
                 (dump you see below)
                 writedump(projectBean.getThis());
        writedump(session);
 abort;
}

</cfscript>
</cffunction>


Bean dump after setting:

component models.beans.projectBean
$MIXED true
PROPERTIES
projects [empty string]
projTitle PROJECT1
projId 7
parentProjId [empty string]
bannerImage [empty string]
defaultPhase [empty string]
dsn PROJECT1
editDuration 90
myKey PROJECT1
parentDsn PROJECT1
phase [empty string]
phaseTitle [empty string]
prjEngName [empty string]
projectLogo [empty string]
METHODS


Session dump w empty values:
struct
cbox_flash_scope
struct [empty]
cbstorage
struct
sessionid E8034E3470215F75654809CF1F44703D.cfusion
urltoken CFID=21307&CFTOKEN=bfbd95ea2e9f2ccf-0806BFA4-5C26-0A61-9CA62637760D20B5&jsessionid=E8034E3470215F75654809CF1F44703D.cfusion
wirebox:projectbean
component models.beans.projectBean
$MIXED true
PROPERTIES
projects [empty string]
projTitle [empty string]
projId [empty string]
parentProjId [empty string]
bannerImage [empty string]
defaultPhase [empty string]
dsn [empty string]
editDuration [empty string]
myKey [empty string]
parentDsn [empty string]
phase [empty string]
phaseTitle [empty string]
prjEngName [empty string]
projectLogo [empty string]
METHODS

Andrew Scott

unread,
May 28, 2015, 9:30:50 AM5/28/15
to col...@googlegroups.com
You have reinit the framework when you make these changes right?

Regards,
Andrew Scott
WebSite: http://www.andyscott.id.au/


--
--
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
For News, visit http://blog.coldbox.org
For Documentation, visit http://wiki.coldbox.org
For Bug Reports, visit https://ortussolutions.atlassian.net/browse/COLDBOX
---
You received this message because you are subscribed to the Google Groups "ColdBox Platform" group.
To unsubscribe from this group and stop receiving emails from it, send an email to coldbox+u...@googlegroups.com.
To post to this group, send email to col...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/coldbox/eda13797-42e9-4b23-9da4-ac4ee4eb54c9%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Chad Baloga

unread,
May 28, 2015, 9:35:47 AM5/28/15
to col...@googlegroups.com
Yes, I even restarted the CF11 service

br...@bradwood.com

unread,
May 28, 2015, 10:06:20 AM5/28/15
to col...@googlegroups.com
  • Why are you setting session data in preProcess?  That runs every request and session data presumable only needs to be set once per session.  Can the project be reset on every request?
  • scope="session" singleton Why is this bean set to the singleton scope and the session scope? That doesn't make any sense. I think you just want session
  • Where is projectBean coming from in your preprocess code? If it is session scoped, do NOT inject it into your interceptor since it is a transient.  This is called scope widening injection and it's bad.  Instead, call wirebox.getInstance( 'mySessionScopedObject' ) every time.
Thanks!

~Brad

ColdBox Platform Evangelist
Ortus Solutions, Corp

E-mail: br...@coldbox.org
ColdBox Platform: http://www.coldbox.org
Blog: http://www.codersrevolution.com 
 
 
--------- Original Message ---------
--

Chad Baloga

unread,
May 28, 2015, 11:06:33 AM5/28/15
to col...@googlegroups.com
  • Why are you setting session data in preProcess?  That runs every request and session data presumable only needs to be set once per session.  Can the project be reset on every request? - Yes, we deal with numerous projects with multiple sub projects which could each have multiple phases with their own settings and user roles.  So depending on where the user navigated, they could be jumping around from project to project.  The data would only get reset in preProcess if "if (StructKeyExists(rc, "project") and rc.project neq projectBean.getProjId())" is true.
  • scope="session" singleton Why is this bean set to the singleton scope and the session scope? That doesn't make any sense. I think you just want session Yes, I have removed singleton.
  • Where is projectBean coming from in your preprocess code? If it is session scoped, do NOT inject it into your interceptor since it is a transient.  This is called scope widening injection and it's bad.  Yes, I was injecting it there and in some models (removed all injections of it now everywhere).  Instead, call wirebox.getInstance( 'mySessionScopedObject' ) every time. 
    • OK, I added "var projectBean = wirebox.getInstance('beans.projectBean');" to my preProcess function to use for my sets (Everything is working now!) 
    • I also removed "map("projectBean").to("models.beans.projectBean");" from my WireBox config file.  I added "prc.projectBean = thewirebox.getInstance('beans.projectBean'); to my request decorator.  Is this a good solution or am I missing something else that I could do in the WireBox config file like any other type of injections or mapping??
Thanks for all the help!

Chad

br...@bradwood.com

unread,
May 28, 2015, 12:06:59 PM5/28/15
to col...@googlegroups.com
I think we're making progress Chad :)
 
  • I also removed "map("projectBean").to("models.beans.projectBean");" from my WireBox config file.  I added "prc.projectBean = thewirebox.getInstance('beans.projectBean'); to my request decorator.  Is this a good solution or am I missing something else that I could do in the WireBox config file like any other type of injections or mapping??
 
This is totally up to your preference.  I prefer to only request a bean by it's name and not the full path.  Of course, I also take care not to have more than one bean with the same name in different folders so the name is unique.  I don't like to map each of my CFCs separately though, so I use mapDirectory() to recursively map all the CFCs in one directory at once.
 
mapDirectory( 'models' );
--------- Original Message ---------

Chad Baloga

unread,
May 28, 2015, 4:48:37 PM5/28/15
to col...@googlegroups.com
So with scope="session" it is safe to still have mappings in the WireBox config and inject into the models?  Just not safe to inject into interceptors?  

Thanks,
Chad

CaptainPalapa

unread,
May 28, 2015, 4:54:42 PM5/28/15
to col...@googlegroups.com
Chad.... consider what happens when a session expires.  Everything in it dies.  If you have added a session.value to one of your persistent models (singletons)...what will happen when you try to use it if that session has expired?  It'll be a "dead stick", maybe a NULL pointer because the source object has been purged.  If you are are using it as an argument to a function, that's different.

br...@bradwood.com

unread,
May 28, 2015, 5:16:19 PM5/28/15
to col...@googlegroups.com
The mappings don't actually create instances of objects, they just define the objects for Wirebox.  Basically, when you create a mapping you're telling Wirebox about an object called "foo" that you might ask for in the future and giving WireBox the recipe it needs to create "foo" when the time comes.  ALL objects WireBox creates have a mapping whether you create it or not.  (WireBox will make one the first time if necessary).
 
Scope widening injection comes into play once you are dealing with actual object instances.  The rule of thumb is never put a hard reference to another objects whose lifespan is shorter than the object you're injecting into.  Interceptors are singletons by default-- a single instance is created and persisted for the life of the application and shared by every thread.  Therefore, only other singletons should ever be injected directly into an interceptor.  Same for handlers.   Otherwise, the injection will be "widening" the scope of the transient object by making it live longer than it was supposed to.
--------- Original Message ---------

br...@bradwood.com

unread,
May 28, 2015, 5:18:26 PM5/28/15
to col...@googlegroups.com
Actually, you wouldn't get a NPE.  Everything in Java (but native data types) are pointers in memory.  As long as there is at least one strong reference to it, the garbage collector won't remove it.  In this instance, the "bad" behavior would be that all users will "share" or point to the same "session" object.  That object may also end up in an invalid state.
--------- Original Message ---------
Reply all
Reply to author
Forward
0 new messages