Skip to content

Commit 2d43927

Browse files
committed
Switched PluginRegistry to be singleton, because Reflections is not thread safe in jar archives scan
1 parent bb85000 commit 2d43927

File tree

2 files changed

+24
-4
lines changed

2 files changed

+24
-4
lines changed

logstash-core/src/main/java/org/logstash/plugins/discovery/PluginRegistry.java

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,41 @@
3737
import java.util.Set;
3838

3939
/**
40-
* Registry for built-in Java plugins (not installed via logstash-plugin)
41-
*/
40+
* Registry for built-in Java plugins (not installed via logstash-plugin).
41+
* This is singleton ofr two reasons:
42+
* <ul>
43+
* <li>it's a registry so no need for multiple instances</li>
44+
* <li>the Reflections library used need to run in single thread during discovery phase</li>
45+
* </ul>
46+
* */
4247
public final class PluginRegistry {
4348

4449
private final Map<String, Class<Input>> inputs = new HashMap<>();
4550
private final Map<String, Class<Filter>> filters = new HashMap<>();
4651
private final Map<String, Class<Output>> outputs = new HashMap<>();
4752
private final Map<String, Class<Codec>> codecs = new HashMap<>();
53+
private static final Object lock = new Object();
54+
private static PluginRegistry instance;
4855

49-
public PluginRegistry() {
56+
private PluginRegistry() {
5057
discoverPlugins();
5158
}
59+
60+
public static PluginRegistry getInstance() {
61+
if (instance == null) {
62+
synchronized (lock) {
63+
if (instance == null) {
64+
instance = new PluginRegistry();
65+
}
66+
}
67+
}
68+
return instance;
69+
}
5270

5371
@SuppressWarnings("unchecked")
5472
private void discoverPlugins() {
73+
// the constructor of Reflection must be called only by one thread, else there is a
74+
// risk that the first thread that completes close the Zip files for the others.
5575
Reflections reflections = new Reflections("org.logstash.plugins");
5676
Set<Class<?>> annotated = reflections.getTypesAnnotatedWith(LogstashPlugin.class);
5777
for (final Class<?> cls : annotated) {

logstash-core/src/main/java/org/logstash/plugins/factory/PluginFactoryExt.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public static IRubyObject filterDelegator(final ThreadContext context,
8282
}
8383

8484
public PluginFactoryExt(final Ruby runtime, final RubyClass metaClass) {
85-
this(runtime, metaClass, new PluginLookup(new PluginRegistry()));
85+
this(runtime, metaClass, new PluginLookup(PluginRegistry.getInstance()));
8686
}
8787

8888
PluginFactoryExt(final Ruby runtime, final RubyClass metaClass, PluginResolver pluginResolver) {

0 commit comments

Comments
 (0)