R8:不进行类型检查,将被假定为不可达

R8: does not type check and will be assumed to be unreachable

启用 android.enableR8.fullMode=true 时,我收到以下警告:

AGPBI: {
    "kind": "warning",
    "text": "The method `void org.apache.commons.logging.impl.Log4JLogger.<clinit>()`
             does not type check and will be assumed to be unreachable.",
    "sources": [{}],
    "tool": "R8"
}

如何明确保留 org.apache.commons.logging.impl.Log4JLogger.<clinit>() 与 R8? android.enableR8.fullMode=false(默认设置)不是一个可接受的解决方法,即使 static 初始值设定项 <clinit> 不会像那样得到优化。被剥离的代码是 this:

// ------------------------------------------------------------
// Static Initializer.
//
// Note that this must come after the static variable declarations
// otherwise initialiser expressions associated with those variables
// will override any settings done here.
//
// Verify that log4j is available, and that it is version 1.2.
// If an ExceptionInInitializerError is generated, then LogFactoryImpl
// will treat that as meaning that the appropriate underlying logging
// library is just not present - if discovery is in progress then
// discovery will continue.
// ------------------------------------------------------------

static {
    if (!Priority.class.isAssignableFrom(Level.class)) {
        // nope, this is log4j 1.3, so force an ExceptionInInitializerError
        throw new InstantiationError("Log4J 1.2 not available");
    }

    // Releases of log4j1.2 >= 1.2.12 have Priority.TRACE available, earlier
    // versions do not. If TRACE is not available, then we have to map
    // calls to Log.trace(...) onto the DEBUG level.

    Priority _traceLevel;
    try {
        _traceLevel = (Priority) Level.class.getDeclaredField("TRACE").get(null);
    } catch(Exception ex) {
        // ok, trace not available
        _traceLevel = Level.DEBUG;
    }
    traceLevel = _traceLevel;
}

这是按预期工作的,分析的细节可以在 http://issuetracker.google.com/146478391.

中看到

还提供了一个可能的解决方案,其中涉及确保 R8 编译已知 Level 和 Priority 之间的关系(Level extends Priority)。