Reputation: 23
I'm trying to use jitsi/ice4j on Android but i'm having trouble with a NullPointerException
in a dependency, namely jitsi/jain-sip, jitsi-oss-only. It occurs when trying to parse a Session Description, in the LexerCore
class.
There's a similar question regarding this: ice-sdp-parse-exception. Someone found the variable that is not instantiated in one of the two constructors. This checks out.
After adding a line that is supposed to fix the NPE and some additional println
s i built the dependency and all super-dependencies (java-sdp-nist-bridge and ice4j). The thing is, the error persists. Also, the additional println
s aren't happening. So i checked the fields of LexerCore
with reflection during runtime and it seems that:
The fields of the superclass don't match the source that i edited. On Android, two static fields defined as ConcurrentHashMap
s are Hashtable
s on Android. The Map<String, Integer
reference that was null (the original problem) is suddenly a Hashtable
as well. On desktop, the field types match what i see in the source files.
The fields on Android:
protected java.util.Hashtable gov.nist.core.LexerCore.currentLexer
protected java.lang.String gov.nist.core.LexerCore.currentLexerName
protected gov.nist.core.Token gov.nist.core.LexerCore.currentMatch
public static final int gov.nist.core.LexerCore.ALPHA
static final char gov.nist.core.LexerCore.ALPHADIGIT_VALID_CHARS
static final char gov.nist.core.LexerCore.ALPHA_VALID_CHARS
public static final int gov.nist.core.LexerCore.AND
public static final int gov.nist.core.LexerCore.AT
public static final int gov.nist.core.LexerCore.BACKSLASH
public static final int gov.nist.core.LexerCore.BACK_QUOTE
public static final int gov.nist.core.LexerCore.BAR
public static final int gov.nist.core.LexerCore.COLON
public static final int gov.nist.core.LexerCore.DIGIT
static final char gov.nist.core.LexerCore.DIGIT_VALID_CHARS
public static final int gov.nist.core.LexerCore.DOLLAR
public static final int gov.nist.core.LexerCore.DOT
public static final int gov.nist.core.LexerCore.DOUBLEQUOTE
public static final int gov.nist.core.LexerCore.END
public static final int gov.nist.core.LexerCore.EQUALS
public static final int gov.nist.core.LexerCore.EXCLAMATION
public static final int gov.nist.core.LexerCore.GREATER_THAN
public static final int gov.nist.core.LexerCore.HAT
public static final int gov.nist.core.LexerCore.HT
public static final int gov.nist.core.LexerCore.ID
public static final int gov.nist.core.LexerCore.LESS_THAN
public static final int gov.nist.core.LexerCore.LPAREN
public static final int gov.nist.core.LexerCore.L_CURLY
public static final int gov.nist.core.LexerCore.L_SQUARE_BRACKET
public static final int gov.nist.core.LexerCore.MINUS
public static final int gov.nist.core.LexerCore.NULL
public static final int gov.nist.core.LexerCore.PERCENT
public static final int gov.nist.core.LexerCore.PLUS
public static final int gov.nist.core.LexerCore.POUND
public static final int gov.nist.core.LexerCore.QUESTION
public static final int gov.nist.core.LexerCore.QUOTE
public static final int gov.nist.core.LexerCore.RPAREN
public static final int gov.nist.core.LexerCore.R_CURLY
public static final int gov.nist.core.LexerCore.R_SQUARE_BRACKET
public static final int gov.nist.core.LexerCore.SAFE
public static final int gov.nist.core.LexerCore.SEMICOLON
public static final int gov.nist.core.LexerCore.SLASH
public static final int gov.nist.core.LexerCore.SP
public static final int gov.nist.core.LexerCore.STAR
public static final int gov.nist.core.LexerCore.START
public static final int gov.nist.core.LexerCore.TILDE
public static final int gov.nist.core.LexerCore.UNDERSCORE
public static final int gov.nist.core.LexerCore.WHITESPACE
protected static final java.util.Hashtable gov.nist.core.LexerCore.globalSymbolTable
protected static final java.util.Hashtable gov.nist.core.LexerCore.lexerTables
The fields on desktop, notice the dummyField
added field:
public static final int gov.nist.core.LexerCore.START
public static final int gov.nist.core.LexerCore.END
public static final int gov.nist.core.LexerCore.ID_NO_WHITESPACE
public static final int gov.nist.core.LexerCore.ID
public static final int gov.nist.core.LexerCore.SAFE
public static final int gov.nist.core.LexerCore.WHITESPACE
public static final int gov.nist.core.LexerCore.DIGIT
public static final int gov.nist.core.LexerCore.ALPHA
public static final int gov.nist.core.LexerCore.BACKSLASH
public static final int gov.nist.core.LexerCore.QUOTE
public static final int gov.nist.core.LexerCore.AT
public static final int gov.nist.core.LexerCore.SP
public static final int gov.nist.core.LexerCore.HT
public static final int gov.nist.core.LexerCore.COLON
public static final int gov.nist.core.LexerCore.STAR
public static final int gov.nist.core.LexerCore.DOLLAR
public static final int gov.nist.core.LexerCore.PLUS
public static final int gov.nist.core.LexerCore.POUND
public static final int gov.nist.core.LexerCore.MINUS
public static final int gov.nist.core.LexerCore.DOUBLEQUOTE
public static final int gov.nist.core.LexerCore.TILDE
public static final int gov.nist.core.LexerCore.BACK_QUOTE
public static final int gov.nist.core.LexerCore.NULL
public static final int gov.nist.core.LexerCore.EQUALS
public static final int gov.nist.core.LexerCore.SEMICOLON
public static final int gov.nist.core.LexerCore.SLASH
public static final int gov.nist.core.LexerCore.L_SQUARE_BRACKET
public static final int gov.nist.core.LexerCore.R_SQUARE_BRACKET
public static final int gov.nist.core.LexerCore.R_CURLY
public static final int gov.nist.core.LexerCore.L_CURLY
public static final int gov.nist.core.LexerCore.HAT
public static final int gov.nist.core.LexerCore.BAR
public static final int gov.nist.core.LexerCore.DOT
public static final int gov.nist.core.LexerCore.EXCLAMATION
public static final int gov.nist.core.LexerCore.LPAREN
public static final int gov.nist.core.LexerCore.RPAREN
public static final int gov.nist.core.LexerCore.GREATER_THAN
public static final int gov.nist.core.LexerCore.LESS_THAN
public static final int gov.nist.core.LexerCore.PERCENT
public static final int gov.nist.core.LexerCore.QUESTION
public static final int gov.nist.core.LexerCore.AND
public static final int gov.nist.core.LexerCore.UNDERSCORE
protected static final java.util.concurrent.ConcurrentHashMap gov.nist.core.LexerCore.globalSymbolTable
protected static final java.util.concurrent.ConcurrentHashMap gov.nist.core.LexerCore.lexerTables
protected java.util.Map gov.nist.core.LexerCore.currentLexer
protected java.lang.String gov.nist.core.LexerCore.dummyField
protected java.lang.String gov.nist.core.LexerCore.currentLexerName
protected gov.nist.core.Token gov.nist.core.LexerCore.currentMatch
static final char gov.nist.core.LexerCore.ALPHA_VALID_CHARS
static final char gov.nist.core.LexerCore.DIGIT_VALID_CHARS
static final char gov.nist.core.LexerCore.ALPHADIGIT_VALID_CHARS
String
field, it's absent on Android and present on desktop.I'm using the same dependency on desktop and Android, i've edited it multiple times now. Im using Maven to build the desktop app and Gradle in Android Studio.
Why is the code being executed different on Android? Reflection is used in the module but not in regards to LexerCore
, at least i did not find it being used.
Thank you for your time.
Upvotes: 2
Views: 133
Reputation: 9601
The issue is because LexerCore
appears to conflict with a hidden embedded Android framework class. Looking at the LexerCore
class with a debugger, you can find a dexCache
field which I believe indicates the location the class was loaded from. Other app classes have a path consistent with coming from the apk's dex files, but LexerCore
gives me a path /system/framework/voip-common.jar
. It looks like they have an internal copy of the NIST classes.
Not sure if it will work for Ice4J as well, but you can try shadowing the jars to avoid the class name conflict. This can be done fairly simply with a shadow plugin like https://imperceptiblethoughts.com/shadow/ to rename the packages.
Upvotes: 1