1

cache2k looks awesome and I really want to use it in my app to cache objects, I'm getting a java.lang.NoClassDefFoundError:

See my stack trace below:

12-02 19:09:43.421 25543-25543/uk.whitecrescent.waqti E/AndroidRuntime: FATAL EXCEPTION: main
Process: uk.whitecrescent.waqti, PID: 25543
java.lang.NoClassDefFoundError: Failed resolution of: Ljavax/naming/InitialContext;
    at org.cache2k.impl.serverSide.JndiDefaultNameProvider.registerCache2kExtension(JndiDefaultNameProvider.java:37)
    at org.cache2k.core.Cache2kCoreProviderImpl.registerExtensions(Cache2kCoreProviderImpl.java:79)
    at org.cache2k.core.Cache2kCoreProviderImpl.<init>(Cache2kCoreProviderImpl.java:57)
    at java.lang.Class.newInstance(Native Method)
    at org.cache2k.spi.SingleProviderResolver.resolve(SingleProviderResolver.java:110)
    at org.cache2k.spi.SingleProviderResolver.resolve(SingleProviderResolver.java:82)
    at org.cache2k.spi.SingleProviderResolver.resolveMandatory(SingleProviderResolver.java:64)
    at org.cache2k.CacheManager.<clinit>(CacheManager.java:54)
    at org.cache2k.CacheManager.getInstance(CacheManager.java:88)
    at org.cache2k.Cache2kBuilder.config(Cache2kBuilder.java:160)
    at org.cache2k.Cache2kBuilder.enableJmx(Cache2kBuilder.java:758)
    at uk.whitecrescent.waqti.model.persistence.Caches.<clinit>(Caches.kt:74)
...
...
Caused by: java.lang.ClassNotFoundException: Didn't find class "javax.naming.InitialContext" on path: DexPathList

I know the reason it's because cache2k wants to use javax.naming which is not in Android, in fact it's in this class that it requires.

import org.cache2k.CacheManager;
import org.cache2k.spi.Cache2kExtensionProvider;

import javax.naming.Context;
import javax.naming.InitialContext;

/**
 * @author Jens Wilke; created: 2014-10-10
 */
public class JndiDefaultNameProvider implements Cache2kExtensionProvider {

  @Override
  public void registerCache2kExtension() {
    try {
      Context ctx = new InitialContext();
      ctx = (Context) ctx.lookup("java:comp/env");
      String _name =
        (String) ctx.lookup("org.cache2k.CacheManager.defaultName");
      if (_name != null) {
        CacheManager.setDefaultName(_name);
      }
    } catch (Exception ignore) {
    }
  }

}

build.gradle looks like this

ext.cache2kVersion = '1.2.0.Final'
implementation "org.cache2k:cache2k-api:$cache2kVersion"
implementation "org.cache2k:cache2k-base-bom:$cache2kVersion"
implementation "org.cache2k:cache2k-core:$cache2kVersion"

I tried having the bottom one be runtimeOnly that didn't work. I even tried downloading the javax.naming jar, only to have it depend on even more stuff.

I'm sure it's just a silly mistake on my part but I can't seem to find it!

theAlse
  • 5,577
  • 11
  • 68
  • 110
Bassam Helal
  • 380
  • 3
  • 12

1 Answers1

1

Sorry for the long time to respond and letting you down.

The cache2k jar is pretty small and I therefore decided to give up to make lots of more tiny jars. That means the JMX support is included in the jar. That's documented here: https://github.com/cache2k/cache2k/issues/80

To make it work on Android again I provided proguard rules, that strip out the JMX support. See it in the documentation here: https://cache2k.org/docs/latest/user-guide.html#android

Let me know whether that helps you and just shout if there are any further questions.

cruftex
  • 5,545
  • 2
  • 20
  • 36
  • I'm having the same problem. I've added the mandatory proguard rules that are specified [here](https://cache2k.org/docs/latest/user-guide.html#android) and yet the `NoClassDefFoundError` occurs. – miguelarc Apr 08 '19 at 16:05
  • Also, is there a way to configure cache2k without proguard rules? – miguelarc Apr 09 '19 at 09:59