简体   繁体   中英

Google App Engine does not support subclasses of java.util.logging.Logger: com/ibm/icu/impl/ICULogger

We are using Google App Engine to publish some flat data from our application in a csv format. Google's DataTable and CsvRenderer from visualization-datasource library made the conversion of our data easy and testing succeeded in the local appengine development server.

Deploying to our appspot instance exposed that App Engine does not like the way IBM's ICU library is Logging:

Google App Engine does not support subclasses of java.util.logging.Logger: com/ibm/icu/impl/ICULogger

The stack trace shows the point of origin:

    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)

Line 114 of TimeZone:

/**
 * {@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());

I put a breakpoint in Eclipse and ran the unit tests in the debugger and TimeZoneLogger is being assigned null since there is no System property turning on the logging as seen further:

    /**
 * 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;
}

I put in some logging statements to see if TimeZoneLogger was being instantiated and it shows it is not.

[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

This shows that it's not the instantiation that App Engine doesn't like, but simply the reference to the class that causes the problem.

At this point all I can think of is to write my own CSV Renderer which is the class using the violating code. The effort would not be significant, but I would prefer to use existing libraries...especially when the library and platform both come from Google.

Any other suggestions?

You can provide your own implementation of the class to avoid this issue.

Simply take the com.ibm.icu.util.TimeZone.java file from the project (It's open source). Then put it into your own project - keeping the package and class name the same. "Your" version will then override the one from the jar library and you can change it.

If it doesn't then check your build path order for the project. On the productive server classes are before libs so it will also work.

I made these hacky modifications to get it to work but you might make better ones :)

line ~114:

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

line ~780: comment this out too.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM