我们正在将应用程序从 JavaEE 7(JDK 1.8、TomEE-7.1.X)更新到 JakartaEE 9.1(JDK 11、TomEE-9.1.X)。
当我们在 TomEE 9.1.0 中使用 cxf-3.5 时遇到问题,我们尝试更新到更新版本的 TomEE (9.1.1/9.1.2),因为从 9.1.1 开始使用 cxf-4.0.3这为我们解决了一些问题。
使用 9.1.1+ 版本,我们无法再部署 Web 应用程序,因为一个特定的 @inject 会导致 UnsatisfiedResolutionException。如果我使用它删除 3 个 bean 上的注入,一切都会正常。 OpenWebBeans 在所有 3 个提到的 TomEE 9.1.X 版本的同一版本中用作 CDI 实现。
查看代码并检查 CDI 文档,我看不出发生这种情况的任何原因。如果我错过了什么或者您知道如何解决这个问题,请告诉我。
背景: @ApplicationScoped bean 用于与我们的 IAM 服务器作为单点联系进行所有通信。
控制台中的消息
INFORMATION: Deployment of web application directory [C:\dev\srv\apache-tomee-plus-9.1.2\SheepWeb-local\webapps\manager] has finished in [2.120] ms
Feb. 01, 2024 2:30:09 NACHM. org.apache.openejb.cdi.OpenEJBLifecycle startApplication
SCHWERWIEGEND: CDI Beans module deployment failed
org.apache.webbeans.exception.WebBeansDeploymentException: jakarta.enterprise.inject.UnsatisfiedResolutionException: Api type [ch.qual.base.web.auth.oic.OpenIDConnectService] is not found with the qualifiers
Qualifiers: [@jakarta.enterprise.inject.Default()]
for injection into Field Injection Point, field name : openIDConnectService, Bean Owner : [Authentication, WebBeansType:MANAGED, Name:Auth_m, API Types:[java.lang.Object,ch.qual.base.web.auth.beans.Authentication,java.io.Serializable], Qualifiers:[jakarta.enterprise.inject.Default,jakarta.enterprise.inject.Any,jakarta.inject.Named]]
界面
package ch.qual.base.web.auth.oic;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jws;
import java.net.URL;
import java.util.Locale;
public interface OpenIDConnectService {
boolean iamEnabled();
String createAuthenticationURL( Integer clientIndex, String redirectURL, Locale userLocale);
AuthenticationInfo registerUser( Integer clientIndex, AuthenticationInfo authenticationInfo, String accessCode);
//more methods present
}
实施
package ch.qual.base.web.auth.oic;
imports...
@ApplicationScoped
public class QOpenIDConnectServiceImpl implements OpenIDConnectService, Serializable {
private static final long serialVersionUID = -3637502198182884565L;
private static final Logger log = LoggerFactory.getLogger(QOpenIDConnectServiceImpl.class);
//a lot of other private static final Strings removed
private static final String URLPATH_AUTHSERVER_REALM_BASE = "auth/realms/";
private static final String URLPATH_AUTHSERVER_ADMIN_BASE = "auth/admin/";
@Inject
private SecurityModuleConfiguration securityModuleConfiguration;
@Inject
private ClientConfig clientConfig;
private boolean iamInitialized = false;
private String serverURL;
private HashMap<Integer, AuthenticationRealmConfiguration> realmStore;
// ***** init and destruct *****
@PostConstruct
public void init() {
//load information from IAM server
}
...
}
beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="https://jakarta.ee/xml/ns/jakartaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/beans_3_0.xsd"
bean-discovery-mode="all" version="3.0">
</beans>
感谢您的帮助,亲切的问候。
我可以通过大量调试结合尝试和错误方法来解决这个问题。该项目现在在 Tomee 9.1.2 上运行没有问题,但我不明白我遇到的问题。让我告诉你解决方案。
我们的应用程序无法启动,因为启动时需要实现OpenIDConnectService。创建一个没有任何逻辑的新的简单实现(由 CDI 发现)后,我删除了一个又一个代码以找到问题的根源。是CXF。
解决方案:
在 QOpenIDConnectServiceImpl 中,我删除了来自 CXF(WebClient、IOUtils、cxf.jaxrs.json.*)的所有导入,并将它们替换为 httpcomponents.client5 和 jakarta.json.*,并且我更改了代码以使用新的库。这解决了我的问题。
但我仍然不明白为什么 CDI 能够使用 cxf-shade 9.1.0 (cxf-3.5) 找到 QOpenIDConnectServiceImpl,而不是使用 cxf-4.0.3(不再有阴影)。
亲切的问候