Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable log4j JMX on Android

I am trying to port the Hyperledger Fabric Java SDK v1.4 to Android (API level 26). The SDK uses Log4j v2.13. Log4j is not quite optimised for android. I get the following error:

I/System.out: WARNING: sun.reflect.Reflection.getCallerClass is not supported. This will impact performance.
I/icandroidsampl: 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;
        at void org.apache.logging.log4j.core.lookup.JmxRuntimeInputArgumentsLookup.<clinit>() (JmxRuntimeInputArgumentsLookup.java:35)
        at java.lang.Object java.lang.reflect.Constructor.newInstance0(java.lang.Object[]) (Constructor.java:-2)
        at java.lang.Object java.lang.reflect.Constructor.newInstance(java.lang.Object[]) (Constructor.java:343)
        at java.lang.Object org.apache.logging.log4j.util.LoaderUtil.newInstanceOf(java.lang.Class) (LoaderUtil.java:185)
        at java.lang.Object org.apache.logging.log4j.util.LoaderUtil.newInstanceOf(java.lang.String) (LoaderUtil.java:207)
        at java.lang.Object org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOf(java.lang.String, java.lang.Class) (LoaderUtil.java:228)
        at java.lang.Object org.apache.logging.log4j.core.util.Loader.newCheckedInstanceOf(java.lang.String, java.lang.Class) (Loader.java:311)
        at void org.apache.logging.log4j.core.lookup.Interpolator.<init>(java.util.Map) (Interpolator.java:120)
        at void org.apache.logging.log4j.core.config.AbstractConfiguration.<init>(org.apache.logging.log4j.core.LoggerContext, org.apache.logging.log4j.core.config.ConfigurationSource) (AbstractConfiguration.java:129)
        at void org.apache.logging.log4j.core.config.NullConfiguration.<init>() (NullConfiguration.java:32)
        at void org.apache.logging.log4j.core.LoggerContext.<clinit>() (LoggerContext.java:86)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.createContext(java.lang.String, java.net.URI) (ClassLoaderContextSelector.java:229)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.locateContext(java.lang.ClassLoader, java.net.URI) (ClassLoaderContextSelector.java:203)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(java.lang.String, java.lang.ClassLoader, boolean, java.net.URI) (ClassLoaderContextSelector.java:128)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(java.lang.String, java.lang.ClassLoader, boolean) (ClassLoaderContextSelector.java:115)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(java.lang.String, java.lang.ClassLoader, java.lang.Object, boolean) (Log4jContextFactory.java:148)
        at org.apache.logging.log4j.spi.LoggerContext org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(java.lang.String, java.lang.ClassLoader, java.lang.Object, boolean) (Log4jContextFactory.java:45)
        at org.apache.logging.log4j.spi.LoggerContext org.apache.logging.log4j.LogManager.getContext(java.lang.ClassLoader, boolean) (LogManager.java:194)
        at org.apache.logging.log4j.spi.LoggerContext org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(java.lang.Class) (AbstractLoggerAdapter.java:138)
        at org.apache.logging.log4j.spi.LoggerContext org.apache.logging.log4j.jcl.LogAdapter.getContext() (LogAdapter.java:39)
        at java.lang.Object org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(java.lang.String) (AbstractLoggerAdapter.java:48)
        at org.apache.commons.logging.Log org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(java.lang.String) (LogFactoryImpl.java:40)
        at org.apache.commons.logging.Log org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(java.lang.Class) (LogFactoryImpl.java:55)
        at org.apache.commons.logging.Log org.apache.commons.logging.LogFactory.getLog(java.lang.Class) (LogFactory.java:655)
        at void org.hyperledger.fabric.gateway.impl.GatewayImpl.<clinit>() (GatewayImpl.java:55)
        at java.util.concurrent.TimeUnit org.hyperledger.fabric.gateway.impl.GatewayImpl.access$000() (GatewayImpl.java:54)
        at void org.hyperledger.fabric.gateway.impl.GatewayImpl$Builder.<init>() (GatewayImpl.java:71)
        at org.hyperledger.fabric.gateway.Gateway$Builder org.hyperledger.fabric.gateway.Gateway.createBuilder() (Gateway.java:87)
        at java.lang.String tubs.ibr.fabricandroidsample.MainActivity$FabricRequestTask.doInBackground(java.lang.Object[]) (MainActivity.java:78)
        at java.lang.Object tubs.ibr.fabricandroidsample.MainActivity$FabricRequestTask.doInBackground(java.lang.Object[]) (MainActivity.java:70)
        at java.lang.Object android.os.AsyncTask$2.call() (AsyncTask.java:333)
        at void java.util.concurrent.FutureTask.run() (FutureTask.java:266)
        at void android.os.AsyncTask$SerialExecutor$1.run() (AsyncTask.java:245)
        at void java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) (ThreadPoolExecutor.java:1167)
        at void java.util.concurrent.ThreadPoolExecutor$Worker.run() (ThreadPoolExecutor.java:641)
