带有使用protobufs的库的Android项目NoClassDefFound

时间:2016-10-18 17:19:07

标签: android protocol-buffers

我正在尝试编写一个编译成jar文件的库,并且可以包含在android项目中,但每当我向库中添加协议缓冲区时,它会在运行时抛出以下异常但不编译时间:

10-18 10:10:10.310 25071-25071/com.example.s.manualinsttest E/AndroidRuntime: FATAL EXCEPTION: main Process: com.example.s.manualinsttest, PID: 25071 java.lang.NoClassDefFoundError: Failed resolution of: Lcom/MyLibrary/Tracemsg$MyProtoContainer$MyProto; ...

我已经验证了这是一个问题,其中一个最小的例子是库包含:

public class MyLibrary{ 
    public static void myMethod(){
        Tracemsg.MyProtoContainer.MyProto proto = Tracemsg.MyProtoContainer.MyProto.newBuilder().setMynumber(5).build();
    }

}

协议缓冲区:

syntax = "proto2";
option optimize_for = LITE_RUNTIME;

package ...

message MyProtoContainer {

   message MyProto {
      required uint64 mynumber = 1;
   }

}

库编译得很好并且在从普通的java应用程序调用时运行但是当作为库包含时,我得到前面提到的异常。另外,我尝试使用jadx-gui对生成的jar文件进行反编译,实际上该类就在那里。

感谢您的帮助

1 个答案:

答案 0 :(得分:0)

解决方案原来是我使用的Gradle插件为我处理了protobuf内部工作,需要配置为编译为lite版本。我在https://github.com/google/protobuf-gradle-plugin/tree/master/testProjectLite中找到了这段代码,其中包含以下内容:

protobuf {
protoc {
    artifact = 'com.google.protobuf:protoc:3.0.0'
}
plugins {
    javalite {
        artifact = 'com.google.protobuf:protoc-gen-javalite:3.0.0'
    }
}
generateProtoTasks {
    all().each { task ->
        task.builtins {
            remove java
        }
        task.plugins {
            javalite { }
        }
    }
}
}

据我所知,你不应该在Android中使用完整的protobufs并且它有点棘手,如果你没有正确设置所有设置,它就不会回到使用完整的protobufs。