Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 6.0 (Marshmallow) static initialization exception on getDeclaredField() in svg-android library

I'm having some serious problem with this code, from svg-android:

public class ParserHelper {

private static final Field STRING_CHARS;
static {
    try {
        STRING_CHARS = String.class.getDeclaredField("value"); //<-- exception here
        STRING_CHARS.setAccessible(true);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
}

private final char[] s;
private final int n;
private char current;
public int pos;

public ParserHelper(String str, int pos) {
    try {
        this.s = (char[]) STRING_CHARS.get(str); 
    } catch (Exception e) {
        throw new RuntimeException(e);
    }
    this.pos = pos;
    n = s.length;
    current = s[pos];
}

the STRING_CHARS = String.class.getDeclaredField("value");throws the excpetion

10-09 10:25:58.240: E/AndroidRuntime(3430): Caused by: java.lang.RuntimeException: java.lang.NoSuchFieldException: No field value in class Ljava/lang/String; (declaration of 'java.lang.String' appears in /system/framework/core-libart.jar)

I can't continue the job. Only in Android 6.0 Marshmallow. Any idea?

SOLVED: Now, I did not solved the static initialization issue but I changed the char[] s initialization:

public class ParserHelper {

//  private static final Field STRING_CHARS;
//  static {
//      try {
//          STRING_CHARS = String.class.getDeclaredField("value");
//          STRING_CHARS.setAccessible(true);
//      } catch (Exception e) {
//          throw new RuntimeException(e);
//      }
//  }

    private final char[] s;
    private final int n;
    private char current;
    public int pos;

    public ParserHelper(String str, int pos) {
        try {
            s = new char[str.length()];
            str.getChars(0, str.length(), this.s, 0); //<-- here
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        this.pos = pos;
        n = s.length;
        current = s[pos];
    }
like image 798
Seraphim's Avatar asked Oct 09 '15 10:10

Seraphim's


1 Answers

Looks like the String's private field called value which holds the array of chars was renamed to ASCII in the Marshmallow. Thus you have a RuntimeException in these lines (taken from the com.larvalabs.svgandroid.ParserHelper class):

    try {
        STRING_CHARS = String.class.getDeclaredField("value");
        STRING_CHARS.setAccessible(true);
    } catch (Exception e) {
        throw new RuntimeException(e);
    }

The svgandroid is discontinued, so there is little chance that the project's author will fix this issue and push the new jar to maven.You can make your own fork of svgandroid library, merge this pull-request, build the jar and use it from now on instead of mavenized version.

Or you can go a little further, and push the fixed version to mvnrepository yourself. :)

like image 153
aga Avatar answered Oct 22 '22 07:10

aga