I/icandroidsampl:     at void java.lang.Thread.run() (Thread.java:764)
    Caused by: java.lang.ClassNotFoundException: Didn't find class "java.lang.management.ManagementFactory" on path: DexPathList[[zip file "/data/app/tubs.ibr.fabricandroidsample-48U2GXMv9D0UPIKFDpmpOA==/base.apk"],nativeLibraryDirectories=[/data/app/tubs.ibr.fabricandroidsample-48U2GXMv9D0UPIKFDpmpOA==/lib/x86, /system/lib]]
        at java.lang.Class dalvik.system.BaseDexClassLoader.findClass(java.lang.String) (BaseDexClassLoader.java:134)
        at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String, boolean) (ClassLoader.java:379)
        at java.lang.Class java.lang.ClassLoader.loadClass(java.lang.String) (ClassLoader.java:312)
        at void org.apache.logging.log4j.core.lookup.JmxRuntimeInputArgumentsLookup.<clinit>() (JmxRuntimeInputArgumentsLookup.java:35)
        at java.lang.Object java.lang.reflect.Constructor.newInstance0(java.lang.Object[]) (Constructor.java:-2)
        at java.lang.Object java.lang.reflect.Constructor.newInstance(java.lang.Object[]) (Constructor.java:343)
        at java.lang.Object org.apache.logging.log4j.util.LoaderUtil.newInstanceOf(java.lang.Class) (LoaderUtil.java:185)
        at java.lang.Object org.apache.logging.log4j.util.LoaderUtil.newInstanceOf(java.lang.String) (LoaderUtil.java:207)
        at java.lang.Object org.apache.logging.log4j.util.LoaderUtil.newCheckedInstanceOf(java.lang.String, java.lang.Class) (LoaderUtil.java:228)
        at java.lang.Object org.apache.logging.log4j.core.util.Loader.newCheckedInstanceOf(java.lang.String, java.lang.Class) (Loader.java:311)
        at void org.apache.logging.log4j.core.lookup.Interpolator.<init>(java.util.Map) (Interpolator.java:120)
        at void org.apache.logging.log4j.core.config.AbstractConfiguration.<init>(org.apache.logging.log4j.core.LoggerContext, org.apache.logging.log4j.core.config.ConfigurationSource) (AbstractConfiguration.java:129)
        at void org.apache.logging.log4j.core.config.NullConfiguration.<init>() (NullConfiguration.java:32)
        at void org.apache.logging.log4j.core.LoggerContext.<clinit>() (LoggerContext.java:86)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.createContext(java.lang.String, java.net.URI) (ClassLoaderContextSelector.java:229)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.locateContext(java.lang.ClassLoader, java.net.URI) (ClassLoaderContextSelector.java:203)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(java.lang.String, java.lang.ClassLoader, boolean, java.net.URI) (ClassLoaderContextSelector.java:128)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.selector.ClassLoaderContextSelector.getContext(java.lang.String, java.lang.ClassLoader, boolean) (ClassLoaderContextSelector.java:115)
        at org.apache.logging.log4j.core.LoggerContext org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(java.lang.String, java.lang.ClassLoader, java.lang.Object, boolean) (Log4jContextFactory.java:148)
        at org.apache.logging.log4j.spi.LoggerContext org.apache.logging.log4j.core.impl.Log4jContextFactory.getContext(java.lang.String, java.lang.ClassLoader, java.lang.Object, boolean) (Log4jContextFactory.java:45)
        at org.apache.logging.log4j.spi.LoggerContext org.apache.logging.log4j.LogManager.getContext(java.lang.ClassLoader, boolean) (LogManager.java:194)
        at org.apache.logging.log4j.spi.LoggerContext org.apache.logging.log4j.spi.AbstractLoggerAdapter.getContext(java.lang.Class) (AbstractLoggerAdapter.java:138)
        at org.apache.logging.log4j.spi.LoggerContext org.apache.logging.log4j.jcl.LogAdapter.getContext() (LogAdapter.java:39)
        at java.lang.Object org.apache.logging.log4j.spi.AbstractLoggerAdapter.getLogger(java.lang.String) (AbstractLoggerAdapter.java:48)
