标签: ejb-3.1

Java EE应用程序启动失败

如果在应用程序初始化期间发生异常,是否有任何方法可以阻止Java EE应用程序启动?我基本上正在寻找一种方法,使应用程序在应用程序初始化期间从一个或一个bean 抛出一个未处理的异常后进入一个" j2ee.state.failed"状态(按照JSR-77).ServletContextListenerSingleton Startup

EJB规范似乎表明,如果在初始化过程中发生了异常Singleton的bean,应用程序将继续启动和运行没有错误; 但是,只有bean本身可能处于无法调用的状态.不幸的是,这不是我正在寻找的行为.

4.8.4单例错误处理

在Singleton初始化期间发生的错误被认为是致命的,必须导致丢弃Singleton实例.可能的初始化错误包括注入失败,从PostConstruct方法抛出的系统异常,或PostConstruct方法容器管理的事务成功提交失败.如果单例无法初始化,则对Singleton的尝试调用会导致第3.4.3节和第3.4.4节中定义的异常.

Servlet规范是它的要求更加模糊了一下,貌似不是需要一个容器中,任何特定的行为方式,而只是提示(通过使用术语"可能"),该网络模块继续启动,但任何请求应导致内部服务器错误.再说一次,遗憾的是这不是我正在寻找的行为.如果Web应用程序无法处理任何请求,为什么应该继续启动并且似乎正在运行?

11.6听众例外

容器可以使用HTTP状态代码500响应对Web应用程序的所有后续请求以指示应用程序错误.

根据我的经验,我看到应用程序服务器以不同的方式处理此要求.实际上,某些容器会阻止应用程序在这些情况下启动,而其他容器只会抑制异常并响应具有500个错误的请求,如规范中所述.

如果在初始化期间发生异常,我是否会忽略规范中阻止应用程序启动的任何部分?

servlets startup java-ee ejb-3.1

14
推荐指数
1
解决办法
1933
查看次数

设置/配置EJB Timer Service的DataSource

我正在尝试在我的应用程序中使用EJB 3.1中的计时器服务.

@Stateless
@LocalBean
public class StatelessTimerSessionBean {

    @Schedule(minute = "*", second = "0", dayOfMonth = "*", month = "*", year = "*", hour = "9-17", dayOfWeek = "Mon-Fri")
    public void myTimer() {
        System.out.println("Timer event: " + new Date());
    }
}
Run Code Online (Sandbox Code Playgroud)

"..将EJB Timer Service的Timer DataSource设置设置为有效的JDBC资源.."

来自EJB Timer Service

我无法弄清楚如何正确配置Timer Datasource?

部署时出现的错误是:

SEVERE: Exception while invoking class org.glassfish.ejb.startup.EjbApplication start method
java.lang.RuntimeException: EJB Timer Service is not available
Run Code Online (Sandbox Code Playgroud)

跑步:glassfish-3.1.2.2

java glassfish java-ee ejb-3.1

14
推荐指数
1
解决办法
1万
查看次数

EJB 3.1 @EJB注入POJO

今天下午成为一个完整的大菱鲆,似乎无法在任何地方找到答案.

使用新的EJB 3.1规范是否可以将EJB注入pojo?我知道在EJB 3.0中,@ EJB注释可用于注入EJB,但这不适用于简单的pojos.

如果不是,我必须在JNDI中查看bean,因为我知道你不能简单地使用new关键字.

提前致谢.

卡尔

java ejb java-ee-6 ejb-3.1

13
推荐指数
3
解决办法
2万
查看次数

使用EJBContext getContextData - 这样安全吗?

我打算用来EJBContext将一些属性从应用程序层(特别是消息驱动的bean)传递给持久性生命周期回调,它不能直接注入或传递参数(EclipseLink中的会话监听器,实体生命周期回调等),并且该回调正在获得EJBContext通过JNDI.

这看起来有效,但有没有任何隐藏的陷阱,比如线程安全或对象寿命,我错过了?(假设传递的属性值是不可变的,如String或Long.)

示例bean代码

@MessageDriven
public class MDB implements MessageListener {
   private @Resource MessageDrivenContext context;

   public void onMessage(Message m) { 
      context.getContextData().put("property", "value");
   }
}
Run Code Online (Sandbox Code Playgroud)

然后是使用EJBContext的回调

public void callback() { 
   InitialContext ic = new InitialContext();
   EJBContext context = (EJBContext) ic.lookup("java:comp/EJBContext");
   String value = (String) context.getContextData().get("property");
} 
Run Code Online (Sandbox Code Playgroud)

我想知道的是,我能确定contextData地图内容只对当前的调用/线程可见吗?换句话说,如果两个线程同时运行该callback方法,并且都EJBContext从JNDI 查找,它们实际上是获得不同的contextData地图内容?

而且,这实际上是如何工作的 - EJBContext从JNDI查找返回的是ThreadLocal最终围绕类似结构的包装器对象?

