Luca Parolari
Luca Parolari

Reputation: 15

NoClassDefFoundError no sense

I'm discovering a problem with an Android application.

My problem is that when I open the application it crashes giving NoClassDefFoundError. This is the stack trace:

09-24 19:37:14.542 32545-32545/? E/AndroidRuntime: FATAL EXCEPTION: main
Process: it.bcv.invadelite, PID: 32545
java.lang.NoClassDefFoundError: com.electronwill.nightconfig.core.file.FormatDetector$$Lambda$0
    at com.electronwill.nightconfig.core.file.FormatDetector.registerExtension(FormatDetector.java:27)
    at com.electronwill.nightconfig.json.JsonFormat.<clinit>(JsonFormat.java:66)
    at it.bcv.invade.appdb.ConfigAdapter.<init>(ConfigAdapter.java:39)
    at it.bcv.invade.appdb.Db.<init>(Db.java:51)
    at it.bcv.invade.appdb.Db.init(Db.java:75)
    at it.bcv.invadelite.activities.StartActivity.initDatabase(StartActivity.java:165)
    at it.bcv.invadelite.activities.StartActivity.onCreate(StartActivity.java:125)
    [...]

and build.gradle file has following lines:

// https://github.com/TheElectronWill/Night-Config
implementation 'com.github.TheElectronWill.Night-Config:core:3.1.0'
implementation 'com.github.TheElectronWill.Night-Config:json:3.1.0'

The FormatDetector class is like this

private static final Map<String, Supplier<ConfigFormat<?>>> registry = new ConcurrentHashMap<>();

/**
 * Registers a ConfigFormat for a specific fileExtension.
 *
 * @param fileExtension the file extension
 * @param format        the config format
 */
public static void registerExtension(String fileExtension, ConfigFormat<?> format) {
    registry.put(fileExtension, () -> format);
}

while the JsonFormat class has this declaration

private static final JsonFormat<FancyJsonWriter> FANCY = new JsonFormat<FancyJsonWriter>() {
    @Override
    public FancyJsonWriter createWriter() {
        return new FancyJsonWriter();
    }

    @Override
    public ConfigParser<Config> createParser() {
        return new JsonParser(this);
    }
};

static {
    FormatDetector.registerExtension("json", FANCY);
}

I've googled about this error and I found that could be due to the missing of some classes in the classpath. For this reason I've analyzed the apk with Android Studio analyzer and i found that in classes.dex there are both packages com.electronwill.nightconfig.core and com.electronwill.nightconfig.json that are the only two package that I'm using.

I've debugged the application on many phones, and the only that is causing problems has Android 5.1.1. I don't know if other versions of Android can cause problems but I think that the Android version is not the core problem.

Anyone can help me to solve this please? Anyone knows why I'm getting this error even with gradle and only in one phone?

Upvotes: 1

Views: 708

Answers (4)

ElectronWill
ElectronWill

Reputation: 823

NightConfig author here.

Android studio tools do work with lambdas, but older versions of Android don't have the Supplier class, which is used by my FormatDetector. This is probably what causes the error.

You should use the new NightConfig *_android modules, which are adapted for older Android APIs.

Upvotes: 1

Luca Parolari
Luca Parolari

Reputation: 15

I've solved the issue with a different approach to the problem.

In the db lib I had a ConfigAdapter class used to wrap some functionalities from Night-Config lib.

I've transformed this class into an interface like this:

/**
 * Find and return value at searched key, or default.
 *
 * @param k   The key to search
 * @param def The default value if object not found
 * @param <T> The value's type
 * @return The value at {@code k} or {@code def}
 */
<T> T get(String k, T def);

/**
 * Replaces old value with new one, return old.
 *
 * @param k     The value's key
 * @param v     The value to set
 * @param <T>   The type of old value
 * @return      The old value if any, or null
 */
<T> T put(String k, T v);

/**
 * Closes the config resource.
 */
void close();

than I on my application I've created the ConfigAdapterImpl class like this

public class ConfigAdapterImpl implements ConfigAdapter {

    private SharedPreferences preferences;

    public ConfigAdapterImpl(SharedPreferences _preferences) {
        preferences = _preferences;
    }

    @Override
    public <T> T get(String s, T t) {
        Map<String, ?> all = preferences.getAll();

        // Watch out unchecked cast!

        if (all.get(s) != null)
            return (T) all.get(s);
        else return t;
    }


    @Override
    public <T> T put(String s, T t) {
        SharedPreferences.Editor editor = preferences.edit();

        T oldVal = get(s, null);

        if (t instanceof String)
            editor.putString(s, (String) t);
        else if (t instanceof Integer)
            editor.putInt(s, (Integer) t);
        else if (t instanceof Boolean)
            editor.putBoolean(s, (Boolean) t);

        editor.apply();
        return oldVal;
    }

    @Override
    public void close() {

    }
}

With this implementation the configurations are handled by the Android preferences manager, and my lib uses them like the Night-Config object.

Upvotes: 0

Markus Penguin
Markus Penguin

Reputation: 1661

The library you are using uses a Java 8 feature (lambda) that is not supported by your current setup. The problem is in this line:

registry.put(fileExtension, () -> format);

You will find step-by-step information on how to use Java 8 features in Android in the official docs. This will usually mean upgrading the Android plugin to 3.0.0 or higher and changing the source and target compatibility in your build.gradle:

android {
  compileOptions {
    sourceCompatibility JavaVersion.VERSION_1_8
    targetCompatibility JavaVersion.VERSION_1_8
  }
}

Android does not support all Java 8 features; also some features are not available below API 24 (Android 7).

Upvotes: 2

JFPicard
JFPicard

Reputation: 5168

I don't really know graddle, but if I check the maven repository, maybe the depency should be noted as:

compile group: 'com.electronwill.night-config', name: 'core', version: '3.3.1'

see:

https://mvnrepository.com/artifact/com.electronwill.night-config/core/3.3.1

Upvotes: 1

Related Questions