我正在尝试将Spring bean注入到EJB中,@Interceptors(SpringBeanAutowiringInterceptor.class)
但是我无法使用beanRefContext.xml
我见过的示例.
这是我的EJB:
@Stateless
@Interceptors(SpringBeanAutowiringInterceptor.class)
public class AlertNotificationMethodServiceImpl implements
AlertNotificationMethodService {
@Autowired
private SomeBean bean;
}
Run Code Online (Sandbox Code Playgroud)
我提供了一个beanRefContext.xml,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="...">
<!-- Have also tried with ClassPathXmlApplicationContext -->
<bean id="context"
class="org.springframework.web.context.support.XmlWebApplicationContext">
<property name="configLocations" value="/config/app-config.xml" />
</bean>
</beans>
Run Code Online (Sandbox Code Playgroud)
但是,它似乎正在重新创建bean而不是获取现有的ApplicationContext.我最终得到以下异常,因为我的一个bean是ServletContextAware.
java.lang.IllegalArgumentException: Cannot resolve ServletContextResource
without ServletContext
Run Code Online (Sandbox Code Playgroud)
使用时SpringBeanAutowiringInterceptor
,是不是应该获取ApplicationContext而不是创建一个新的?
我也试过更改我的web.xml,所以contextConfigLocation指向beanRefContext.xml,希望它加载我的Spring配置,但我最终得到了与上面相同的异常.
有谁知道如何正确地做到这一点?我看到的示例似乎使用了我正在使用的相同方法,我假设这意味着在调用Interceptor时正在重新创建bean(或者它是如何工作的,我误解了).
我有一个JavaEE6应用程序,由Web东西和EJB组成,并且部署为仅使用WAR(使用EJB3.1).构建基于Maven.我刚刚看了一下新的可能命令在Java EE 6的初始化模块在这里,我还需要我的应用程序.此外,我想有一个选项来定义XML中的一些EJB属性.
由于该示例是作为EAR项目部署的,因此订单在application.xml中定义.但是在WAR部署的项目中,没有application.xml.现在我想知道我可以在哪里定义这样的信息?或者是否可以在WAR-deployed-app中以某种方式使用application.xml?
编辑:
哎呀我没有正确读取模块顺序示例,在第一时间我认为它是关于我的应用程序中的EJB加载的顺序.当然我的WAR-app中只有一个模块,所以排序没有意义.
好吧,但就我而言,一个大问题仍然存在(也改变了问题标题以反映变化):ejb-jar.xml怎么样?我可以用XML以某种方式定义关于我的EJB的东西(因为它对某些设置有用,以避免重新编译)?
我有一个Singleton EJB(javax.ejb.Singleton版本.叹气.),它有一个CDI观察者方法.当我尝试将此部署到glassfish 3.1时,服务器无法在没有任何实际解释的情况下部署EAR文件 - 只是说在部署期间没有任何更多细节存在异常.
SEVERE: Exception while loading the app
SEVERE: Exception while shutting down application container
....
SEVERE: Exception while shutting down application container : java.lang.NullPointerException
Run Code Online (Sandbox Code Playgroud)
这是CDI事件监听器:
public void updateFromGranule(@Observes @CloudMask GranuleAvailableEvent granuleEvent) {
LOG.info("updating cloud map");
update(granuleEvent.getGranule(), CloudMask.class);
fireUpdate();
}
Run Code Online (Sandbox Code Playgroud)
如果我将Singleton bean更改为只是一个@ApplicationScoped bean,那么app就可以正常部署.同样,如果我删除CDI事件观察器方法,应用程序部署正常.我实际上需要将该类作为EJB单例,因为我想要EJB的事务,线程安全等,所以将它作为@ApplicationScoped POJO留下来对我来说并没有多大用处.这个问题似乎并不局限于Singleton bean - 我已经通过将注释更改为@Stateless和@Stateful进行了实验,我得到了相同的问题.
在我看来,这可能是Weld中的一个错误,也许Weld和EJB正在争论他们如何代理该方法 - 可能是EJB需要添加一个拦截器类并包装该方法以确保线程安全,而Weld正在尝试做某事否则使事件监听器工作?
我在这里误解了什么,CDI事件处理程序是否应该在EJB上使用(在这种情况下应该有来自glassfish的更好的错误消息) - 或者这实际上只是CDI或EJB实现中的错误?
我一直发现我已经存在的事务是在标记的EJB的任何方法中提交的@ejb.transaction
type="Required"
.这可能是正确的吗?
我的期望是,一个EJB"要求"交易是指:如果有一个已经存在,它会礼貌地离开它时未提交这样做,不管是谁调用开始()可以继续调用之前将它用于进一步的操作commit()
或rollback()
.[当然,如果首先没有事务,那么EJB方法将同时调用begin()
和commit()
/ rollback()
.]
我的期望是错误的,还是我应该寻找配置错误?
可能有必要补充说我在EJB中使用了Hibernate 3.我在调用EJB方法之前获取了UserTransaction.EJB生成的包装器ServerTransaction.commit()
在退出时调用,Hibernate将其挂钩并利用该机会关闭其Session.我得到的错误是一个Hibernate延迟加载异常,因为当我尝试访问Hibernate持久化对象上的getter时会话被关闭.所以从技术上来说,我不是百分之百确定ServerTransaction.commit()
我是否观察到我必须承诺UserTransaction
我开始(可能ServerTransaction.commit()
并不总是真正遵循"真正的"提交?),但如果它没有 - 那么基于什么基础是Hibernate关闭会议?
更新: 我相信我的上述假设是正确的,但我的观察有点偏.请参阅下面的我自己提供的答案.
完成以下任务的最佳方法是什么?
我能想到的几个方法可能会工作.还有其他什么,哪个最好?
使用@TransactionManagement(type=BEAN)
和UserTransaction
,并在捕获异常后显式回滚.例如:
catch (Exception e) {
e.printStackTrace();
utx.rollback();
}
使用容器管理的事务,指定@TransactionAttribute(value=NOT_SUPPORTED)
上onMessage
然后委托DB活动与一个单独的方法@TransactionAttribute(value=REQUIRED)
.
保留事务处理,并在服务器中重新配置重试属性.我正在使用Glassfish 3.1.1,我不确定如何设置它.
保留所有内容并明确检查消息是否在正文中重新发送,onMessage
如果重新发送则退出.(message.getJMSRedelivered()
?)
什么运作良好?有没有一种标准/最佳实践方法来处理这个问题?
我有一个@RequestScoped CDI bean,我想把它变成一个EJB来获取声明式事务.(我在EJB 3.1,Java EE 6上)
目前,我在子例程之间传递状态,假设实例仅用于单个请求.如果我@Stateless
现在补充说假设会改变.
例如,我想做类似的事情
@Stateless
@Named
@RequestScoped
public class Foo {
private String var1; // can't use instance vars in @Stateless?
private String var2;
public void transactionForRequest() {
var1 = value;
var2 = value;
....
subroutine();
}
}
Run Code Online (Sandbox Code Playgroud)
我认为以上不起作用 - 这是正确的吗?
我正在考虑两种选择:
EJBContext.getContextData
map替换实例变量.哪个更好?还有其他一些我没想到的选择吗?(除了等待Java EE 7或切换到Spring.:-))
在我正在研究的Java EE 6项目中,有一个用@EJB注释的单独字段没有被注入.注射在其他地方工作正常.
作为Java EE的新手,我不知道它是否与抽象类中的字段有关,也不能从Glassfish(3.1.2)中找到关于为什么没有发生这种注入的任何输出.
在发生NullPointerException之前,服务器日志中没有错误或警告,因为dataSourceControl字段为null.我已经验证了DataSourceControl Singleton是通过在其构造函数中放入日志来实例化的.
据我所知,dataSourceControl字段没有被注入,但是日志没有给我这么做的理由.
public abstract class AbstractDataMap<T> {
@EJB
private DataSourceControl dataSourceControl; // This is not being injected
DataSourceControl getDataSourceControl() {
return dataSourceControl;
}
// Other methods
}
public abstract class AbstractDataMapDBProd<T> extends AbstractDataMap<T> {
@Override
protected Connection getDBConnection() {
return getDataSourceControl().getConnectionX(); // NullPointerException here
}
// Other methods
}
@Stateless
public class CountryMap extends AbstractDataMapDBProd<Country> {
public boolean update(final Country current, final Country legacy) {
Connection connection = getDBConnection();
// More code 'n stuff …
Run Code Online (Sandbox Code Playgroud) 我正在做我的第一个Java EE项目,我想要进行测试.我搜索并发现自EJB 3.1以来,可以使用嵌入式EJB容器来测试业务层.我正在使用WildFly,但我还没有找到如何配置嵌入式容器.
那么,如何正确配置嵌入式容器并使用WildFly测试EJB 3.1+?
我感谢任何帮助!
我试图在节点node1和node2的集群的每个节点上调用远程ejb,但我总是得到node1.在两个节点中将EJB和客户端代码部署为EAR文件.应用程序在Wildfly 9 ApplicationServer上运行.从node1调用客户端代码.
EJB代码:
@Remote
public interface SLSBRemote {
public void test();
}
@Stateless(mappedName="SLSBEJB")
public class SLSBEJB implements SLSBRemote {
@Override
public void test()
{
try {
String nodeName = System.getProperty("jboss.node.name");
if(nodeName == null) {
nodeName = InetAddress.getLocalHost().getHostName();
}
log.debug("nodename: "+nodeName);
} catch (Exception e) {
log.error("Error",e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
客户代码:
public class testEjb
{
//invoking this method from other class. Able to pass node address
public void testBean(List<String> nodes)
{
Properties properties = new Properties();
properties.put(Context.INITIAL_CONTEXT_FACTORY, "org.jboss.naming.remote.client.InitialContextFactory");
Context …
Run Code Online (Sandbox Code Playgroud) ejb-3.1 ×10
java-ee ×6
java-ee-6 ×4
ejb ×3
glassfish ×3
cdi ×2
java ×2
jms ×2
glassfish-3 ×1
jboss-weld ×1
spring ×1
testing ×1
transactions ×1
wildfly ×1
wildfly-9 ×1