Liferay 7.4 Service-Builder模块导入okhttp3遇错求助
在Liferay 7.4的Service-Builder模块中导入okhttp3库时,会遇到两类典型问题:
- 使用
compileInclude 'com.squareup.okhttp3:okhttp:4.10.0'构建时,触发报错:
error : Classes found in the wrong directory: {META-INF/versions/9/module-info.class=module-info}
- 改用
compile 'com.squareup.okhttp3:okhttp:4.10.0'后构建通过,但部署时出现OSGi依赖解析异常:
com.liferay.portal.kernel.log.LogSanitizerException: org.osgi.framework.BundleException: Could not resolve module: com.toptoken.core.service [1610]_ Unresolved requirement: Import-Package: okhttp3_ [Sanitized]
at org.eclipse.osgi.container.Module.start(Module.java:444) ~[org.eclipse.osgi.jar:?]
at org.eclipse.osgi.internal.framework.EquinoxBundle.start(EquinoxBundle.java:428) ~[org.eclipse.osgi.jar:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher._startBundle(DirectoryWatcher.java:1156) [bundleFile:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher._startBundles(DirectoryWatcher.java:1189) [bundleFile:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher._startAllBundles(DirectoryWatcher.java:1130) [bundleFile:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher._process(DirectoryWatcher.java:1041) [bundleFile:?]
at com.liferay.portal.file.install.internal.DirectoryWatcher.run(DirectoryWatcher.java:247) [bundleFile:?]
以下是两种可行的解决方法:
方案一:嵌入okhttp3依赖(推荐)
这种方式将okhttp3的jar包直接嵌入到当前模块中,避免OSGi依赖解析问题:
- 修改
build.gradle中的依赖配置:
compileOnly 'com.squareup.okhttp3:okhttp:4.10.0'
- 在模块的
bnd.bnd文件中添加嵌入规则,同时排除导致构建报错的模块化文件:
Embed-Dependency: okhttp;scope=compile;inline=true Embed-Transitive: true # 排除冲突的module-info文件 Include-Resource: @okhttp-4.10.0.jar,META-INF/versions/9/module-info.class=
Embed-Transitive会自动嵌入okhttp3的间接依赖(如okio),确保所有相关类都能被模块访问。
方案二:部署独立的okhttp3 OSGi Bundle
如果希望多个模块复用okhttp3依赖,可以将其打包为OSGi Bundle单独部署:
- 下载okhttp3 4.10.0的jar包,使用bnd工具为其生成OSGi元数据,或直接使用已适配OSGi的版本。
- 将生成的okhttp3 Bundle放入Liferay的
osgi/modules目录下完成部署。 - 回到Service-Builder模块,保留
build.gradle中的compile 'com.squareup.okhttp3:okhttp:4.10.0'配置,同时在bnd.bnd中正确声明导入:
Import-Package: okhttp3;version="[4.10,5)"
此时模块启动时会依赖已部署的okhttp3 Bundle,解决依赖解析失败问题。
额外注意事项
- Java 11环境下,okhttp3 4.x版本的
META-INF/versions/9/目录包含Java 9+的模块化信息,compileInclude会因目录结构校验报错,因此需要通过嵌入排除或独立Bundle的方式规避。 - 使用嵌入方案时,需确保
Embed-Dependency和Embed-Transitive配置正确,避免遗漏依赖类。
内容的提问来源于stack exchange,提问作者Zirui Wang

