【问题标题】:Google App Engine does not support subclasses of java.util.logging.Logger: com/ibm/icu/impl/ICULoggerGoogle App Engine 不支持 java.util.logging.Logger 的子类:com/ibm/icu/impl/ICULogger
【发布时间】:2013-10-29 09:02:23
【问题描述】:

我们正在使用 Google App Engine 从我们的应用程序中以 csv 格式发布一些平面数据。 Google 的DataTableCsvRenderer 来自visualization-datasource 库使我们的数据转换变得容易,并且在本地appengine 开发服务器中测试成功。

部署到我们的 apppot 实例暴露了 App Engine 不喜欢 IBM 的 ICU 库记录日志的方式:

Google App Engine 不支持 java.util.logging.Logger 的子类:com/ibm/icu/impl/ICULogger

堆栈跟踪显示原点:

    Caused by: java.lang.SecurityException: Google App Engine does not support subclasses of     java.util.logging.Logger: com/ibm/icu/impl/ICULogger
at com.google.appengine.runtime.Request.process-0b3cd097cad783e6(Request.java)
at java.lang.ClassLoader.loadClass(ClassLoader.java:360)
at com.ibm.icu.util.TimeZone.<clinit>(TimeZone.java:114)

时区第 114 行:

/**
 * {@icu} A logger for TimeZone. Will be null if logging is not on by way of system
 * property: "icu4j.debug.logging"
 * @draft ICU 4.4
 * @provisional This API might change or be removed in a future release.
 */
public static ICULogger TimeZoneLogger = ICULogger.getICULogger(TimeZone.class.getName());

我在 Eclipse 中放置了一个断点并在调试器中运行了单元测试,并且 TimeZoneLogger 被分配为 null,因为没有打开日志记录的系统属性,如下所示:

    /**
 * Instantiates a new ICULogger object with logging turned off by default
 * unless the system property "icu4j.debug.logging" is set to "all"
 *
 * @param name to be use by the logger (usually is the class name)
 * @param resourceBundleName name to localize messages (can be null)
 * @return a new ICULogger object
 * @draft ICU 4.4
 * @provisional This API might change or be removed in a future release.
 */
public static ICULogger getICULogger(String name, String resourceBundleName) {
    LOGGER_STATUS flag = checkGlobalLoggingFlag();
    if (flag != LOGGER_STATUS.NULL) {
        ICULogger logger = new ICULogger(name, resourceBundleName);

        /* Add a default handler to logger*/
        logger.addHandler(new ConsoleHandler());

        /* Turn off logging by default unless SYSTEM_PROP_LOGGER property is set to "all" */
        if (flag == LOGGER_STATUS.ON) {
            logger.turnOnLogging();
        } else {
            logger.turnOffLogging();
        }

        return logger;
    }
    return null;
}

我输入了一些日志语句来查看 TimeZoneLogger 是否正在被实例化,它表明它不是。

[INFO] Oct 29, 2013 8:45:39 AM  com.example.SomeClass
[INFO] WARNING: icu4j.debug.logging = null
[INFO] Oct 29, 2013 8:45:39 AM com.example.SomeClass
[INFO] WARNING: Time Zone Logger = null

这表明不是 App Engine 不喜欢的实例化,而只是对导致问题的类的引用。

此时我能想到的就是编写自己的 CSV 渲染器,它是使用违规代码的类。工作量不会很大,但我更喜欢使用现有的库……尤其是当库和平台都来自 Google 时。

还有其他建议吗?

【问题讨论】:

    标签: java google-app-engine logging google-visualization


    【解决方案1】:

    您可以提供自己的类实现来避免这个问题。

    只需从项目中获取 com.ibm.icu.util.TimeZone.java 文件(它是开源的)。然后把它放到你自己的项目中——保持包名和类名相同。然后,“您的”版本将覆盖 jar 库中的版本,您可以更改它。

    如果没有,请检查项目的构建路径顺序。在生产服务器上,类在库之前,所以它也可以工作。

    我做了这些 hacky 修改以使其正常工作,但您可能会做出更好的修改 :)

    ~114 行:

    public static Object TimeZoneLogger = null; // ICULogger.getICULogger(TimeZone.class.getName());
    

    第 ~780 行:也将其注释掉。

           if (TimeZoneLogger != null && TimeZoneLogger.isLoggingOn()) {
                 TimeZoneLogger.warning(
                   "\"" +ID + "\" is a bogus id so timezone is falling back to Etc/Unknown(GMT).");
          }
    

    【讨论】:

    • 好主意。我过去成功破解了一些这样的课程。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 2017-03-24
    相关资源
    最近更新 更多