Is there a way in Wirebox to inject the current ap...
# box-products
b
Is there a way in Wirebox to inject the current application scope into an instance created with
application.wirebox.getInstance('testing')
I am using a java library that opens a socket and will receive requests that triggers a CFC. However the application scope isn't the same application scope as the one I created the listener instance from, it is basically empty, so any variables created in the application scope are inaccessible.
Pretty sure I am experiencing the same issue that was described with the Lucee Websocket extension https://github.com/isapir/lucee-websocket I remember reading somewhere he had to figure out how to copy the session/application scope over
t
I don't know if it will solve your problem but, google
Extending The Application.cfc ColdFusion
@ben has written a few blogs on the subject
b
You guys are over complicating this-- if you want a reference to the application scope, you just need to pass it in!
The question becomes • when/where is your CFC created • at what point does it get run inside a separate thread that Lucee didn't create (which will just have a default page context)
Keep in mind, it's not just the application scope you're missing though.
You also don't have • cgi • application • session • request • form • url • all application-specific settings such as datasources, ORM settings, mail servers, caches, CF mappings, etc, etc • Everything above but from the web context admin
This can make it nearly impossible to run any actual framework which is going to be depending on stuff like CF mappings
We've already solved this for several box libraries such as cbstreams, coldbox futures, and rabbit SDK. You can copy what we've done there in our base proxy class, but it's a little hairy and differs for Adobe CF and Lucee.
Sadly, both CF engine vendors have completely failed to understand this pain point despite years of me asking them about it 😕
b
@bdw429s thanks I will take a look at that to see if I can get it to work the same way.
b
This code assumes that • the CFC will be created inside of a regular HTTP thread created by Lucee/Adobe • it will grab what it needs from the original page context in the
init()
method and store it in the CFC • When the CFC has a method invoked later in a separate thread created by a java library it will have an empty page context • so it calls loadContext() and unloadContext() to get its information back
There are some caveats • the Adobe CF portions won't run on shared hosting with access to internal CF java classes disabled • The Lucee stuff doesn't capture all the scopes like
request
(which you may or may not need) due to stupid bugs in Lucee that I couldn't get Micha to fix but we use this basic idea in several places and it works pretty good
This is probably one of the single most-needed features built into CFML to finally make it easier to natively pass your CFCs into java libraries which use threading
Adobe probably has a somewhat-reason to avoid caring about this since you could work around their Standard license restrictions on the number of cfthreads you can run.
But in reality, I think it's just apathy and lack of understanding/writing modern CFML code that has prevented either CF engine from doing anything about this missing functionality
b
This worked great, thanks
b
Excellent
I've thought a few times we should wrap that logic up in a library to make it a bit more reusable
But every time I think about it, I just get angry that it's still not baked into either engine, lol
I should flesh out a better ticket for it. There's one for Lucee I think, but it's a bit vague
I think we need some built in CFML function that has three possible ways to call it • associated current thread with a given application -- provide application name • associate current thread with given session -- provide session ID and applicaiton name • associate current thread with given request -- provide page context object from original request (would need a way to prevent the pc from being recycled if the new thread outlives the original 🤔 )
The code we have is an approximation of bullets #2 and #3 depending on the engine.
But in reality, it should be as easy as
Copy code
associateThread( application="myApp" );
try {
  // run My logic inside some random thread
} finally {
  // removes contexts from ThreadLocal
  diassociateThread();
}
Or, if you wanted to be more clever...
Copy code
runThreadInContext( application="myApp", udf=()=>{
  // run My logic inside some random thread
} );
providing the logic to run in a closure would reduce boilerplate and allow for auto-cleanup
Now if I could just get the Adobe and/or Lucee engineers to care about this 😕
I finally fleshed out a ticket for this. Perhaps it will happen in Lucee 6 https://luceeserver.atlassian.net/browse/LDEV-3960
b
Coming back to this I remember you mentioning
request
scope not being carried over which is expected. However it seems to return an immutable
request
scope when I am trying to set a variable in that scope. Have you found a workaround for this?
b
Can you explain what you mean?
Like, are you getting a specific error?
b
message has been deleted
I am just trying to append to the request scope and that is the error I receive. I can append to Session and Cookie just fine
b
What code is on line 14 of
BaseLisetnerNew.cfc
?
b
message has been deleted
tried it a couple different ways
b
Interesting-- I don't think I ever realized Lucee's request scope is stored directly as servlet request attributes.
@Brandon Brown What exact version of Lucee are you on?
b
5.3.8-206
b
I still can't quite figure out why that error is happening
All the code involved is very generic and I'm not sure what exact Map implementation is being used for the servlet request attributes in this case
I have to pick up some kids from school.
b
thanks for taking a look
I am using Igals code for his LuceeApps repo. I am wondering if it has anything to do with the code here: https://github.com/isapir/lucee-apps/blob/34cdedd33510d35bc59ce75ea951af9ec1fc5959/src/main/java/net/twentyonesolutions/lucee/app/LuceeApp.java#L75
@bdw429s it was in fact the code in that file. Collection.EMPTY_MAP creates an immutable map
b
Ahh yes, that was the missing piece
I expected something like that, but I couldn't track down where the map was created in your instance
This will be the second time I've seen a bug in a java lib because the devs defaulted to EMPTY_MAP, apparently not realizing it would be immutable.
I've never used that luceeapp project not am I familiar with it.
No readme or anything. What is it even supposed to do?
b
It is used by Igal's websocket extension and as far as I can tell it is an abstraction of commonly used functionality that is probably needed in other extensions. I am using it similar to the way it is implemented in the websocket extension where it will create an "application listener" and when a message comes in on my open Java socket it will copy over the original application context so I have access to it. The code you showed me for basically doing the same thing works great but I am having trouble with the Java SDK I am using, seemingly losing its methods. After a day or two I start receiving errors that methods on the Java lib don't exist which is very strange.
b
Yeah, no clue about Igal's stuff. you'l have to ask him about it, lol