I/icandroidsampl:     at org.apache.commons.logging.Log org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(java.lang.String) (LogFactoryImpl.java:40)
        at org.apache.commons.logging.Log org.apache.logging.log4j.jcl.LogFactoryImpl.getInstance(java.lang.Class) (LogFactoryImpl.java:55)
        at org.apache.commons.logging.Log org.apache.commons.logging.LogFactory.getLog(java.lang.Class) (LogFactory.java:655)
        at void org.hyperledger.fabric.gateway.impl.GatewayImpl.<clinit>() (GatewayImpl.java:55)
        at java.util.concurrent.TimeUnit org.hyperledger.fabric.gateway.impl.GatewayImpl.access$000() (GatewayImpl.java:54)
        at void org.hyperledger.fabric.gateway.impl.GatewayImpl$Builder.<init>() (GatewayImpl.java:71)
        at org.hyperledger.fabric.gateway.Gateway$Builder org.hyperledger.fabric.gateway.Gateway.createBuilder() (Gateway.java:87)
        at java.lang.String tubs.ibr.fabricandroidsample.MainActivity$FabricRequestTask.doInBackground(java.lang.Object[]) (MainActivity.java:78)
        at java.lang.Object tubs.ibr.fabricandroidsample.MainActivity$FabricRequestTask.doInBackground(java.lang.Object[]) (MainActivity.java:70)
        at java.lang.Object android.os.AsyncTask$2.call() (AsyncTask.java:333)
        at void java.util.concurrent.FutureTask.run() (FutureTask.java:266)
        at void android.os.AsyncTask$SerialExecutor$1.run() (AsyncTask.java:245)
        at void java.util.concurrent.ThreadPoolExecutor.runWorker(java.util.concurrent.ThreadPoolExecutor$Worker) (ThreadPoolExecutor.java:1167)
        at void java.util.concurrent.ThreadPoolExecutor$Worker.run() (ThreadPoolExecutor.java:641)
        at void java.lang.Thread.run() (Thread.java:764)

This happens because java.lang.management.ManagementFactory is not included in the Android Runtime.

So, I tried to disable JMX. No success. Same error. Seams like the system property is not in the 'scope' of the library? How is this possible?

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        System.setProperty("log4j2.disable.jmx","true");

        [...]
    }
[...]
}

I also tried this: https://loune.net/2016/05/using-log4j2-2-3-with-android/. No success. Same error.

The problem is, that Log4j is used in the library I am using. So I'm not looking for a way to use logging in Android, but a way to configure Log4j in Android, so it stops throwing exceptions.

The code actually runs although the exceptions.

like image 807
TheDarkTron Avatar asked Dec 05 '25 05:12

TheDarkTron


1 Answers

Log4j 2 does not officially support Android. This is primarily because none of the Log4j committers develop for Android. That said, we would be open to get it working provide we have participants who can help to get it working and verify new releases. I would suggest you participate on the Log4j developer's list and offer whatever assistance you can. This would primarily consist of reporting errors like the one above, possibly submitting patch requests, and testing fixes. With that said, due to the limitations Android places on the classes in the JDK I can't guarantee that all the problems can be worked out but we would be happy to try.

After having said all of that, in looking at the current code you should simply be getting a warning that JMX is not available and initialization should continue. You haven't said what version of Log4j you tried with but what you experienced should not be the current behavior.

One final point. In looking at the stack trace above the code in question is not dependent on Log4j. It is using Apache Commons Logging. Presumably you have the log4j-jcl jar in the project which is why Log4j is getting involved. You could instead route the Commons Logging calls to anything.

like image 70
rgoers Avatar answered Dec 07 '25 18:12

rgoers



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!