CircleCI中Android单元测试失败,疑因JVM版本不匹配求助
我之前也碰到过完全一样的坑!咱们一步步来理清楚:
问题根源
你猜的没错,就是JVM版本的锅:Java 11及以上版本把javax.xml.bind这个模块从核心库中移除了,但Android DataBinding的注解处理器android.databinding.annotationprocessor.ProcessDataBinding还依赖这个模块,所以用JDK11跑就会报ClassNotFoundException: javax/xml/bind/JAXBException。
虽然CircleCI文档说Android镜像基于openjdk8,但实际环境里可能默认加载了更高版本的JDK(比如系统PATH里优先级更高),或者Gradle自动选用了高版本JDK,导致和本地的1.8.0_222不匹配。
解决方案
有两种靠谱的办法,你可以选一个适合自己的:
方法1:强制CircleCI使用JDK 8
在你的.circleci/config.yml里,明确指定JDK版本或者设置JAVA_HOME指向JDK8的路径:
方式A:用CircleCI的setup-java命令(推荐)
直接在job步骤里添加setup-java,指定版本8:
jobs: test: docker: - image: circleci/android:api-33 # 换成你项目使用的Android镜像版本 steps: - checkout # 强制切换到OpenJDK 8 - setup-java: version: '8' package: openjdk - run: ./gradlew testDevelopDebugUnitTest
方式B:设置JAVA_HOME环境变量
如果setup-java不管用,直接指定JDK8的默认路径(CircleCI Android镜像里JDK8的路径通常是/usr/lib/jvm/java-8-openjdk-amd64):
jobs: test: docker: - image: circleci/android:api-33 environment: JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64 PATH: $JAVA_HOME/bin:$PATH steps: - checkout - run: ./gradlew testDevelopDebugUnitTest
方法2:给DataBinding添加JAXB依赖(兼容JDK8和11)
如果不想折腾环境,也可以在项目的app/build.gradle里给注解处理器手动添加JAXB的依赖,这样不管用JDK8还是11都能正常跑:
dependencies { // 针对JDK9+补充JAXB依赖,本地JDK8会自动忽略冗余依赖 annotationProcessor 'javax.xml.bind:jaxb-api:2.3.1' annotationProcessor 'com.sun.xml.bind:jaxb-core:2.3.0.1' annotationProcessor 'com.sun.xml.bind:jaxb-impl:2.3.2' }
另外别忘了确保你的编译配置指定JVM目标为1.8,和本地保持一致:
android { compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } }
验证
配置完之后,你可以在CircleCI的步骤里加一个run: java -version命令,确认输出的JVM版本是1.8.x,这样就能和本地环境完全对齐了。
内容的提问来源于stack exchange,提问作者NamNH

