added a comment - - edited
So the Etsy-Stories module in 'tutorial' is using a ThreadLocal caching mechanism. This is to allow the multi-threaded running of tests on stacks like SauceLabs.com. As any of the page objects or steps classes may maintain state, they need to be separate instances.
JBehave (as correctly suggested by Brian) does not instantiate page objects, steps classes or other dependent components..... PicoContainer does (for the Etsy example).
Refer https://github.com/jbehave/jbehave-tutorial/blob/master/etsy-stories/src/main/java/org/jbehave/tutorials/etsy/EtsyDotComStories.java. Search in page for ThreadCaching, see that it is used in a container's instantiation (all comps in that container will be 'new' per thread). the makeContainer() invocation makes a child container with the same spec (ThreadCaching). Thus the comps registered at that level are newed up per thread too.
Thus, and I am 100% sure about this. Any instances made by PicoStepsFactory (line 126 presently) are not used by actual step invocation, nor those steps instances invocation into page objects. At least when in multithreaded mode. In regular single-threaded mode, because we coded a class 'NonThreadingExecutorService' the (serial) execution thread will be the same as the thread that passed through the constructor of EtsyStories.
So. In my use-case, these are not singletons because of the multithreaded needs because of the concurrent leasing of browsers from SauceLabs. In my use-case I'm 100% that EtsyDotComSteps, housekeeping.EmptyCartIfNotAlready and the seven Groovy classes in the pages package are instantiated needlessly at during the construction phase of EtsyStories.
OK, here's the unfortunate way we'll have to do this I think :- https://github.com/jbehave/jbehave-tutorial/commit/7b642bc1d692edfd2dffe098c642e29cba856ab4
The steps containers cannot attempt to do ThreadLocal because JBehave works with instances instantiated up front.
However, injected deps (into pages and/or steps classes depending on the number of containers) can be ThreadLocal managed (ThreadCached for PicoContainer). This commit illustrates that.
Unfortunately, this means the end-user needs to think about statelessness in at least steps classes.