Glassfish4 + EJB + Spring,部署失败
Glassfish4 + EJB + Spring, deploy fails
我正在将应用程序从 Glassfish 3.1.2.2 上的 Java7 升级到 Glassfish 4.1 上的 Java8。该应用程序被打包为一个 ear 文件,其中包含一个带有远程 EJB 和 Spring beans 的 jar 文件,以及一个带有几个 servlet 和一些 web 服务的 war 文件。
与 Glassfish 3.x 相比,实际应用程序只做了一些小改动,总的改动是:
- 使用 Java8 而不是 Java7 构建。
- 部署在 Glassfish 4.1 而不是 3.1.2.2
- 较新版本的 Hibernate
- 较新版本的 ActiveMQ(客户端)
我看不出以前的 ear 文件和新的 ear 文件有什么区别(除了上面提到的 lib-jars),但是当我尝试部署时,我的所有 EJB 都会出现这样的错误:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type SomethingLogic with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private com.my.application.server.service.SomethingServiceSession.somethingLogic
SomethingService 是 EJB,SomethingLogic 是 Spring bean。
我的 EJB 是这样定义的:
@Stateless
@RolesAllowed("secure")
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class SomethingServiceSession implements SomethingService {
@Inject
private SomethingLogic somethingLogic; //Spring bean
SomethingLogic 是一个接口。
我有一个 beanRefContext.xml 包含:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg value="classpath*:applicationContext-glassfish.xml"/>
</bean>
</beans>
EJB 服务在 glassfish-ejb-jar.xml 中定义,如下所示:
<ejb>
<ejb-name>SomethingServiceSession</ejb-name>
<ior-security-config>
<as-context>
<auth-method>USERNAME_PASSWORD</auth-method>
<realm>AD</realm>
<required>true</required>
</as-context>
</ior-security-config>
</ejb>
我尝试将具有以下内容的 beans.xml 添加到我的 EJB 项目的 resources\META-INF 文件夹中:
<?xml version="1.0"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd" />
运气不好。
我也尝试过将 @LocalBean 添加到我所有的 EJB,但也没有成功。
此外,我尝试使用以下命令一起禁用 CDI:
asadmin set configs.config.server-config.cdi-service.enable-implicit-cdi=false
这实际上允许部署我的 EJB 服务,但我怀疑它有一个不太好的副作用,即我的 web 服务没有被发现,所以我希望能够在启用 CDI 的情况下进行部署以控制它出。
更新:
我已经尝试在所有非Spring处理的类(EJB、web 服务和servlet)中将@Inject 更改为@Autowired。现在,对于实际的 Spring bean,我得到了同样的错误。似乎 Glassfish 在遇到 @Inject 时会尝试寻找 EJB bean,无论它们出现在哪里。
通过将 bean-discovery-mode="none"
添加到我的各种 beans.xml 文件中解决了我的问题。
<?xml version="1.0"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_2.xsd"
bean-discovery-mode="none" />
我正在将应用程序从 Glassfish 3.1.2.2 上的 Java7 升级到 Glassfish 4.1 上的 Java8。该应用程序被打包为一个 ear 文件,其中包含一个带有远程 EJB 和 Spring beans 的 jar 文件,以及一个带有几个 servlet 和一些 web 服务的 war 文件。
与 Glassfish 3.x 相比,实际应用程序只做了一些小改动,总的改动是:
- 使用 Java8 而不是 Java7 构建。
- 部署在 Glassfish 4.1 而不是 3.1.2.2
- 较新版本的 Hibernate
- 较新版本的 ActiveMQ(客户端)
我看不出以前的 ear 文件和新的 ear 文件有什么区别(除了上面提到的 lib-jars),但是当我尝试部署时,我的所有 EJB 都会出现这样的错误:
org.jboss.weld.exceptions.DeploymentException: WELD-001408: Unsatisfied dependencies for type SomethingLogic with qualifiers @Default
at injection point [BackedAnnotatedField] @Inject private com.my.application.server.service.SomethingServiceSession.somethingLogic
SomethingService 是 EJB,SomethingLogic 是 Spring bean。
我的 EJB 是这样定义的:
@Stateless
@RolesAllowed("secure")
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class SomethingServiceSession implements SomethingService {
@Inject
private SomethingLogic somethingLogic; //Spring bean
SomethingLogic 是一个接口。
我有一个 beanRefContext.xml 包含:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="beanFactory" class="org.springframework.context.support.ClassPathXmlApplicationContext">
<constructor-arg value="classpath*:applicationContext-glassfish.xml"/>
</bean>
</beans>
EJB 服务在 glassfish-ejb-jar.xml 中定义,如下所示:
<ejb>
<ejb-name>SomethingServiceSession</ejb-name>
<ior-security-config>
<as-context>
<auth-method>USERNAME_PASSWORD</auth-method>
<realm>AD</realm>
<required>true</required>
</as-context>
</ior-security-config>
</ejb>
我尝试将具有以下内容的 beans.xml 添加到我的 EJB 项目的 resources\META-INF 文件夹中:
<?xml version="1.0"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_0.xsd" />
运气不好。
我也尝试过将 @LocalBean 添加到我所有的 EJB,但也没有成功。
此外,我尝试使用以下命令一起禁用 CDI:
asadmin set configs.config.server-config.cdi-service.enable-implicit-cdi=false
这实际上允许部署我的 EJB 服务,但我怀疑它有一个不太好的副作用,即我的 web 服务没有被发现,所以我希望能够在启用 CDI 的情况下进行部署以控制它出。
更新:
我已经尝试在所有非Spring处理的类(EJB、web 服务和servlet)中将@Inject 更改为@Autowired。现在,对于实际的 Spring bean,我得到了同样的错误。似乎 Glassfish 在遇到 @Inject 时会尝试寻找 EJB bean,无论它们出现在哪里。
通过将 bean-discovery-mode="none"
添加到我的各种 beans.xml 文件中解决了我的问题。
<?xml version="1.0"?>
<beans xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://jboss.org/schema/cdi/beans_1_2.xsd"
bean-discovery-mode="none" />