Description:
|
In the ch.qos.logback.classic.Logger class, the method getSeparatorIndexOf() is used to separate off child logger names (basically, to do String.split() on "name"). It looks for the occurrence of DOT or DOLLAR:
---------------
static int getSeparatorIndexOf(String name, int fromIndex) {
int i = name.indexOf(CoreConstants.DOT, fromIndex);
if (i != -1) {
return i;
} else {
return name.indexOf(CoreConstants.DOLLAR, fromIndex);
}
}
---------------
LoggerContext.getLogger() uses the above to split a passed "name" String.
The logic, however is peculiar.
getSeparatorIndexOf() splits a String along the DOT. Unless that is impossible,
in which case it splits it along the DOLLAR.
Unfortunately, LoggerContext.getLogger() may then behave surprisingly
The name "A.B.C$D"
will give the Logger chain A -> A.B -> A.B.C -> A.B.C.D as expected
The name "A.B$C.D"
could give the Logger chain A -> A.B -> A.B.C -> A.B.C.D but construction will
fail! Because:
Decomposition via getSeparatorIndexOf() will at first yield
A , B$C , D
But construction of a Logger in LoggerContext.getLogger() named "B$C" will then fail because that method checks whether decomposition is still possible; given "B$C" it will indeed find that decomposition is still possible, along the $ sign. It will thus throw an Exception.
The problem occurs in case of Logger names like:
"com.mplify.msgserver.ReceiverStickyPersistentStore$ReceiverStickyUpdateTransactionCallback.<clinit>"
This was an acceptable name in logback 0.9.30 (my previous version) but causes an exception in 1.7.4
Splitting should probably be done with a modified function:
static int getSeparatorIndexOf(String name, int fromIndex) {
int i = name.indexOf(CoreConstants.DOT, fromIndex);
int j = name.indexOf(CoreConstants.DOLLAR, fromIndex);
if (i < 0) {
return j;
}
else if (j < 0) {
return i;
} else {
return (i < j) ? i : j;
}
}
which splits along DOT and DOLLAR.
Problem with that approach:
1) Properly recompositing the name from the logger chain will demand that one stores whether the preceding separator was a DOT or DOLLAR (on second thoughts, probably not, as the whole logger name is stored, not only the components)
2) The names "A.B$C" and "A$B.C" would actually be equivalent. Would that be good?
P.S. :
Another problem: What about a logger "A..B"? Should
Logger.createChildByName(final String childName)
not check that is not passed the empty string? Currently it does not.
|