Some services accessed through the ServiceRegistry are not provided by
Drools modules but by jBPM, and have a higher probability of not
actually being in the classpath. ProcessBuilderFactory and
ProcessRuntimeFactory (try to) load such services when respectively
called during the construction of KnowledgeBuilderImpl and
StatefulKnowledgeSessionImpl. Trying to load a class is an expensive
operation, especially in the context of a web application where the
classloader will scan all the jars. With Tomcat for example, this
operation is moreover synchronized and can lead to lock contention.
There's also the issue of using exceptions for the regular control flow,
because filling an exception's stacktrace is also quite expensive.
ProcessBuilderFactory is modified to only try to load the service once,
and then either stores the service or the exception. The exception can
then be rethrown on subsequent accesses, to keep reporting on the failure
to load the service in KnowledgeBuilderImpl.
ProcessRuntimeFactory is simply modified to try to load the service once
and return null is the service cannot be loaded, simplifying the control
flow in StatefulKnowledgeSessionImpl.