jasonross / Nuwa

Nuwa, pure java implementation, can hotfix your android application.
2.96k stars 575 forks source link

java.lang.NoClassDefFoundError: cn.jiajixin.nuwa.Hack #16

Closed liericiyan closed 8 years ago

liericiyan commented 8 years ago

application继承的是MultiDexApplication,内部使用了静态变量okhttp 声明: public static final OkHttpClient client = new OkHttpClient(); 然后就报错了

jasonross commented 8 years ago

@liericiyan 看一下readme里,nuwa DSL的说明

liericiyan commented 8 years ago

不好意思,nuwa DSL的说明 我看不太明白

jasonross commented 8 years ago

nuwa{ excludeClass=['OkHttpClient.class'] }

把这个加在apply plugin 'cn.jiajixin.nuwa'的后面

liericiyan commented 8 years ago

Sorry,It's useless!

build.gradle dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile project(":nuwa") compile 'com.android.support:appcompat-v7:22.2.1' compile 'com.android.support:design:22.2.1' compile 'com.squareup.okhttp:okhttp:2.4.0' compile 'com.squareup.okio:okio:1.5.0' } apply plugin: "cn.jiajixin.nuwa" nuwa{ excludeClass=['OkHttpClient.class']

}

The error log is: E/AndroidRuntime: FATAL EXCEPTION: main Process: cn.jiajixin.nuwasample, PID: 21631 java.lang.NoClassDefFoundError: cn.jiajixin.nuwa.Hack at a.a.a.r.(Unknown Source) at a.a.a.r.(Unknown Source) at a.a.a.p.(Unknown Source) at cn.jiajixin.nuwasample.NuwaApplication.(Unknown Source) at java.lang.Class.newInstanceImpl(Native Method) at java.lang.Class.newInstance(Class.java:1214) at android.app.Instrumentation.newApplication(Instrumentation.java:990) at android.app.Instrumentation.newApplication(Instrumentation.java:975) at android.app.LoadedApk.makeApplication(LoadedApk.java:525) at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4403) at android.app.ActivityThread.access$1500(ActivityThread.java:142) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1263) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:136) at android.app.ActivityThread.main(ActivityThread.java:5118) at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invoke(Method.java:515) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:794) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:610)

at dalvik.system.NativeStart.main(Native Method)

The code is : public class NuwaApplication extends Application { public static final OkHttpClient client = new OkHttpClient(); @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); Nuwa.init(this); Nuwa.loadPatch(this, Environment.getExternalStorageDirectory().getAbsolutePath().concat("/patch.jar")); } }

jasonross commented 8 years ago

@liericiyan 继续看nuwa DSL的includePackage用法,看不懂就算了吧,要么改代码,静态初始化延迟。

liericiyan commented 8 years ago

延迟加载解决了这个问题,感谢!

AllynYonge commented 8 years ago

请问加载patch.jar时出现时,在BaseApplication初始化的时候出现 Class ref in pre-verified class resolved to unexpected implementation错误,是什么原因

gondole-zz commented 8 years ago

@JakeWoki 我试了试nuwa的sample是可以的,然后我加入了一个baseApplication 让NuwaApplication继承之,然后运行就会出现Hack类找不到的情况,你的什么情况?

dodola commented 8 years ago

@gondole 你不会忘了加权限吧,我遇到个盆友就是忘了加权限(・・)

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
gondole-zz commented 8 years ago

@dodola @JakeWoki 权限是没有问题的,只是给nuwaApplication添加了一个父类继承Application,仍会提示找不到Hack类,苦思摸索找原因中呢。。。另外DSL中说Application不用exclude 对吧。@JakeWoki 你试试加个继承application的父类给nuwaApplication继承试试啊。

dodola commented 8 years ago

@gondole 不知道这算不算个bug,出现这个问题是因为插件将你BaseApplication的构造方法里插入了 Class cls = Hack.class; 所以你应该将这个类排除在外

JakeWoki commented 8 years ago

@gondole 不用继承nuwaApplication,nuwaApplication没什么东西在里面,我项目Application本来就继承了别的

dodola commented 8 years ago

@gondole 如果excludeClass = ['BaseApplication.class'] 不能用的话,那么就不要混淆BaseApplication这个类

gondole-zz commented 8 years ago

@dodola @JakeWoki 问题已经解决。

解决方法就是dodola说的对baseApplication类移除混淆并且添加到excludeClass中。

@JakeWoki 这段代码nuwa {excludeClass = ['BaseApplication.class'] } 要和android {} 平级的。

@dodola 为什么要防止BaseApplication混淆呢?还望解答一下 :)

dodola commented 8 years ago

@gondole 因为作者是将打包后的jar包拿出来进行处理,这个时候已经是混淆的了,BaseApplication有可能已经变了名字比如a.class 这时候excludeClass的hashset里找不到a.class

dodola commented 8 years ago

@JakeWoki 写在apply plugin之后


apply plugin: "cn.jiajixin.nuwa"
nuwa{
    excludeClass = ['BaseApplication.class']

}
dodola commented 8 years ago

@JakeWoki 虽然看不出为啥,但com/activeandroid/content/ContentProvider.class 这个类应该被注入了hack.class了,ContentProvider类,你去掉混淆没

liericiyan commented 8 years ago

@JakeWoki 可以试试另一个Andfix开源热修复,不需要重启app,addpatch之后立即生效

JakeWoki commented 8 years ago

@dodola nuwa { includePackage = ['com/activeandroid'] } gradlew clean nuwaReleasePatch -P NuwaDir=F:/nuwa 这样执行BUILD SUCCESSFUL成功了,但是没有生成patch.jar,也没有相应的xxx.class生成