只要我的EJB在使用它的应用程序的战争中部署,一切正常,我只需@Inject它,没有xml,没有本地或远程接口。 webapp是使用vaadin-cdi的Vaadin 7.5.6应用程序。
当将ejb作为单独的jar部署时,调用它的web-app将失败并显示“Forbidden”。我用
注释了它@SecurityDomain("other")
@RolesAllowed({ "guest" })
然而,仍然是“禁止的”。 webapp中也可能需要一些配置。到目前为止我发现的所有例子都提到了jndi-lookup,ejb-jar.xml,web.xml,jboss-ejb.xml,ejb接口和诸如此类的东西。是否可以单独部署和访问ejb,同时避免所有这些额外的配置?我想分解我的应用程序,以便每次我更改gui时都不需要部署所有内容,但如果我必须恢复到“旧学校”ejb配置,我不确定是否有一点
使用Wildfly 9.0.2,Java 8和Maven。
编辑:
EJB:Hello World EJB存在于maven子项目中,它有jar包装。它没有xml配置,也没有本地或远程接口。没有使用maven-ejb-plugin。实现如下:
import javax.ejb.Stateless;
@Stateless
public class ReceptionService {
public String welcome() {
return "Hello, Developer! No XML, No Configuration, and it works!";
}
}
还有一些真实的会话bean在方法中使用JPA(如下所示),因此可能会出现一些持久性和事务问题,但直到简单的hello-world案例工作中。 hello-world-webapp不包含任何这些EJB,只包含简单的hello-world-EJB。
@Stateless
@TransactionManagement(value = TransactionManagementType.CONTAINER)
public class DealerSession {
private Logger logger = LoggerFactory.getLogger(DealerSession.class);
@PersistenceContext(unitName = "MyUnit")
protected EntityManager em;
@TransactionAttribute(REQUIRED)
public Long create(DealerUpdate update) {
notNull(update, "update"); // and so on ....
持久性单元在EJB项目中定义,它连接到Wildfly中的数据源。在真实世界中,Bean事务在失败时回滚。
WAR:这是一个Vaadin 7 webapp。它看起来像这样:
@CDIUI("")
@Theme("valo")
public class WelcomePage extends UI {
@Inject
ReceptionService service;
@Override
protected void init(VaadinRequest request) {
setSizeFull();
String message = service.welcome();
Label label = new Label("this is the message: " + message);
setContent(new HorizontalLayout(label));
} ....
EJB jar文件在依赖项中引用。因此它被包含在内,并且所有内容都像EJB bean在战争中只是一个.class文件一样。这非常方便,因为几乎不涉及任何配置。但随着真实世界项目的增长,我想分割部署,这样每次gui更新时我都不必将所有EJB部署为战争的一部分,因为它会减慢开发周期
war项目取决于vaadin-cdi 1.0.3和vaadin-bom 7.5.6,当然还有带有EJB的jar(有jar而不是ejb包装)。还使用了vaadin-maven-plugin,maven-resource-plugin和maven-war-plugin。
两个项目也使用wildly-plugin 1.0.2.Final。并依赖于java javaee-api 7.0。
现在,我迄今为止的天真尝试是将EJB jar的包装更改为“ejb”,添加maven-ejb-plugin,指定战争项目的pom文件中的依赖项中提供的范围,并部署战争和罐子分开。到目前为止,没有任何错误消息或警告,两者都已部署。但访问ejb是“禁止”,gui中有一条错误消息说,奇怪的是没有在wildfly控制台中。我试图将@SecurityDomain和@RolesAllowed注释添加到EJB(参见上文),但也必须在webapp上配置内容。如果是这样CDI只会将EJB作为pojo注入,或者我必须添加本地和/或远程接口,执行JNDI查找,向xml配置文件添加大量内容等等,我可以管理它,因为有一些示例应用程序和文档,但是一切都变得复杂得多,我想避免这种情况。
答案 0 :(得分:1)
首先,您的EJB不会被注入,即使它们与您的WAR一起部署也是如此。这是因为您没有声明接口。在这种情况下,您至少必须使用@LocalBean注释它们,它声明了bean的no-interface-view。
当您将EJB外包到jar中时,CDI无法注入由EJB(代理)生成的bean伪装,而是注入pojo实例。为避免这种情况,您可以为WAR中的每个EJB创建一个生产者字段或方法。用CDI注入bean然后调用生产者。这个生产者必须进行特定的JNDI查找(java:global / ...)来获取EJB bean实例。
然后,在部署到wildfly时,您必须从WAR向JAR添加依赖项,因为两个部署都有单独的类加载器,并且无法相互看到。依赖项连接两个类加载器,以便WAR中的一个能够加载JAR的类。
在这种情况下,您只需要为WAR而不是JAR激活CDI,因为EJB实例是通过显式JNDI查找来检索的。
答案 1 :(得分:1)
如果你绝对需要使用cdi注射,我已经批准我的问题的答案可能是正确的。尽管如此,我从来没有这样做过。
相反,我决定尝试使用@EJB注释,而不是@Inject。当我部署我的ejb(在我的web-app中的一个单独的jar中,它存在于war文件中)时,Wildfly会记录jndi-names并在控制台中报告。其中一个名称是" java:global / template-service-1.0.0-SNAPSHOT / ReceptionService"。注意"全球"范围。
@EJB注释有一个名为mappedName的参数。像这样注入和使用ejb就可以了:
nm1 <- paste0('Loc', 1:3)
lst <- vector('list' , length(nm1))
for(i in seq_along(nm1)){
temp <- table(DT$Group, DT[[i]], useNA= 'ifany')
lst[[i]] <- list(temp, prop.table(temp, 1))
}
lst[[1]]
#[[1]]
#
# G T <NA>
# G1 3 0 0
# G2 1 2 1
# G3 0 2 1
#[[2]]
#
# G T <NA>
# G1 1.0000000 0.0000000 0.0000000
# G2 0.2500000 0.5000000 0.2500000
# G3 0.0000000 0.6666667 0.3333333
还需要注册模块依赖项,以便客户端类加载器可以看到该服务。我是使用war-plugin在webapp pom.xml中完成的:
@EJB(mappedName = "java:global/template-service-1.0.0-SNAPSHOT/ReceptionService")
ReceptionService service;
@Override
protected void init(VaadinRequest request) {
UI.getCurrent().setLocale(new Locale("nb","no"));
setSizeFull();
String message = service.welcome();
Label label = new Label("message: " + message);
setContent(new HorizontalLayout(label));
}
通过这种方式,我可以单独部署我的ejbs,然后我可以将我的war文件部署为&#34; thin&#34;部署。我的真实项目有一堆ejbs和jpa-stuff,这会减慢开发 - 编译 - 部署周期,当我处理肠道时,这个设置我可以节省相当一些时间摆弄gui。
EJB看起来像这样,没有ejb-jar.xml。
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<archive>
<manifestEntries>
<Dependencies>deployment.template-service-1.0.0-SNAPSHOT.jar</Dependencies>
</manifestEntries>
</archive>
</configuration>
</plugin>
如果您手动将模块依赖项添加到清单中,并且不使用war-plugin,则消息中的no-xml-part将为true:o)
编辑:要在ejb jar中包含依赖项,可以使用one-jar插件或类似插件。