Commits
md_5 authored 89e4f83cd41
1 1 | package org.bukkit.plugin.java; |
2 2 | |
3 3 | import java.io.File; |
4 4 | import java.io.FileNotFoundException; |
5 5 | import java.io.IOException; |
6 6 | import java.io.InputStream; |
7 7 | import java.lang.reflect.InvocationTargetException; |
8 8 | import java.lang.reflect.Method; |
9 9 | import java.util.Arrays; |
10 + | import java.util.Collections; |
10 11 | import java.util.HashMap; |
11 12 | import java.util.HashSet; |
12 13 | import java.util.LinkedHashMap; |
13 14 | import java.util.Map; |
14 15 | import java.util.Set; |
15 16 | import java.util.jar.JarEntry; |
16 17 | import java.util.jar.JarFile; |
17 18 | import java.util.logging.Level; |
18 19 | import java.util.regex.Pattern; |
19 20 | |
41 42 | import org.bukkit.plugin.UnknownDependencyException; |
42 43 | import org.yaml.snakeyaml.error.YAMLException; |
43 44 | |
44 45 | /** |
45 46 | * Represents a Java plugin loader, allowing plugins in the form of .jar |
46 47 | */ |
47 48 | public final class JavaPluginLoader implements PluginLoader { |
48 49 | final Server server; |
49 50 | private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), }; |
50 51 | private final Map<String, Class<?>> classes = new HashMap<String, Class<?>>(); |
51 - | private final Map<String, PluginClassLoader> loaders = new LinkedHashMap<String, PluginClassLoader>(); |
52 + | private final Map<String, PluginClassLoader> loaders = Collections.synchronizedMap(new LinkedHashMap<String, PluginClassLoader>()); |
52 53 | |
53 54 | /** |
54 55 | * This class was not meant to be constructed explicitly |
55 56 | * |
56 57 | * @param instance the server instance |
57 58 | */ |
58 59 | |
59 60 | public JavaPluginLoader(Server instance) { |
60 61 | Validate.notNull(instance, "Server cannot be null"); |
61 62 | server = instance; |
107 108 | if (dataFolder.exists() && !dataFolder.isDirectory()) { |
108 109 | throw new InvalidPluginException(String.format( |
109 110 | "Projected datafolder: `%s' for %s (%s) exists and is not a directory", |
110 111 | dataFolder, |
111 112 | description.getFullName(), |
112 113 | file |
113 114 | )); |
114 115 | } |
115 116 | |
116 117 | for (final String pluginName : description.getDepend()) { |
117 - | if (loaders == null) { |
118 - | throw new UnknownDependencyException(pluginName); |
119 - | } |
120 118 | PluginClassLoader current = loaders.get(pluginName); |
121 119 | |
122 120 | if (current == null) { |
123 121 | throw new UnknownDependencyException(pluginName); |
124 122 | } |
125 123 | } |
126 124 | |
127 125 | final PluginClassLoader loader; |
128 126 | try { |
129 127 | loader = new PluginClassLoader(this, getClass().getClassLoader(), description, dataFolder, file); |
179 177 | public Pattern[] getPluginFileFilters() { |
180 178 | return fileFilters.clone(); |
181 179 | } |
182 180 | |
183 181 | Class<?> getClassByName(final String name) { |
184 182 | Class<?> cachedClass = classes.get(name); |
185 183 | |
186 184 | if (cachedClass != null) { |
187 185 | return cachedClass; |
188 186 | } else { |
189 - | for (String current : loaders.keySet()) { |
190 - | PluginClassLoader loader = loaders.get(current); |
191 - | |
192 - | try { |
193 - | cachedClass = loader.findClass(name, false); |
194 - | } catch (ClassNotFoundException cnfe) {} |
195 - | if (cachedClass != null) { |
196 - | return cachedClass; |
187 + | synchronized (loaders) { |
188 + | for (PluginClassLoader loader : loaders.values()) { |
189 + | try { |
190 + | cachedClass = loader.findClass(name, false); |
191 + | } catch (ClassNotFoundException cnfe) {} |
192 + | if (cachedClass != null) { |
193 + | return cachedClass; |
194 + | } |
197 195 | } |
198 196 | } |
199 197 | } |
200 198 | return null; |
201 199 | } |
202 200 | |
203 201 | void setClass(final String name, final Class<?> clazz) { |
204 202 | if (!classes.containsKey(name)) { |
205 203 | classes.put(name, clazz); |
206 204 | |