Skip to content

Commit fbe45c6

Browse files
committed
LOGABCK-1717 configuirators shipping with logback-classic are instantiated via reflection
Signed-off-by: Ceki Gulcu <ceki@qos.ch>
1 parent e69ed4d commit fbe45c6

File tree

8 files changed

+65
-55
lines changed

8 files changed

+65
-55
lines changed

logback-classic/src/main/java/ch/qos/logback/classic/ClassicConstants.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,6 @@ public class ClassicConstants {
6060

6161
public static final String FINALIZE_SESSION = "FINALIZE_SESSION";
6262
public static final Marker FINALIZE_SESSION_MARKER = MarkerFactory.getMarker(FINALIZE_SESSION);
63+
final public static String AUTOCONFIG_FILE = "logback.xml";
64+
final public static String TEST_AUTOCONFIG_FILE = "logback-test.xml";
6365
}

logback-classic/src/main/java/ch/qos/logback/classic/joran/SerializedModelConfigurator.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,10 +98,13 @@ private void buildModelInterpretationContext(Model topModel) {
9898
}
9999

100100
private Model retrieveModel(URL url) {
101+
long start = System.currentTimeMillis();
101102
try (InputStream is = url.openStream()) {
102103
HardenedModelInputStream hmis = new HardenedModelInputStream(is);
103104

104105
Model model = (Model) hmis.readObject();
106+
long diff = System.currentTimeMillis() - start;
107+
addInfo("Model at ["+url+"] read in "+diff + " milliseconds");
105108
return model;
106109
} catch(IOException e) {
107110
addError("Failed to open "+url, e);

logback-classic/src/main/java/ch/qos/logback/classic/spi/LoggingEvent.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ public long getSequenceNumber() {
332332
return sequenceNumber;
333333
}
334334

335-
public void setSquenceNumber(long sn) {
335+
public void setSequenceNumber(long sn) {
336336
sequenceNumber = sn;
337337
}
338338

logback-classic/src/main/java/ch/qos/logback/classic/util/ContextInitializer.java

Lines changed: 56 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,22 @@
3737
*/
3838
public class ContextInitializer {
3939

40-
final public static String AUTOCONFIG_FILE = DefaultJoranConfigurator.AUTOCONFIG_FILE;
41-
final public static String TEST_AUTOCONFIG_FILE = DefaultJoranConfigurator.TEST_AUTOCONFIG_FILE;
40+
/**
41+
* @deprecated Please use ClassicConstants.AUTOCONFIG_FILE instead
42+
*/
43+
final public static String AUTOCONFIG_FILE = ClassicConstants.AUTOCONFIG_FILE;
44+
/**
45+
* @deprecated Please use ClassicConstants.TEST_AUTOCONFIG_FILE instead
46+
*/
47+
final public static String TEST_AUTOCONFIG_FILE = ClassicConstants.TEST_AUTOCONFIG_FILE;
4248
/**
4349
* @deprecated Please use ClassicConstants.CONFIG_FILE_PROPERTY instead
4450
*/
4551
final public static String CONFIG_FILE_PROPERTY = ClassicConstants.CONFIG_FILE_PROPERTY;
4652

53+
String[] INTERNAL_CONFIGURATOR_CLASSNAME_LIST = {"ch.qos.logback.classic.joran.SerializedModelConfigurator",
54+
"ch.qos.logback.classic.util.DefaultJoranConfigurator", "ch.qos.logback.classic.BasicConfigurator"};
55+
4756
final LoggerContext loggerContext;
4857

4958
final ContextAware contextAware;
@@ -66,41 +75,59 @@ public void autoConfig(ClassLoader classLoader) throws JoranException {
6675
StatusListenerConfigHelper.installIfAsked(loggerContext);
6776

6877

78+
// invoke custom configurators
6979
List<Configurator> configuratorList = ClassicEnvUtil.loadFromServiceLoader(Configurator.class, classLoader);
70-
7180
configuratorList.sort(rankComparator);
72-
73-
printConfiguratorOrder(configuratorList);
81+
if (configuratorList.isEmpty()) {
82+
contextAware.addInfo("No custom configurators were discovered as a service.");
83+
} else {
84+
printConfiguratorOrder(configuratorList);
85+
}
7486

7587
for (Configurator c : configuratorList) {
76-
try {
77-
long start = System.currentTimeMillis();
78-
contextAware.addInfo("Constructed configurator of type " + c.getClass());
79-
c.setContext(loggerContext);
80-
Configurator.ExecutionStatus status = c.configure(loggerContext);
81-
printDuration(start, c, status);
82-
if (status == Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY) {
83-
return;
84-
}
85-
} catch (Exception e) {
86-
throw new LogbackException(String.format("Failed to initialize Configurator: %s using ServiceLoader",
87-
c != null ? c.getClass().getCanonicalName() : "null"), e);
88-
}
88+
if (invokeConfigure(c) == Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY)
89+
return;
8990
}
9091

92+
// invoke internal configurators
93+
for (String configuratorClassName : INTERNAL_CONFIGURATOR_CLASSNAME_LIST) {
94+
contextAware.addInfo("Trying to configure with "+configuratorClassName);
95+
Configurator c = instantiateConfiguratorByClassName(configuratorClassName, classLoader);
96+
if(c == null)
97+
continue;
98+
if (invokeConfigure(c) == Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY)
99+
return;
100+
}
101+
}
91102

103+
private Configurator instantiateConfiguratorByClassName(String configuratorClassName, ClassLoader classLoader) {
104+
try {
105+
Class<?> classObj = classLoader.loadClass(configuratorClassName);
106+
return (Configurator) classObj.getConstructor().newInstance();
107+
} catch (ReflectiveOperationException e) {
108+
contextAware.addInfo("Instantiation failure: " + e.toString());
109+
return null;
110+
}
111+
}
92112

93-
// long startJoranConfiguration = System.currentTimeMillis();
94-
// Configurator.ExecutionStatus es = attemptConfigurationUsingJoranUsingReflexion(classLoader);
95-
//
96-
// if (es == Configurator.ExecutionStatus.DO_NOT_INVOKE_NEXT_IF_ANY) {
97-
// printDuration(startJoranConfiguration, JORAN_CONFIGURATION_DURATION_MSG, true);
98-
// return;
99-
// }
100-
// printDuration(startJoranConfiguration, JORAN_CONFIGURATION_DURATION_MSG, false);
101-
//
102-
// // at this stage invoke basicConfigurator
103-
// fallbackOnToBasicConfigurator();
113+
/**
114+
*
115+
* @param configurator
116+
* @return true if enclosing loop should break, false otherwise
117+
*/
118+
private Configurator.ExecutionStatus invokeConfigure(Configurator configurator) {
119+
try {
120+
long start = System.currentTimeMillis();
121+
contextAware.addInfo("Constructed configurator of type " + configurator.getClass());
122+
configurator.setContext(loggerContext);
123+
Configurator.ExecutionStatus status = configurator.configure(loggerContext);
124+
printDuration(start, configurator, status);
125+
return status;
126+
127+
} catch (Exception e) {
128+
throw new LogbackException(String.format("Failed to initialize or to run Configurator: %s",
129+
configurator != null ? configurator.getClass().getCanonicalName() : "null"), e);
130+
}
104131
}
105132

106133
private void printConfiguratorOrder(List<Configurator> configuratorList) {
@@ -131,13 +158,6 @@ private Configurator.ExecutionStatus attemptConfigurationUsingJoranUsingReflexio
131158

132159
}
133160

134-
private void fallbackOnToBasicConfigurator() {
135-
BasicConfigurator basicConfigurator = new BasicConfigurator();
136-
basicConfigurator.setContext(loggerContext);
137-
basicConfigurator.configure(loggerContext);
138-
}
139-
140-
141161
Comparator<Configurator> rankComparator = new Comparator<Configurator>() {
142162
@Override
143163
public int compare(Configurator c1, Configurator c2) {

logback-classic/src/main/java/ch/qos/logback/classic/util/DefaultJoranConfigurator.java

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,6 @@
2626
@ConfiguratorRank(value = ConfiguratorRank.NOMINAL)
2727
public class DefaultJoranConfigurator extends ContextAwareBase implements Configurator {
2828

29-
final public static String AUTOCONFIG_FILE = "logback.xml";
30-
final public static String TEST_AUTOCONFIG_FILE = "logback-test.xml";
31-
3229
@Override
3330
public ExecutionStatus configure(Context context) {
3431
URL url = performMultiStepConfigurationFileSearch(true);
@@ -52,12 +49,12 @@ private URL performMultiStepConfigurationFileSearch(boolean updateStatus) {
5249
return url;
5350
}
5451

55-
url = getResource(TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus);
52+
url = getResource(ClassicConstants.TEST_AUTOCONFIG_FILE, myClassLoader, updateStatus);
5653
if (url != null) {
5754
return url;
5855
}
5956

60-
return getResource(AUTOCONFIG_FILE, myClassLoader, updateStatus);
57+
return getResource(ClassicConstants.AUTOCONFIG_FILE, myClassLoader, updateStatus);
6158
}
6259
public void configureByResource(URL url) throws JoranException {
6360
if (url == null) {

logback-classic/src/main/java9/module-info.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,6 @@
1818
requires ch.qos.logback.core;
1919
uses ch.qos.logback.core.spi.Configurator;
2020
provides org.slf4j.spi.SLF4JServiceProvider with ch.qos.logback.classic.spi.LogbackServiceProvider;
21-
provides ch.qos.logback.core.spi.Configurator with ch.qos.logback.classic.joran.SerializedModelConfigurator,
22-
ch.qos.logback.classic.util.DefaultJoranConfigurator,
23-
ch.qos.logback.classic.BasicConfigurator;
2421

2522
exports ch.qos.logback.classic;
2623
exports ch.qos.logback.classic.boolex;

logback-classic/src/main/resources/META-INF/services/ch.qos.logback.core.spi.Configurator

Lines changed: 0 additions & 9 deletions
This file was deleted.

logback-classic/src/test/java/ch/qos/logback/classic/pattern/ConverterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -423,7 +423,7 @@ public void testSequenceNumber() {
423423
assertTrue(converter.isStarted());
424424
LoggingEvent event = makeLoggingEvent(null);
425425

426-
event.setSquenceNumber(123);
426+
event.setSequenceNumber(123);
427427
assertEquals("123", converter.convert(event));
428428
StatusPrinter.print(loggerContext);
429429
}

0 commit comments

Comments
 (0)