I am using EJB in order to take advantages of:
Concurrent (instead of creating 2 threads, I divided the work into 2
EJB beans).
Pooling (I use stateless EJB a lot and I love the idea that the pool
contains a specific number of bean). This way, I am not afraid of
running out of memory. Memory usage is more predictable).
Asynchronous processing (all I need is just an annotation).
Well, the problem is I am using it with MongoDB so I don't need any transaction. I can use #TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) and #TransactionAttribute(TransactionAttributeType.NEVER) annotations but... it means I must specify it everywhere?
Is there anyway to disable EJB transaction by default?
In an EJB 3.0 container, annotate your EJB (or EJB method) with:
#Stateless
#TransactionManagement(TransactionManagementType.BEAN)
#TransactionAttribute(value=TransactionAttributeType.NEVER)
public class YourBean
for BEAN management. For CONTAINER management instead:
#Stateless
#TransactionManagement(TransactionManagementType.CONTAINER)
#TransactionAttribute(value=TransactionAttributeType.NEVER)
public class YourBean
The default value is managed by the container but if you dont specify nothing to do i think you solve your problem.
Or annotate all the Ejb to donĀ“t support transaction
#Stateless
#TransactionManagement(TransactionManagementType.NEVER)
public class YourBean
Remember that the ejb transactions are executed in a hierarchical way, ie if the first method being invoked does not support methods "children methods" are handled in the same way
Related
I have a Java EE app that's deployed on WildFly AS.
I have a method annotated with #Asynchronous and I need to set the max number of threads for this method.
I configured a new <managed-executor-service> in server config, but I don't know how to bind it to an async method.
This link: https://developer.jboss.org/message/851027#851027
provides a good answer to how (or when) to use #Asynchronous and when to use JSR-236 ExecutorService and concurrency utilities:
In short, #Asynchronous is a annotation (EE6) to mark an EJB method as async.
You can invoke the method and keep the future object to check whether the method is finished and get the result. The EJB Concurrency Utilities are provided to have a safe way in EE7 to delegate work to a parallel thread. Threads started by this ConcurrentUtilities are managed by the container.
In difference to a direct start of a Thread (which is not allowed for an EE application). There is less overhead than using #Async and you have a bit more control.
See also this link about how to inject a MES:
http://www.adam-bien.com/roller/abien/entry/injecting_an_executorservice_with_java
I know from experience that injection of circular dependencies in EJB do work, at least in some application servers.
I've done it multiple times with self-injection (e.g. to get an EJB proxy for #TransactionAttribute, #RolesAllowed, #Asynchronous etc. to work).
I've done it with more complex graphs too (A->B->A etc.), which obviously work too.
I've done it at least in Glassfish 3/4, Weblogic, and JBoss 7.3. Maybe Weblogic, not sure.
Now, I've been trying to find some precise guarantee from the specification, without success. There are provisions for this in CDI, but I couldn't find any explanation on why it works for EJBs. Is there some indirect one, maybe?
I'm looking from some references from EJB specifications regarding this.
I don't believe the EJB specification explicitly disallows self-injection, which means it implicitly allows it since there is no reason for the bean's own interface to be different from the interface of some other EJB. In practice, self-injection can only work for stateless (and singleton in EJB 3.1) and not stateful since each lookup/injection of a stateful bean creates a new instance, which would result in infinite recusion. For stateful, you can inject SessionContext and use the getter methods to return a "self-proxy" rather than using injection. This technique also works for stateless/singleton, and it might be marginally faster than using injection (particularly if you cache the result in an instance field the same as injection) since the EJB container can probably return a self-proxy more directly than going through injection/JNDI.
The only additional authority I can give to this answer is that I was one of the primary developers/maintainers of the EJB container in WebSphere Application Server for 5 years. To add to your list of products, I know that self-injection also works in practice on WebSphere Application Server.
I have a process that I want to run serially, but in a different thread. How can I accomplish that in JBoss 7? The obvious answer would be an #Asyncronous EJB method where the EJB is configured to only have one thread running at a time (the others requests would be in queue).
How can that be best accomplished?
I believe a great way of achieving this is using a combination of Singleton + Asynchronous annotations from EJB 3.1, you can also use the AccessTimeout annotation to provide wait timeout for the queued calls and finally you can even use Lock annotation to control READ,WRITE locking on this if you want:
#Singleton
public class SingletonAsyncProcessor{
#Asynchronous
#AccessTimeout(5000) //times out after 5 seconds
public Future<String> addJobToQueue(String jobName) {
Also notice that you can use most of these annotations at class level(all methods will be async) or method level. You can even run EJB 3.1 in the web container.
EJB 3.1 ROCKS.
Regards.
In EJB 3.1 I can get all timers for a specific bean using TimerService#getTimers() on the TimerService instance obtained for that bean.
What I actually need however is a system-wide version of this. I.e. I would like to have a list of all Timers in the EJB container.
Is something like that possible?
There simply is no official API for this in EJB 3.1.
If you're only using annotations and/or interfaces to mark your timeout method, you could do a run-time walk over all classes on the class path and check if this annotation or interface is present. This will at least give you the beans which theoretically can have timers associated with them.
Unfortunately, this still won't give you the actual timers for those beans. In EJB 3.1, the time information can only be requested from the session context, which as you already seem to know is private for each bean. This means that only the bean itself can see what timers it has.
As an alternative to what Nayan is suggesting, you could let your beans implement a method that gives you this info. You can then mark this method with either an interface or a custom annotation.
In your system-wide sweep over all timer classes you first try to discover all beans that can have timers associated with them, and of those you then try to find whether they have the required annotation or interface. If they don't have this latter thing, you can log a warning. The advantage of this method is that it's less likely that timers slip through the cracks.
Yet another method, but a very brittle one, is to hack into whatever private structure the container holds to store the timer information. For persistent timers there is at least the persist store which you can check, and somewhere in the container there must be the structure you're after. It must be there as the container itself has to be aware of this. Often a container has some private API to get to this and you can hack into that via reflective tricks.
It can also be that containers offer a proprietary API for this. E.g. in Java EE 5 it's impossible to do a programmatic login in the Servlet container, but JBoss AS has a proprietary API that allows you to do exactly that.
EJB 3.2 has a method called "getAllTimers()".
https://docs.oracle.com/javaee/7/api/javax/ejb/TimerService.html#getAllTimers--
Description:
Returns all active timers associated with the beans in the same module in which the caller bean is packaged. These include both the programmatically-created timers and the automatically-created timers.
Below is the sample code fragment for fetching information of all the existing timers of the system.
//---
private void viewSystemTimers(){
Collection<Timer> allTimers = sessionContext.getTimerService().getTimers();
Iterator<Timer> iterator = allTimers.iterator();
while (iterator.hasNext()) {
Timer timer = (Timer) iterator.next();
System.out.println("SYSTEM TIMER : "+timer.getInfo());
}
}
//---
You can only see timers of your own class. With the EJB Scheduler you can't list all timers of your application.
#Resource
private TimerService timerService;
for (Timer timer : timerService.getTimers()) {
// do anything
}
With Quartz you can via Scheduler.getJobNames/triggerNames for all jobs/triggers of you application.
We all know that in the web tier there is the possibility that only a single instance of a given Servlet exists which services multiple requests. This can lead to threading issues in instance variables.
My question is, is it safe to inject an EJB using the #EJB annotation into a servlet as an instance variable?
My initial instinct would be no, under the assumption that the same instance of the EJB would service multiple requests at the same time. It would seem that this would also be the instinct of a number of other programmers: Don't inject to servlets
However have I jumped to the wrong conclusion. Clearly what is injected into the servlet is a proxy, under the hood does the container actually service each request with a different instance and maintain thread safety? As this forum would suggest: Do inject to servlets
There seems to be a lot of conflicting opinions. WHICH IS CORRECT???
It is safe to inject an EJB in a Servlet as a Servlet instance variable, as long as the EJB is Stateless. You MUST NEVER inject a Stateful Bean in a Servlet.
You must implement your EJB stateless in that it doesn't hold any instance variable which itself holds a stateful value (like Persistence Context). If you need to use the persistence context, then you must get an instance of it IN the methods of the EJB. You can do that by having a PersistenceContextFactory as a EJB instance Variable and then you get an instance of the entity manager from the Factory in the method of the EJB.
The PersistenceContextFactory is thread-safe, thus it can be injected in an instance variable.
As long as you comply to the above mentioned rules, it should be thread-safe to inject a Stateless Bean in a Servlet
Your reference "Don't inject to servlets" mentions nothing about ejbs or #ejb annotation. It talks about not thread safe objects such as PersistenceContext.
Per EJB spec you can access ejbs from variety of remote clients including servlets (EJB 3.0 Specification (JSR-220) - Section 3.1). Injecting ejb using #EJB annotation is a method of obtaining EJB interface via dependency injection (section 3.4.1) which is alternative to looking up ejb objects in the JNDI namespace. So there is nothing special about #EJB annotation with respect to EJBs obtained.
So, based on EJB 3.0 Spec, it's a standard practice to obtain ejbs from servlets using #EJB annotation.
It's a mixed bag.
Stateless session beans may be injected and are safe. This is because even if a single instance of a stub is used, access to the methods will be serialized by the container.
I think what inferreddesign says is not true. It doesn't matter if the stateless session bean uses a persistence context. Only one caller will ever access a single bean instance at the same time, so even though the persistence context is not thread safe, the EJB guards against multiple access to it. Think of it as if every session bean method has the synchronized keyword applied to it.
The main problem with injecting an EJB in a Servlet I think is performance. The single stub instance will become a major area of contention when multiple requests are queuing up while waiting for a session bean method to be executed for them.
I think the simple answer is that you aren't guaranteed that it is safe.
The reason for this is that there is nothing explicit in the EJB specification that says EJB home interfaces have to be thread safe. The spec outlines the behaviour of the server side part only. What you will probably find is that the client skeletons are actually thread safe but you would need to look at how they are implemented by the library you are using. The annotation part will just expand into a service locator so that doesn't buy you anything.