java java-ee java-ee-6 ejb-3.1

12
推荐指数
2
解决办法
1万
查看次数

使用Maven 2和Glassfish 3对EJB进行单元测试

我一直在尝试设置我的应用程序,以便我可以整天测试它的EJB,但我似乎无法超越看似简单的问题.

我在NetBeans 6.9中设置了标准的Maven Web应用程序.我已经自动为其中一个EJB生成了单元测试,但每当我去运行它时,我都会收到错误消息:

Testcase: initializationError(com.example.ExampleTest): Caused an ERROR
Absent Code attribute in method that is not native or abstract in class file javax/ejb/embeddable/EJBContainer
java.lang.ClassFormatError: Absent Code attribute in method that is not native or abstract in class file javax/ejb/embeddable/EJBContainer
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClassCond(ClassLoader.java:632)
        at java.lang.ClassLoader.defineClass(ClassLoader.java:616)
        at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
Run Code Online (Sandbox Code Playgroud)

我已经研究了这个,我很确定问题是我的pom当前指向一个只包含API的jar

<dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-web-api</artifactId>
            <version>6.0</version>
            <scope>provided</scope>
        </dependency>
Run Code Online (Sandbox Code Playgroud)

不是和可用于运行测试的实现.我很确定在尝试执行@BeforeClass的方法中测试失败了

container = EJBContainer.createEJBContainer();
Run Code Online (Sandbox Code Playgroud)

标准推荐的解决方案是将glassfish-embedded-all工件添加为具有测试范围的第一个项目依赖项

<dependency>
            <groupId>org.glassfish.extras</groupId>
            <artifactId>glassfish-embedded-all</artifactId>
            <version>3.0.1</version>
            <scope>test</scope>
        </dependency>
Run Code Online (Sandbox Code Playgroud)

我可以在这里找到这个工件的Maven包:http://download.java.net/maven/glassfish/但是Nexus不能将这个目录或任何子目录识别为Maven 2存储库.我想我可以下载jar并手动将其安装到Nexus中,但这似乎打败了安装Nexus的人.

那么,是否有一个Maven存储库,Nexus能够编制索引以便为我提供glassfish-embedded-all工件?我读过的一些帖子提到现在正在使用的正确工件是javax.ejb,但我找不到更多的运气了.

你可能已经猜到我对单元测试是全新的,而且对JEE6来说还是比较新的; 这甚至是单元测试EJB的正确方法吗?

java maven-2 unit-testing glassfish ejb-3.1

11
推荐指数
1
解决办法
7547
查看次数

无需使用部署描述符即可动态添加Java EE安全角色

我正在使用Glassfish 3.1,B06开发Java EE 6应用程序.为了保护我的应用程序,我正在使用JDBCRealm和编程安全性.这可以很好地检查用户名和密码.但是当谈到声明安全角色时,我遇到了一个问题:

要在Java EE 6中使用安全角色,我必须在EJB部署描述符和Glassfish特定的部署描述符中声明这些角色以链接这些角色(如Java EE 6教程中所述)仅我可以使用方法isCallerInRole(String roleRef)在EJB内部检查权限.

这对我的应用程序来说是不可取的,因为我希望能够动态地和以编程方式添加安全角色,而不必编写XML文件(例如,可以在数据库中定义角色名称).

我刚刚通过GF3源代码进行了调试,并在com.sun.ejb.containers.EjbContextImpl中看到了isCallerInRole的实现.容器从EJB描述符中获取角色:

public boolean isCallerInRole(String roleRef) {
  (...)
  EjbDescriptor ejbd = container.getEjbDescriptor();
  RoleReference rr = ejbd.getRoleReferenceByName(roleRef);
  (...)
}
Run Code Online (Sandbox Code Playgroud)

我环顾四周,发现如果我能以某种方式在我的应用程序中获取EJB描述符,我可以添加这样的角色:

EjbDescriptor ejbd = //??? Can i use that descriptor inside my app, or is that "forbidden"?
RoleReference rr = new RoleReference("admin", "Admins are allowed to do everything");
ejbd.addRoleReference(rr);
Run Code Online (Sandbox Code Playgroud)

有人做过这样的事情,还是对此有所了解?是否可以在我的应用程序中使用Ejb部署描述符?还是有更好的方法?

PS或我应该使用MBeans添加角色?在这里找到一个相关的帖子.

ejb glassfish java-ee ejb-3.1 glassfish-3

10
推荐指数
1
解决办法
3531
查看次数

Java EE 6注释继承的神秘面纱

我在几个场景中使用EJB继承,有时在超类中使用注释,就像这个通用实体DAO:

public class JpaDAO<T>{
    protected Class<T> entityClass;

    @PersistenceContext(unitName="CarrierPortalPU")
    protected EntityManager em;
    protected CriteriaBuilder cb;

