JGit克隆仓库失败求助:NoSuchMethodError错误排查与修复
JGit克隆仓库崩溃问题修复方案
问题描述
使用JGit的CloneCommand克隆公共仓库时,进度走到Checking out files阶段直接崩溃,相关信息如下:
进度日志
-remote: Compressing objects -receiving objects -resolving deltas -Checking out files [And here app crashed]
克隆实现代码
ExecutorService executor = Executors.newSingleThreadExecutor(); final Handler handler = new Handler(Looper.getMainLooper()); executor.execute( new Runnable() { @Override public void run() { try { Log.e("GitDebug",file.getAbsolutePath()); Log.e("GitDebug",username); // Log.e("GitDebug",password); Log.e("GitDebug",url); CloneCommand clone = Git.cloneRepository(); clone.setURI(url); clone.setDirectory(file); clone.setBare(false); clone.setCloneAllBranches(true); if (setUseCredentialsProvider) { // clone.setCredentialsProvider(new UsernamePasswordCredentialsProvider(username, password)); } clone.setProgressMonitor( new ProgressMonitor() { @Override public void start(int arg0) {} @Override public void beginTask(String arg0, int arg1) { gitCallback.onProgress(arg0,arg1); } @Override public void update(int arg0) {} @Override public void endTask() {} @Override public boolean isCancelled() { return false; } @Override public void showDuration(boolean arg0) {} }); clone.call(); gitCallback.onProgressComplete(true, "Download complete"); } catch (GitAPIException | JGitInternalException e) { gitCallback.onProgressComplete(false, e.getMessage()); } } });
崩溃报错信息
java.lang.NoSuchMethodError: No virtual method transferTo(Ljava/io/OutputStream;)J in class Ljava/io/InputStream; or its super classes (declaration of 'java.io.InputStream' appears in /apex/com.android.runtime/javalib/core-oj.jar) at org.eclipse.jgit.dircache.DirCacheCheckout.getContent(DirCacheCheckout.java:1684) at org.eclipse.jgit.dircache.DirCacheCheckout.getContent(DirCacheCheckout.java:1609) at org.eclipse.jgit.dircache.DirCacheCheckout.checkoutEntry(DirCacheCheckout.java:1535) at org.eclipse.jgit.dircache.DirCacheCheckout.doCheckout(DirCacheCheckout.java:569) at org.eclipse.jgit.dircache.DirCacheCheckout.checkout(DirCacheCheckout.java:471) at org.eclipse.jgit.api.CloneCommand.checkout(CloneCommand.java:399) at org.eclipse.jgit.api.CloneCommand.call(CloneCommand.java:220) at android.code.editor.utils.GitCloneHandler$1.run(GitCloneHandler.java:138) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641) at java.lang.Thread.run(Thread.java:919)
当前Gradle配置
compileOptions { sourceCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_17 } .... implementation 'org.eclipse.jgit:org.eclipse.jgit:6.5.0.202303070854-r'
修复方案
报错核心原因是:InputStream.transferTo()是Java 9引入的方法,而运行的Android系统版本(API级别低于33)的核心库未实现该方法,JGit 6.5.0版本依赖了这个Java 9+ API导致崩溃。以下是几种可行修复方式:
1. 降级JGit版本
选择兼容Java 8的JGit版本,比如5.13.1.202206130906-r,该版本不依赖Java 9+ API,适配Android低版本:
implementation 'org.eclipse.jgit:org.eclipse.jgit:5.13.1.202206130906-r'
2. 调整Java编译版本(配合降级)
如果降级JGit到Java 8兼容版本,建议同步调整编译版本,避免潜在兼容问题:
compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 }
3. 升级Android API级别(若业务允许)
如果应用可以将targetSdkVersion升级到33或更高,Android系统核心库已支持InputStream.transferTo(),可保持JGit版本不变,只需修改build.gradle中的API级别配置。
4. 使用JGit Android专用适配包
替换原有JGit依赖为Android专用包,该包会替换依赖Java 9+的实现,适配Android环境:
implementation 'org.eclipse.jgit:org.eclipse.jgit.android:6.5.0.202303070854-r'
内容的提问来源于stack exchange,提问作者Tech Info
相关产品推荐
相关产品推荐

