This is indeed a very strange mistake. When you look at the source of AbstractObjectFactory.GetObjectInternal , you will see the following structure:
[ThreadStatic] private int nestingCount; protected object GetObjectInternal(...) { const int INDENT = 3; bool hasErrors = false; try { nestingCount++; if (log.IsDebugEnabled) { log.Debug("msg" + new String(' ', nestingCount * INDENT)); } // More code: Calls self recursively. } catch { nestingCount--; hasErrors = true; if (log.IsErrorEnabled) { log.Error("msg" + new String(' ', nestingCount * INDENT)); } } finally { if (!hasErrors) { nestingCount--; if (log.IsDebugEnabled) { log.Debug("msg" + new String(' ', nestingCount * INDENT)); } } } }
The exception you see must be thrown by one of three calls to new String(' ', nestingCount * INDENT) . This particular call to the string constructor string when the given value is negative. Since INDENT is a constant, nestingCount must have a negative value in this case. nestingCount is a stream-static variable. By default, static variables are always initialized to the default value (0 in this case) and cannot be influenced by other threads. Moreover, nestingCount never used outside this method.
Since nestingCount is thread-static and is used only in this method, it is difficult to imagine that the nestingCount script can become negative. Perhaps in the case of an asynchronous exception (ThreadAbort), but even this is difficult for me to imagine. Another option is that the static variable of the stream is changed by someone else using reflection.
But the big question is: how to solve this?
Decision:
There is only one thing that I can think of, and which reconfigures log4net so that debugging information is not logged. If debugging information is rejected, the string(char, int) constructor will probably never be called again, which will hide the problem. Not very beautiful, but possibly effective. This may work because AbstractObjectFactory logs use the log variable, which is initialized as follows:
this.log = LogManager.GetLogger(this.GetType());
You can do this by globally disabling logging of debugging information in log4net, or when you find it too complicated, setting log4net to turn off debugging information for type Spring.Objects.Factory.Support.DefaultListableObjectFactory (an instance that actually raises an exception) .
Good luck.