I've the following situation:
I wish the "methodB" was executed 10 times paralleling. But it only happening when the "methodB" is called from another bean.
Why the annotation "#Asynchronous" does not work when the method is called from another method in the same class?
Thanks.
It only works for methods call via a client proxy, for example a #Local or #Remote interface. This is described in the EJB 3.1 specs (section 4.5 - 4.5.1):
A session bean can expose methods with asynchronous client invocation semantics
...
The #Asynchronous annotation is used to designate which business methods are asynchronous.
...
Asynchronous method invocation semantics only apply to the no-interface, Local business, and Remote business client views.
Related
I want to define a annotation like #PlatformRelated, once it is marked in a interface, there will be a proxy bean at spring context, and this proxy bean should be #Priority.I want this proxy could invoke different implement according to key parameter #KeyPrameter.And I still wanna use spring features like #Async,#Trasaction,etc... at my Implement1 and Implement2.
#PlatformRelated
interface MyInterface {
method(#KeyPrameter String parameter);
}
#Component
class Implement1 implements MyInterface {
method(String parameter){
//do something 111
}
}
#Component
class Implement2 implements MyInterface {
method(String parameter){
//do something 222
}
}
#Service
class BusinessService{
#Autowired
private MyInterface myInterface;
public void doSomething() {
myInterface.method("key1");
//Implement1 work
myInterface.method("key2");
//Implement2 work
}
}
Do you guys have some good idea to complete it?
I must admit I haven't totally understood the meaning #Priority, however, I can say that if you want to implement this feature in spring, you should probably take a look at Bean Post Processors.
BeanPostProcessors are essentially a hook to Bean Creation process in spring intended for altering bean behavior.
Among other things, they allow wrapping the underlying bean into the proxy (CGLIB/java.lang.Proxy if you're working with interfaces, or even using programmatically Spring AOP), these proxies can provide a hook to the method execution that can read your annotations (like mentioned #KeyParameter) and execute a code in a way similar to Aspect's code that you already make use of.
Not all bean post processor wrap the bean into the proxy. For example, if you want to implement a BPP that uses "#Autowire", you will return the same bean, just "inject" (read, put by reflection) its dependencies. On the other hand, if you want to implement with BPP #Transactional behavior, then yes, you should wrap the bean into a proxy that would take care of transaction management capabilities before and after the method execution.
It's totally ok to have a spring bean that gets "altered" by many post processors, some of them would wrap it into a proxy other will just modify-and-return the same bean, If there are many BPP-s that wrap the bean into proxy we'll get "proxy inside proxy inside proxy" (you get the idea). Each layer of proxy will handle one specific behavior.
As an example, I suggest you take a look at existing Spring postprocessors, or, for instance, a source code of the following library: Spring Boot metering integration library
This library contains some implementations of post processors that allow metrics infrastructure integration by defining annotations on methods of Spring Beans.
i Have a job which needs both a dao and 1 factory class
something like this
https://pastebin.com/kK7VcbW1
My question is how to inject them , i get this exception when the code reaches the dao calling getSomething in the Factory class
In the abstractDao i #Inject entityManager which i get from an #ApplicationScoped EnttityManagerProducer its getEntityManager is #RequestScoped
org.jboss.weld.context.ContextNotActiveException: WELD-001303: No active contexts for scope type javax.enterprise.context.RequestScoped
at org.jboss.weld.manager.BeanManagerImpl.getContext(BeanManagerImpl.java:691)
at org.jboss.weld.bean.ContextualInstanceStrategy$DefaultContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:89)
at org.jboss.weld.bean.ContextualInstanceStrategy$CachingContextualInstanceStrategy.getIfExists(ContextualInstanceStrategy.java:164)
at org.jboss.weld.bean.ContextualInstance.getIfExists(ContextualInstance.java:63)
at org.jboss.weld.bean.proxy.ContextBeanInstance.getInstance(ContextBeanInstance.java:83)
at org.jboss.weld.bean.proxy.ProxyMethodHandler.invoke(ProxyMethodHandler.java:99)
at org.jboss.weldx.persistence.EntityManager$1070085530$Proxy$_$$_WeldClientProxy.createQuery(Unknown Source)
at com.org.dao.impl.ConcreteDAOImpl.getByName(ConcreteDAOImpl.java:18)
at com.org.dao.impl.ConcreteDAOImp$Proxy$_$$_WeldClientProxy.getByName(Unknown Source)
at com.org.FactoryImpl.getObj(FactoryImpl.java:33)
(the real classes i replaced for the sake of the example)
I tried putting the annotations on both class and interface level i dont know which is preferrable
This type of functionality is built in out of the box with Apache Deltaspike, you can read about the scheduler module. The problem as you're aluding to is that by default, contexts are not started automatically when outside of Java EE. To do that, you need to manually start one. In CDI 2.0 this can be done by adding #ActivateRequestContext to a method/class and a request scope will be started for the duration of that method.
Prior to CDI 2.0, its platform specific. DeltaSpike solves the issue much cleaner.
I have a problem accessing stateless EJBs in the preDestroy method of an singleton. I need to log the shutdown of the application server in an database table.
This is what the singleton looks like:
#Startup
#Singleton
public class ServerShutdown {
#EJB
TableFacade tableFacade;
#PreDestroy
private void shutdown() {
TestEntity e = tableFacade.find("test");
//do something
}
}
Here's example code of the stateless bean:
#Stateless
public class TableFacade {
...
public TestEntity find(String test) {
Query query =
getEntityManager().createNamedQuery("TestEntity.namedQuery");
return (TestEntity) query.getSingleResult();
}
}
If the server is shutting down, the preDestroy method is accessed and the EJB method is called. But during the call, the server seems to force the shutdown process and cancels the calling of the EJB method.
I'm using Java EE 6, JDK 1.8, EJB 3.1, eclipselink 2.5.2.
Thanks in advance
The #predestroy should only do ejb resource cleanup, such as connection, variable etc...
Your problem has to do with the transaction context, infact from the spec:
The PreDestroy lifecycle callback interceptor methods for stateless
and stateful session beans execute in an unspecified transaction
context.
And then:
For example, it would be wrong to perform database operations within a
stateful session bean’s PostConstruct or PreDestroy lifecycle callback
interceptor methods and to assume that the operations are part of the
client’s transaction. The PostConstruct and PreDestroy methods for
stateful and stateless session beans are not controlled by a
transaction attribute because handling rollbacks in these methods
would greatly complicate the session instance’s state diagram.
So, it is not explicitly forbidden, but you are warned that things may go wrong.
According to the ejb 3.2 spec, singleton beans are allowed to access ejb's in their pre destroy method. See section 4.8.6 Table 3. If a singleton bean needs to access another singleton bean, then it must declare its dependency using the #DependsOn annotation. The example provided by the original poster should work.
We have some JavaEE5 stateless EJB bean that passes the injected EntityManager to its helpers.
Is this safe? It has worked well until now, but I found out some Oracle document that states its implementation of EntityManager is thread-safe. Now I wonder whether the reason we did not have issues until now, was only because the implementation we were using happened to be thread-safe (we use Oracle).
#Stateless
class SomeBean {
#PersistenceContext
private EntityManager em;
private SomeHelper helper;
#PostConstruct
public void init(){
helper = new SomeHelper(em);
}
#Override
public void business(){
helper.doSomethingWithEm();
}
}
Actually it makes sense.. If EntityManager is thread-unsafe, a container would have to do
inercept business()
this.em = newEntityManager();
business();
which will not propagate to its helper classes.
If so, what is the best practice in this kind of a situation? Passing EntityManagerFactory instead of EntityManager?
EDIT: This question is very interesting so if you are interested in this question, you probably want to check out this one, too:
EDIT: More info.
ejb3.0 spec
4.7.11 Non-reentrant Instances
The container must ensure that only one
thread can be executing an instance at
any time. If a client request arrives
for an instance while the instance is
executing another request, the
container may throw the
javax.ejb.ConcurrentAccessException to
the second client[24]. If the EJB 2.1
client view is used, the container may
throw the java.rmi.RemoteException to
the second request if the client is a
remote client, or the
javax.ejb.EJBException if the client
is a local client.[25] Note that a
session object is intended to support
only a single client. Therefore, it
would be an application error if two
clients attempted to invoke the same
session object. One implication of
this rule is that an application
cannot make loopback calls to a
session bean instance.
And,
4.3.2 Dependency Injection
A session bean may use dependency injection
mechanisms to acquire references to
resources or other objects in its
environment (see Chapter 16,
“Enterprise Bean Environment”). If a
session bean makes use of dependency
injection, the container injects these
references after the bean instance is
created, and before any business
methods are invoked on the bean
instance. If a dependency on the
SessionContext is declared, or if the
bean class implements the optional
SessionBean interface (see Section
4.3.5), the SessionContext is also injected at this time. If dependency
injection fails, the bean instance is
discarded. Under the EJB 3.0 API, the
bean class may acquire the
SessionContext interface through
dependency injection without having to
implement the SessionBean interface.
In this case, the Resource annotation
(or resource-env-ref deployment
descriptor element) is used to denote
the bean’s dependency on the
SessionContext. See Chapter 16,
“Enterprise Bean Environment”.
I used a similar pattern, but the helper was created in #PostConstruct and the injected entity manager was passed in the constructor as parameter. Each EJB instance had its own helper and thread-safety was guaranteed then.
I also had a variant were the entity manager was not injected (because the EJB wasn't using it altogether), so the helper has to look it up with InitialContext. In this case, the Persistence context must still be "imported" in the parent EJB with #PersistenceContext:
#Stateless
#PersistenceContext(name="OrderEM")
public class MySessionBean implements MyInterface {
#Resource SessionContext ctx;
public void doSomething() {
EntityManager em = (EntityManager)ctx.lookup("OrderEM");
...
}
}
But it's actually easier to inject it (even if the EJB doesn't use it) than to look it up, especially for testability.
But to come back to your main question, I think that the entity manager that is injected or looked up is a wrapper that forwards to the underlying active entity manager that is bound to the transaction.
Hope it helps.
EDIT
The section § 3.3 and § 5.6 in the spec cover a bit the topic.
I've been using helper methods and passed the EntityManager there, and it is perfectly OK.
So I'd recommend either passing it to methods whenever needed, or make the helper a bean itself, inject it (using #EJB) and inject the EntityManager there as well.
Well, personally, I wouldn't like to have to pass the Entity Manager to all my POJOs in my constructors or methods. Especially for non-trivial programs where the number of POJOs is large.
I would try to create POJOs/HelperClasses that deal with the Entities returned by the EntityManager, instead of using the entitymanager directly.
If not possible, I guess I'd create a New EJB Bean.
Application Server: JBOss 4.2
I have a method which I want to intercept.Its a method annotated #Timeout and invoked by javax.ejb.TimerService instance.
The method signature:
#Stateless
class A
#TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
#Timeout
#Interceptors(AnInterceptor.class)
public void doSomething(Timer timer)...
Now I have the interceptor class:
public class AnInterceptor {
#AroundInvoke
public Object intercept(InvocationContext ic) throws Exception{...
System.out.prin(...)
It does work on other method methods (which are not annotated with #Timeout)
Thanks,
Rod
Per the spec, AroundInvoke is not supported for timeout methods (business interface, component interface, and webservice endpoint only). Searching Google, AroundTimeout appears to be coming in EJB 3.1 (pages 12 and 22):
http://www.ow2.org/xwiki/bin/download/Events2009AnnualConference/Program/JavaEE6-EasyBeans-F-Benoit.pdf
In the meantime, you can workaround the issue by injecting a reference to the same bean into itself. In other words inject (or lookup) another "A" from within "A", and then create and invoke a new "doTimeout" method from your "doSomething" method.
Instead of using #AroundInvoke, try using #AroundTimeout
"Interceptors for EJB timer service timeout methods may be defined using the #AroundTimeout annotation on methods in the target class or in an interceptor class. Only one #AroundTimeout method per class is allowed."
Here you can see how to use it, under the section "Intercepting Timeout Events"
http://docs.oracle.com/javaee/6/tutorial/doc/gkedm.html#gkedu