3

我有一个场景,我需要在应用程序启动时加载一个 bean (ReportManager),以便它可以安排执行报告(由 DataStore bean 从数据库轮询)。

谷歌搜索我发现了@Singleton、@Startup 和@DependsOn 注释,我使用过这样的注释:

@Singleton
@Startup
@DependsOn("DataStore")
public class ReportManager {
    @EJB
    DataStore dataStore;

    @PostConstruct
    public void scheduleReports() {
       logger.log("INITIALIZED");
       List<Report> reports = dataStore.getReports();
       ....
    }
}

@Singleton
@RolesAllowed("user") //I had security checks implemented like that beforehand
public class DataStore {
    @PostConstruct
    public void initialize() {
        logger.log("INITIALIZED");
    }

    public List<Report> getReports() {
        ...
    }
}

问题是我在部署期间遇到了非常奇怪的异常:

<2012-09-27 14:04:15 CEST> <Warning> <Deployer> <BEA-149004> <Failures were detected while initiating deploy task for application "app".>
<2012-09-27 14:04:15 CEST> <Warning> <Deployer> <BEA-149078> <Stack trace for message 149004
weblogic.application.ModuleException: Exception starting module: EJBModule(app-ejb-1.0-SNAPSHOT.jar)

Unable to deploy EJB: ReportManager from app-ejb-1.0-SNAPSHOT.jar:

Singleton ReportManager(Application: app, EJBComponent: app-ejb-1.0-SNAPSHOT.jar) failed to initialize.

   at weblogic.ejb.container.deployer.EJBModule.start(EJBModule.java:592)
 .....

Caused By: weblogic.ejb.container.InternalException: Transaction marked rollback or not expected transaction status: 1
   at weblogic.ejb.container.manager.SingletonSessionManager.postCallback(SingletonSessionManager.java:464)

不是真正有用的异常消息。特别是我也没有得到任何“初始化”日志条目。当我注释掉 dataStore.getReports() 调用时,一切正常,bean 以正确的顺序构造(产生了“INITIALIZED”消息)。包括 dataStore 方法调用导致了上述错误,并且以某种方式抑制了所有日志输出。

我正在使用 Weblogic 12c。

4

2 回答 2

4

最后,我弄清楚了导致错误的原因。这是@RolesAllowed由于空的安全上下文而阻塞方法调用的声明,@PostConstruct在 bean 中执行时未在方法中设置@Startup(来自EJB 3.1 规范,第 4.3.4 章:PostConstruct 生命周期回调拦截器方法在未指定的安全上下文中执行。) .

使它工作所需的只是添加@PermitAll到调用的方法中:

@PermitAll
public List<Report> getReports() {
   ...
}

这个错误太令人误解了,我决定把这个案例放在这里,因为我无法用谷歌搜索答案。

于 2012-09-27T12:38:34.853 回答
1

就我而言,我使用的是 SpringLoader.java 类,它是一个加载 Spring 配置的 @Singleton。Spring 配置了 Quartz 调度程序,该调度程序正在尝试访问其 DB 表(作为某些事务的一部分)。

所以在我的例子中,它有助于在这个 SpringLoader 类中添加以下行:@TransactionManagement(TransactionManagementType.BEAN)

之后,会显示一些更有意义的错误消息:ORA-00942:表或视图不存在。

顺便说一句:它也值得添加这一行:@ConcurrencyManagement(ConcurrencyManagementType.BEAN)

于 2013-08-11T13:32:48.083 回答