dialogflow / dialogflow-android-client

Android SDK for Dialogflow
https://dialogflow.com
Apache License 2.0
575 stars 270 forks source link

Class loading warnings due to Log4J and JMX #34

Open eugenelozada opened 7 years ago

eugenelozada commented 7 years ago

I'm seeing these warnings on application startup

Rejecting re-init on previously-failed class java.lang.Class<org.apache.logging.log4j.core.lookup.JmxRuntimeInputArgumentsLookup>: java.lang.NoClassDefFoundError: Failed resolution of: Ljava/lang/management/ManagementFactory;

Likely due to the Java VM Android is running does not have those classes. Anyway we can exclude them fro being loaded or referenced? App still runs fine though.

robpridham-bbc commented 7 years ago

I have the same but the app doesn't run fine for me - it crashes on pressing any button. This is on Android O Developer Preview but I understand that ManagementFactory was removed in API 20.

viveks9 commented 7 years ago

Seeing this issue on 7.1. Any work around for this issue ?

sergiandreplace commented 7 years ago

Lint reports all these imports not existing in Android:

../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.2/c707664e020218f8529b9a5e55016ee15f0f82ac/log4j-core-2.2.jar: Invalid package reference in library; not included in Android: java.lang.management. Referenced from org.apache.logging.log4j.core.jmx.Server.
../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.2/c707664e020218f8529b9a5e55016ee15f0f82ac/log4j-core-2.2.jar: Invalid package reference in library; not included in Android: javax.jms. Referenced from org.apache.logging.log4j.core.appender.mom.JmsAppender.
../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.2/c707664e020218f8529b9a5e55016ee15f0f82ac/log4j-core-2.2.jar: Invalid package reference in library; not included in Android: javax.mail.internet. Referenced from org.apache.logging.log4j.core.net.MimeMessageBuilder.
../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.2/c707664e020218f8529b9a5e55016ee15f0f82ac/log4j-core-2.2.jar: Invalid package reference in library; not included in Android: javax.mail.util. Referenced from org.apache.logging.log4j.core.net.SmtpManager.
../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.2/c707664e020218f8529b9a5e55016ee15f0f82ac/log4j-core-2.2.jar: Invalid package reference in library; not included in Android: javax.mail. Referenced from org.apache.logging.log4j.core.net.SmtpManager.
../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.2/c707664e020218f8529b9a5e55016ee15f0f82ac/log4j-core-2.2.jar: Invalid package reference in library; not included in Android: javax.management. Referenced from org.apache.logging.log4j.core.jmx.AppenderAdmin.
../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.2/c707664e020218f8529b9a5e55016ee15f0f82ac/log4j-core-2.2.jar: Invalid package reference in library; not included in Android: javax.naming. Referenced from org.apache.logging.log4j.core.appender.db.jdbc.DataSourceConnectionSource.
../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.2/c707664e020218f8529b9a5e55016ee15f0f82ac/log4j-core-2.2.jar: Invalid package reference in library; not included in Android: javax.persistence. Referenced from org.apache.logging.log4j.core.appender.db.jpa.JpaDatabaseManager.
../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.2/c707664e020218f8529b9a5e55016ee15f0f82ac/log4j-core-2.2.jar: Invalid package reference in library; not included in Android: javax.xml.bind. Referenced from org.apache.logging.log4j.core.config.plugins.convert.TypeConverters.ByteArrayConverter.
sergiandreplace commented 7 years ago

In my case, being a lint issue, I solved it by adding this configuration:

  <issue id="InvalidPackage">
    <ignore regexp="org.apache.logging.log4j.core.*"/>
  </issue>
tao1 commented 7 years ago

It crashes my app on Android O java.lang.NoClassDefFoundError: org.apache.logging.log4j.core.lookup.JmxRuntimeInputArgumentsLookup at java.lang.reflect.Constructor.newInstance0(Native Method) at java.lang.reflect.Constructor.newInstance(Constructor.java:334) at org.apache.logging.log4j.core.util.ReflectionUtil.instantiate(ReflectionUtil.java:185) at org.apache.logging.log4j.core.lookup.Interpolator.(Interpolator.java:65) at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:346) at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:161) at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:359) at org.apache.logging.log4j.core.LoggerContext.reconfigure(LoggerContext.java:420) at org.apache.logging.log4j.core.LoggerContext.start(LoggerContext.java:138) at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:147) at org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(Log4jContextFactory.java:41) at org.apache.logging.log4j.LogManager.getContext(LogManager.java:175) at org.apache.logging.log4j.LogManager.getLogger(LogManager.java:426) at ai.api.AIDataService.(AIDataService.java:59) at ai.api.android.AIService.(AIService.java:81)

Vandalko commented 7 years ago

https://github.com/api-ai/apiai-android-client has transitive dependency on https://github.com/api-ai/apiai-java-client Which adds log4j to your app.

log4j was not really designed to work on Android VM, so the best way to solve your issue is to use different implementation.

  compile 'ai.api:sdk:2.0.5@aar'
// api.ai SDK dependencies
  compile('ai.api:libai:1.4.8') {
    exclude module: 'log4j-core'
  }

The example below still uses log4j-api as logging entry-point, but it excludes whole implementation nonsense. Then, the simplest way to configure default logging is by log4j2.component.properties resource file:

log4j2.loggerContextFactory=org.apache.logging.log4j.simple.SimpleLoggerContextFactory

Define default log level log4j2.simplelog.properties

org.apache.logging.log4j.simplelog.level=DEBUG

Similar thing can be achieved in code - just add to your Application class:

  static {
    LogManager.setFactory(new SimpleLoggerContextFactory());
    // but SimpleLoggerContextFactory does not allow to override log level in runtime
   // I guess you would need to play with root logger, but it's easier to set it in resource file
  }

At the end, your logs would be visible in stderr. Ofc, you may also do your own LoggerContextFactory implementation.

sergiandreplace commented 6 years ago

Question, when mentioning "Then, the simplest way to configure default logging is by log4j2.component.properties resource file:"

Where and how to setup this file for an Android project?

Vandalko commented 6 years ago

@sergiandreplace Just put into src/main/resources folder

> tail -vn +1 src/main/resources/*
==> src/main/resources/log4j2.component.properties <==
log4j2.loggerContextFactory=org.apache.logging.log4j.simple.SimpleLoggerContextFactory
==> src/main/resources/log4j2.simplelog.properties <==
org.apache.logging.log4j.simplelog.level=DEBUG
sergiandreplace commented 6 years ago

Thanks, now it works perfectly on Android 8, buuuut, lint is not happy about it. It returns the error:

Package not included in Android
../../../../../.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-api/2.2/d7ef6ad7ff0711dd12fe409d62d72d6ed14516e0/log4j-api-2.2.jar: Invalid package reference in library; not included in Android: java.lang.management. Referenced from org.apache.logging.log4j.message.ExtendedThreadInformation.
This check scans through libraries looking for calls to APIs that are not included in Android.

As the ExtendedThreadInformation class is referencing java.lang.management classes that are not included in Android.

One option is to ignore the error, but I'm not really happy ignoring InvalidPackage errors.

sergiandreplace commented 6 years ago

More info. If I remove the exclusion on log4j-core, the apps crashes, but lint says nothing about the java.lang.management issue, despite the classes are not there. This looks like a weird behaviour from Lint.

sergiandreplace commented 6 years ago

No news on this issue? We stopped using dialogflow because this (it was an experimental feature)

But, as @vandalko said, log4j is not intended for android, so, why is this library using it?

I think df team should really remove it