如果在应用程序初始化期间发生异常,是否有任何方法可以阻止Java EE应用程序启动?我基本上正在寻找一种方法,使应用程序在应用程序初始化期间从一个或一个bean 抛出一个未处理的异常后进入一个" j2ee.state.failed
"状态(按照JSR-77).ServletContextListener
Singleton
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个错误的请求,如规范中所述.
如果在初始化期间发生异常,我是否会忽略规范中阻止应用程序启动的任何部分?
我正在尝试在我的应用程序中使用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资源.."
我无法弄清楚如何正确配置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
今天下午成为一个完整的大菱鲆,似乎无法在任何地方找到答案.
使用新的EJB 3.1规范是否可以将EJB注入pojo?我知道在EJB 3.0中,@ EJB注释可用于注入EJB,但这不适用于简单的pojos.
如果不是,我必须在JNDI中查看bean,因为我知道你不能简单地使用new关键字.
提前致谢.
卡尔
我打算用来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
最终围绕类似结构的包装器对象?
我一直在尝试设置我的应用程序,以便我可以整天测试它的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的正确方法吗?
我正在使用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继承,有时在超类中使用注释,就像这个通用实体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) 使用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名称,但我无法弄清楚映射的注释.
谢谢!
根据Robert C. Martin的干净代码方法应该有一个小签名.最好的情况是没有参数的方法.相反,建议使用状态变量.这非常有用.但是无状态会话bean呢?
这个名字有点令人困惑,因为SLSB可以拥有州.您只需要进行内务管理,这样就不会使用先前EJB调用中的状态.
回到干净的代码:我也喜欢在SLSB中使用实例变量.这样可以正常工作,如果你足够小心,你就不会遇到状态不一致的问题,因为每次公共方法调用都会覆盖状态.
到现在为止还挺好.但是如果用过的bean回到池中会发生什么?它采取了它的状态.根据状态的大小,这可能是真正的内存泄漏.JBoss对bean非常慷慨,产生了大量的bean,导致一些严重的内存消耗 - 一无所获.
因此,一种方法是在bean方法存在之前清理状态,并将bean返回到池中.但在我看来,这应该是无用的代码.
有没有正确的方法来处理这个问题?在这种情况下,最佳做法是什么?
在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更早实例化并注入?
ejb-3.1 ×10
java ×7
java-ee-6 ×6
glassfish ×4
java-ee ×4
ejb ×2
ejb-3.0 ×2
annotations ×1
coding-style ×1
eclipselink ×1
glassfish-3 ×1
inheritance ×1
jpa-2.0 ×1
maven-2 ×1
oracle ×1
servlets ×1
startup ×1
unit-testing ×1