scip-java索引Java17项目报IllegalAccessError的JVM参数配置问题
问题背景
- 参照scip-java入门文档指引,在项目根目录执行命令,尝试为spring-framework仓库构建索引以测试Sourcegraph精准代码智能功能,执行命令如下:
docker run -v $(pwd):/home/gradle sourcegraph/scip-java:latest scip-java index --build-tool=gradle - 命令运行后抛出模块访问错误,错误信息如下:
Exception in thread "main" java.lang.IllegalAccessError: class com.sourcegraph.semanticdb_javac.SemanticdbPlugin (in unnamed module @0x1794d431) cannot access class com.sun.tools.javac.api.BasicJavacTask (in module jdk.compiler) because module jdk.compiler does not export com.sun.tools.javac.api to unnamed module @0x1794d431 - 根据文档说明,Java 17及更新版本构建索引需要配置以下JVM参数:
--add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED --add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED - 先后尝试三种参数传入方式均未成功:
- 通过
JAVA_OPTS环境变量传入带--add-exports前缀的完整参数,运行时提示Unrecognized option: --add-exports,JVM启动失败 - 通过
JAVA_OPTS传入去掉--add-exports前缀的参数值,运行时提示找不到对应主类 - 通过
JDK_JAVA_OPTIONS环境变量传入参数,日志显示参数已被拾取,但仍抛出完全相同的模块访问错误
- 通过
- 无Java开发基础,需要正确配置上述JVM参数、顺利完成项目索引的可操作方案。
解决方案
之前传参失败的核心原因是参数加错了位置。scip-java通过注入javac编译插件采集代码语义信息生成索引,真正需要这些--add-exports参数的是Gradle构建流程中启动的Java编译进程,而非外层的scip-java启动进程。之前的传参方式都只作用于外层scip-java进程,根本没有触达实际运行插件的编译进程,自然无法解决权限报错。
按以下步骤操作即可正常完成索引构建:
- 进入spring-framework仓库根目录,找到或新建
gradle.properties文件,在文件中添加如下配置,直接将JVM参数传递给Gradle编译进程:org.gradle.jvmargs=-Xmx4g \ --add-exports jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \ --add-exports jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMEDspring-framework项目构建对内存要求较高,配置中预留了4G堆内存避免构建过程中内存溢出,机器内存充足的情况下可以适当调大该值。
- 不需要在docker启动命令中额外添加
JAVA_OPTS、JDK_JAVA_OPTIONS之类的环境变量,直接执行原索引构建命令即可:docker run -v $(pwd):/home/gradle sourcegraph/scip-java:latest scip-java index --build-tool=gradle - 如果执行后仍报错,先运行清理命令删除之前构建残留的缓存文件,再重新执行索引构建命令:
docker run -v $(pwd):/home/gradle sourcegraph/scip-java:latest scip-java clean
注意事项
- 不要给外层docker命令传入JVM相关环境变量,这类参数只会作用于scip-java本身的启动进程,无法传递到内部Gradle启动的编译守护进程,这也是之前出现“参数被拾取但仍报错”现象的根本原因。
- 索引构建耗时受机器性能影响,通常需要10-30分钟,期间不要中断进程。
- 不需要修改项目其他构建配置,scip-java官方镜像内置的Gradle版本可以兼容spring-framework的构建逻辑。
内容的提问来源于stack exchange,提问作者aka010120
相关产品推荐
相关产品推荐