    @PostConstruct
    private void init() {
        cb = em.getCriteriaBuilder();
    }

    public JpaDAO(Class<T> type) {
        entityClass = type;
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void create(T entity) {
        em.persist(entity);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public T find(Object id) {
        return em.find(entityClass, id);
    }

    @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
    public List<T> findAll(){
        CriteriaQuery<T> cq = cb.createQuery(entityClass);
        Root<T> entity = cq.from(entityClass);
        cq.select(entity);
        return em.createQuery(cq).getResultList();
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void remove(T entity) {
        em.remove(em.merge(entity));
    }

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public T edit(T entity) {
        return …
Run Code Online (Sandbox Code Playgroud)

inheritance annotations java-ee-6 jpa-2.0 ejb-3.1

10
推荐指数
1
解决办法
6905
查看次数

可以使用@Resource在EJB3.0中注入原语吗?

使用Glassfish,我可以设置一个字符串jndi条目:

JNDI name: "com/xyzcompany/echo/EchoServiceBean/viewName"
Factory Class: org.glassfish.resources.custom.factory.PrimitivesAndStringFactory
Properties: value="Testing123"

然后我可以将这个容器配置的字符串注入我的EJB:

    @Resource(lookup = "com/xyzcompany/echo/EchoServiceBean/viewName")
    String viewName;

lookup =似乎在内部执行InitialContext.lookup(...).但是,这使用ejb3.1,但不幸的是我的prod环境只有ejb3.0.

我想我想弄清楚是否有办法使用@Resource(name =)或@Resource(mappedName =)做类似的事情?name =似乎是特定于应用程序的,所以我应该能够以某种方式将相对名称映射到全局JNDI名称,但我无法弄清楚映射的注释.

谢谢!

java glassfish ejb-3.0 java-ee-6 ejb-3.1

10
推荐指数
1
解决办法
9260
查看次数

清理代码,无状态会话bean和私有状态

根据Robert C. Martin的干净代码方法应该有一个小签名.最好的情况是没有参数的方法.相反,建议使用状态变量.这非常有用.但是无状态会话bean呢?

这个名字有点令人困惑,因为SLSB可以拥有州.您只需要进行内务管理,这样就不会使用先前EJB调用中的状态.

回到干净的代码:我也喜欢在SLSB中使用实例变量.这样可以正常工作,如果你足够小心,你就不会遇到状态不一致的问题,因为每次公共方法调用都会覆盖状态.

到现在为止还挺好.但是如果用过的bean回到池中会发生什么?它采取了它的状态.根据状态的大小,这可能是真正的内存泄漏.JBoss对bean非常慷慨,产生了大量的bean,导致一些严重的内存消耗 - 一无所获.

因此,一种方法是在bean方法存在之前清理状态,并将bean返回到池中.但在我看来,这应该是无用的代码.

有没有正确的方法来处理这个问题?在这种情况下,最佳做法是什么?

java coding-style ejb-3.0 java-ee-6 ejb-3.1

10
推荐指数
1
解决办法
1071
查看次数

将EJB注入Eclipselink SessionCustomizer以提供Oracle模式名称

在GlassFish(3.1.2.2b5)上运行的Java EE 6应用程序中,假设您有一个ConfigurationService,它读取一些属性文件并相应地分发属性值:

@Local
public interface ConfigurationService { ... }
Run Code Online (Sandbox Code Playgroud)
@Singleton  
public class ConfigurationServiceImpl implements ConfigurationService { ... }
Run Code Online (Sandbox Code Playgroud)

还有一个Eclipselink SessionCustomizer,因为应用程序中的一个持久性单元(Oracle数据库)的模式名称需要以编程方式设置,即可以从之前提到的属性文件进行配置.的SessionCustomizer是在配置persistence.xml和实施包含对一个参考ConfigurationService:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence"...
    <persistence-unit name="myPU" transaction-type="JTA">
        <property name="eclipselink.session.customizer" value="MySessionCustomizer"/>
        ...
Run Code Online (Sandbox Code Playgroud)
public class MySessionCustomizer implements SessionCustomizer {
    @EJB
    private ConfigurationService configurationService;
    @Override
    public void customize(Session session) {
        session.getLogin().setTableQualifier(configurationService.getSchemaName());
        ...
Run Code Online (Sandbox Code Playgroud)

是否有可能以ConfigurationService这种方式注入,以便在SessionCustomizer实例化时可用?上述操作失败,因为ConfigurationService实例仍然为空,即注入尚未发生.此观察对应于服务器的日志条目.似乎依赖注入机制总是在持久性单元 - 因此SessionCustomizer- 被实例化之后开始.我搞砸周围的各种注释(@Startup,@DependsOn(...),...),但无济于事.我的结论是正确的还是有另一种方法让EJB更早实例化并注入?

java oracle eclipselink java-ee-6 ejb-3.1

10
推荐指数
1
解决办法
524
查看次数