242 if (name == null && bundle == null) {
243 return NO_RESOURCE_BUNDLE;
244 } else if (SYSTEM_LOGGER_RB_NAME.equals(name) && bundle == null) {
245 return SYSTEM_BUNDLE;
246 } else {
247 return new LoggerBundle(name, bundle);
248 }
249 }
250 }
251
252 // This instance will be shared by all loggers created by the system
253 // code
254 private static final LoggerBundle SYSTEM_BUNDLE =
255 new LoggerBundle(SYSTEM_LOGGER_RB_NAME, null);
256
257 // This instance indicates that no resource bundle has been specified yet,
258 // and it will be shared by all loggers which have no resource bundle.
259 private static final LoggerBundle NO_RESOURCE_BUNDLE =
260 new LoggerBundle(null, null);
261
262 private static final JavaUtilResourceBundleAccess RB_ACCESS =
263 SharedSecrets.getJavaUtilResourceBundleAccess();
264
265 // A value class that holds the logger configuration data.
266 // This configuration can be shared between an application logger
267 // and a system logger of the same name.
268 private static final class ConfigurationData {
269
270 // The delegate field is used to avoid races while
271 // merging configuration. This will ensure that any pending
272 // configuration action on an application logger will either
273 // be finished before the merge happens, or will be forwarded
274 // to the system logger configuration after the merge is completed.
275 // By default delegate=this.
276 private volatile ConfigurationData delegate;
277
278 volatile boolean useParentHandlers;
279 volatile Filter filter;
280 volatile Level levelObject;
281 volatile int levelValue; // current effective level value
282 final CopyOnWriteArrayList<Handler> handlers =
283 new CopyOnWriteArrayList<>();
2166 } else if (catalog != null && currentLocale.equals(catalogLocale)
2167 && name.equals(catalogName)) {
2168 return catalog;
2169 }
2170
2171 // Use the thread's context ClassLoader. If there isn't one, use the
2172 // {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader}.
2173 ClassLoader cl = Thread.currentThread().getContextClassLoader();
2174 if (cl == null) {
2175 cl = ClassLoader.getSystemClassLoader();
2176 }
2177
2178 final Module callerModule = getCallerModule();
2179
2180 // If useCallersModule is false, we are called by logrb, with a name
2181 // that is provided by the user. In that case we will look in the TCCL.
2182 // We also look in the TCCL if callerModule is null or unnamed.
2183 if (!useCallersModule || callerModule == null || !callerModule.isNamed()) {
2184 try {
2185 Module mod = cl.getUnnamedModule();
2186 catalog = RB_ACCESS.getBundle(name, currentLocale, mod);
2187 catalogName = name;
2188 catalogLocale = currentLocale;
2189 return catalog;
2190 } catch (MissingResourceException ex) {
2191 // We can't find the ResourceBundle in the default
2192 // ClassLoader. Drop through.
2193 if (useCallersModule && callerModule != null) {
2194 try {
2195 // We are called by an unnamed module: try with the
2196 // unnamed module class loader:
2197 PrivilegedAction<ClassLoader> getModuleClassLoader =
2198 () -> callerModule.getClassLoader();
2199 ClassLoader moduleCL =
2200 AccessController.doPrivileged(getModuleClassLoader);
2201 // moduleCL can be null if the logger is created by a class
2202 // appended to the bootclasspath.
2203 // If moduleCL is null we would use cl, but we already tried
2204 // that above (we first looked in the TCCL for unnamed
2205 // caller modules) - so there no point in trying again: we
2206 // won't find anything more this second time.
2210 // we already tried the TCCL and found nothing - so try
2211 // with the module's loader this time.
2212 catalog = ResourceBundle.getBundle(name, currentLocale,
2213 moduleCL);
2214 catalogName = name;
2215 catalogLocale = currentLocale;
2216 return catalog;
2217 } catch (MissingResourceException x) {
2218 return null; // no luck
2219 }
2220 } else {
2221 return null;
2222 }
2223 }
2224 } else {
2225 // we should have:
2226 // useCallersModule && callerModule != null && callerModule.isNamed();
2227 // Try with the caller's module
2228 try {
2229 // Use the caller's module
2230 catalog = RB_ACCESS.getBundle(name, currentLocale, callerModule);
2231 catalogName = name;
2232 catalogLocale = currentLocale;
2233 return catalog;
2234 } catch (MissingResourceException ex) {
2235 return null; // no luck
2236 }
2237 }
2238 }
2239
2240 private void setupResourceInfo(String name, Class<?> caller) {
2241 final Module module = caller == null ? null : caller.getModule();
2242 setupResourceInfo(name, module);
2243 }
2244
2245 // Private utility method to initialize our one entry
2246 // resource bundle name cache and the callers Module
2247 // Note: for consistency reasons, we are careful to check
2248 // that a suitable ResourceBundle exists before setting the
2249 // resourceBundleName field.
2250 // Synchronized to prevent races in setting the fields.
|
242 if (name == null && bundle == null) {
243 return NO_RESOURCE_BUNDLE;
244 } else if (SYSTEM_LOGGER_RB_NAME.equals(name) && bundle == null) {
245 return SYSTEM_BUNDLE;
246 } else {
247 return new LoggerBundle(name, bundle);
248 }
249 }
250 }
251
252 // This instance will be shared by all loggers created by the system
253 // code
254 private static final LoggerBundle SYSTEM_BUNDLE =
255 new LoggerBundle(SYSTEM_LOGGER_RB_NAME, null);
256
257 // This instance indicates that no resource bundle has been specified yet,
258 // and it will be shared by all loggers which have no resource bundle.
259 private static final LoggerBundle NO_RESOURCE_BUNDLE =
260 new LoggerBundle(null, null);
261
262 // Calling SharedSecrets.getJavaUtilResourceBundleAccess()
263 // forces the initialization of ResourceBundle.class, which
264 // can be too early if the VM has not finished booting yet.
265 private static final class RbAccess {
266 static final JavaUtilResourceBundleAccess RB_ACCESS =
267 SharedSecrets.getJavaUtilResourceBundleAccess();
268 }
269
270 // A value class that holds the logger configuration data.
271 // This configuration can be shared between an application logger
272 // and a system logger of the same name.
273 private static final class ConfigurationData {
274
275 // The delegate field is used to avoid races while
276 // merging configuration. This will ensure that any pending
277 // configuration action on an application logger will either
278 // be finished before the merge happens, or will be forwarded
279 // to the system logger configuration after the merge is completed.
280 // By default delegate=this.
281 private volatile ConfigurationData delegate;
282
283 volatile boolean useParentHandlers;
284 volatile Filter filter;
285 volatile Level levelObject;
286 volatile int levelValue; // current effective level value
287 final CopyOnWriteArrayList<Handler> handlers =
288 new CopyOnWriteArrayList<>();
2171 } else if (catalog != null && currentLocale.equals(catalogLocale)
2172 && name.equals(catalogName)) {
2173 return catalog;
2174 }
2175
2176 // Use the thread's context ClassLoader. If there isn't one, use the
2177 // {@linkplain java.lang.ClassLoader#getSystemClassLoader() system ClassLoader}.
2178 ClassLoader cl = Thread.currentThread().getContextClassLoader();
2179 if (cl == null) {
2180 cl = ClassLoader.getSystemClassLoader();
2181 }
2182
2183 final Module callerModule = getCallerModule();
2184
2185 // If useCallersModule is false, we are called by logrb, with a name
2186 // that is provided by the user. In that case we will look in the TCCL.
2187 // We also look in the TCCL if callerModule is null or unnamed.
2188 if (!useCallersModule || callerModule == null || !callerModule.isNamed()) {
2189 try {
2190 Module mod = cl.getUnnamedModule();
2191 catalog = RbAccess.RB_ACCESS.getBundle(name, currentLocale, mod);
2192 catalogName = name;
2193 catalogLocale = currentLocale;
2194 return catalog;
2195 } catch (MissingResourceException ex) {
2196 // We can't find the ResourceBundle in the default
2197 // ClassLoader. Drop through.
2198 if (useCallersModule && callerModule != null) {
2199 try {
2200 // We are called by an unnamed module: try with the
2201 // unnamed module class loader:
2202 PrivilegedAction<ClassLoader> getModuleClassLoader =
2203 () -> callerModule.getClassLoader();
2204 ClassLoader moduleCL =
2205 AccessController.doPrivileged(getModuleClassLoader);
2206 // moduleCL can be null if the logger is created by a class
2207 // appended to the bootclasspath.
2208 // If moduleCL is null we would use cl, but we already tried
2209 // that above (we first looked in the TCCL for unnamed
2210 // caller modules) - so there no point in trying again: we
2211 // won't find anything more this second time.
2215 // we already tried the TCCL and found nothing - so try
2216 // with the module's loader this time.
2217 catalog = ResourceBundle.getBundle(name, currentLocale,
2218 moduleCL);
2219 catalogName = name;
2220 catalogLocale = currentLocale;
2221 return catalog;
2222 } catch (MissingResourceException x) {
2223 return null; // no luck
2224 }
2225 } else {
2226 return null;
2227 }
2228 }
2229 } else {
2230 // we should have:
2231 // useCallersModule && callerModule != null && callerModule.isNamed();
2232 // Try with the caller's module
2233 try {
2234 // Use the caller's module
2235 catalog = RbAccess.RB_ACCESS.getBundle(name, currentLocale, callerModule);
2236 catalogName = name;
2237 catalogLocale = currentLocale;
2238 return catalog;
2239 } catch (MissingResourceException ex) {
2240 return null; // no luck
2241 }
2242 }
2243 }
2244
2245 private void setupResourceInfo(String name, Class<?> caller) {
2246 final Module module = caller == null ? null : caller.getModule();
2247 setupResourceInfo(name, module);
2248 }
2249
2250 // Private utility method to initialize our one entry
2251 // resource bundle name cache and the callers Module
2252 // Note: for consistency reasons, we are careful to check
2253 // that a suitable ResourceBundle exists before setting the
2254 // resourceBundleName field.
2255 // Synchronized to prevent races in setting the fields.
|