【问题标题】:MissingResourceException: Can't find bundle for base name sun.util.logging.resources.logging, locale en_USMissingResourceException:找不到基本名称 sun.util.logging.resources.logging 的捆绑包,语言环境 en_US
【发布时间】:2017-07-05 16:40:54
【问题描述】:

我明白了,

Caused by java.lang.InternalError: java.util.MissingResourceException: Can't find bundle for base name sun.util.logging.resources.logging, locale en_US 

在我的应用程序中来自 firebase 崩溃报告。

其他细节

Manufacturer: HTC
Model: HTC 10 
Android API: 24 

这是堆栈跟踪

java.util.logging.Logger$1.run (Logger.java:1385)
java.util.logging.Logger$1.run (Logger.java:1379)
java.security.AccessController.doPrivileged (AccessController.java:41)
java.util.logging.Logger.findSystemResourceBundle (Logger.java:1378)
java.util.logging.Logger.findResourceBundle (Logger.java:1425)
java.util.logging.Logger.setupResourceInfo (Logger.java:1523)
java.util.logging.Logger.<init> (Logger.java:266)
java.util.logging.Logger.<init> (Logger.java:261)
java.util.logging.LogManager$SystemLoggerContext.demandLogger (LogManager.java:734)
java.util.logging.LogManager.demandSystemLogger (LogManager.java:399)
java.util.logging.Logger.getPlatformLogger (Logger.java:474)
java.util.logging.LoggingProxyImpl.getLogger (LoggingProxyImpl.java:41)
sun.util.logging.LoggingSupport.getLogger (LoggingSupport.java:100)
sun.util.logging.PlatformLogger$JavaLoggerProxy.<init> (PlatformLogger.java:636)
sun.util.logging.PlatformLogger$JavaLoggerProxy.<init> (PlatformLogger.java:631)
sun.util.logging.PlatformLogger.<init> (PlatformLogger.java:246)
sun.util.logging.PlatformLogger.getLogger (PlatformLogger.java:205)
java.net.CookieManager.put (CookieManager.java:262)
okhttp3.JavaNetCookieJar.saveFromResponse (JavaNetCookieJar.java:47)
okhttp3.internal.http.HttpHeaders.receiveHeaders (HttpHeaders.java:182)
okhttp3.internal.http.BridgeInterceptor.intercept (BridgeInterceptor.java:95)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept (RetryAndFollowUpInterceptor.java:120)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:92)
okhttp3.internal.http.RealInterceptorChain.proceed (RealInterceptorChain.java:67)
okhttp3.RealCall.getResponseWithInterceptorChain (RealCall.java:185)
okhttp3.RealCall.execute (RealCall.java:69)

这里是相关的Logger代码

private static ResourceBundle findSystemResourceBundle(final Locale var0) {
        return (ResourceBundle)AccessController.doPrivileged(new PrivilegedAction() {
            public ResourceBundle run() {
                try {
                    return ResourceBundle.getBundle("sun.util.logging.resources.logging", var0, ClassLoader.getSystemClassLoader());
                } catch (MissingResourceException var2) {
                    throw new InternalError(var2.toString());
                }
            }
        });
    }

我也收到了语言环境 en_AU 的崩溃报告。

由于崩溃代码不是我控制的,如何防止崩溃?

【问题讨论】:

  • 好像是这个问题:github.com/square/okhttp/issues/3334
  • @q126y 发布您的目录结构?
  • 你在用proguard吗?
  • 请添加调用方法的代码-findSystemResourceBundle。
  • @MimmoGrottoli 是的

标签: java android okhttp okhttp3 cookiemanager


【解决方案1】:

分析:

MissingResourceException:找不到基本名称的捆绑包 sun.util.logging.resources.logging,语言环境 en_US

系统生成候选捆绑包名称

sun/util/logging/resources/logging_en_US
sun/util/logging/resources/logging_en
sun/util/logging/resources/logging

对于每个候选包名称,它会尝试加载一个资源包:

首先,它尝试使用生成的类名加载一个类。

如果可以使用指定的类找到并加载这样的类 loader,与 ResourceBundle 兼容,可访问 来自 ResourceBundle,并且可以实例化,getBundle 创建一个新的 此类的实例并将其用作结果资源包。

否则,getBundle 会尝试使用生成的属性文件名来定位属性资源文件。

它生成一个路径名 通过替换所有“。”从候选包名称中提取。字符与 “/”并附加字符串“.properties”。它试图找到一个 具有此名称的“资源”使用 java.lang.ClassLoader.getResource(java.lang.String)。 (请注意,一个 getResource 意义上的“资源”与 资源包的内容,它只是一个数据容器,例如 一个文件。)如果它找到一个“资源”,它会尝试创建一个新的 PropertyResourceBundle 实例来自其内容。如果成功,这 instance 成为结果资源包。

更详细地了解here 资源是如何解析的。

由于系统正在类路径中按降序查找这些文件中的任何一个(通常没有 _en*.properties)

sun/util/logging/resources/logging_en_US.properties
sun/util/logging/resources/logging_en.properties
sun/util/logging/resources/logging.properties

将这样的file(或上面提到的类)添加到您的应用程序将是一种解决方法。 属性文件的内容类似于this:

# Localizations for Level names.  For the US locale
# these are the same as the non-localized level name.

# The following ALL CAPS words should be translated.
ALL=All
# The following ALL CAPS words should be translated.
SEVERE=Severe
# The following ALL CAPS words should be translated.
WARNING=Warning
# The following ALL CAPS words should be translated.
INFO=Info
# The following ALL CAPS words should be translated.
CONFIG= Config
# The following ALL CAPS words should be translated.
FINE=Fine
# The following ALL CAPS words should be translated.
FINER=Finer
# The following ALL CAPS words should be translated.
FINEST=Finest
# The following ALL CAPS words should be translated.
OFF=Off

【讨论】:

  • 我会试一试。但崩溃只发生在 HTC 设备和 API 24 上。因此资源包可用于其他 API 和设备组合。
  • 我认为资源包通常是 android 的一部分。这只是一种解决方法。我假设在此设备上由于某种原因类路径已损坏,或者他们忘记添加资源或某些东西阻止了对 jar 的访问。
  • 嘿,我在哪里添加这个文件?我应该将它添加到assets 文件夹中吗?
  • 属性文件的位置取决于您的构建工具。它应该位于项目的 ressource 文件夹中,最后位于“sun/util/logging/resources/logging.properties”下的 java 类路径中。我可能会创建一个额外的项目来仅使用此文件构建一个 jar 并将其添加为依赖项。对于将在“/src/main/resources”下创建“sun/util/logging/resources/logging.properties”的maven
【解决方案2】:

如果它可以按照其他答案的建议使用资源文件是一个更好的选择,但如果这不起作用,我还有另一个选择。假设您不需要日志记录,您应该能够像这样禁用它:

try {
    Class<?> cls = Class.forName("sun.util.logging.PlatformLogger");
    Field field = cls.getDeclaredField("loggingEnabled");
    field.setAccessible(true);
    field.set(null, Boolean.FALSE);
} catch(Exception e) {
    // Failed
}

如果您尽早这样做,PlatformLogger 应该构造 DefaultLoggerProxy 而不是 JavaLoggerProxy,因此损坏的代码永远不会运行。这很丑陋,因为它依赖于内部实现细节并且因为它禁用了日志记录,但也许它适用于您的应用程序?

【讨论】:

    猜你喜欢
    • 2012-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-13
    • 2016-05-02
    • 2014-03-21
    相关资源
    最近更新 更多