I'm trying to obfuscate an Android app code via Proguard. After processing with proguard the app is working by itself, however native calls made from c to java are failing with java.lang.NoSuchMethodError
.
This code is from the native part, where a call is made to the java class instance, named EngineStarted:
void callEngineStarted( JNIEnv* env, bool isStreamOne )
{
jclass cls;
if(isStreamOne == true) {
cls = ( *env )->GetObjectClass( env, currentObjectOne );
} else {
cls = ( *env )->GetObjectClass( env, currentObjectTwo );
}
jmethodID midCallBack = ( *env )->GetMethodID( env, cls, "EngineStarted", "(I)V" );
if (0 == midCallBack) {
LOGW("Could not find EngineStarted method in class");
return;
}
if(isStreamOne == true) {
( *env )->CallVoidMethod( env, currentObjectOne, midCallBack, 1 );
} else {
( *env )->CallVoidMethod( env, currentObjectTwo, midCallBack, 0 );
}
}
The java has this method. It is only called from the native part, and not anywhere else. Because of that, proguard is removing the method.
public void EngineStarted ( int isStreamOne )
{
Log.v( "decoderService", "PDecoder - Engine started, using stream " + ( isStreamOne == 1 ? "one" : "two" ) );
this.isStreamOne = isStreamOne == 1;
// Initialize the player
InitializePlayer( isStreamOne );
}
I've tried adding this to proguard-project.txt, but did not solve the problem.
-keep class com.emrahgunduz.AppBase.Services.PlayService.players.pDecoders.PDecoderNative {
void EngineStarted( int );
void PositionChanged( int );
void SetDuration( int );
void Completed();
void CompletedWithFade();
void Spectrum ( *** );
}
After compiling, mapping.txt does not include the methods, I suspect proguard removes them. How can I keep these methods getting removed and/or renamed?
EDIT / SOLUTION:
I was able to solve the problem by changing full location with a wildcard. This saved some of the methods but was not enough. Don't know why but one other method (void InitializePlayer(int)
) that was called by the dumped ones were also being dumped which somehow created a chain reaction. Adding this method solved the remaining missing methods. The final solution became
-keepclassmembers class **.PDecoderNative {
native <methods>;
void InitializePlayer(int);
void EngineStarted(int);
void PositionChanged(int);
void SetDuration(int);
void Completed();
void CompletedWithFade();
void Spectrum(float[]);
}
EDIT: The problem was not with the proguard, but with proguard not being able to read the project.txt file from time to time. Moved the whole project to a new location on disk and re-created the file. It is working perfectly.