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.
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 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
#WebListener
public class AllRequestsWebListener implements ServletRequestListener {
#Inject HttpRequestProducer producer;
public void requestInitialized(ServletRequestEvent sre) {
producer.requestInitialized(sre);
}
}
...
#RequestScoped
public class HttpRequestProducer {
...
}
I don't know howto inject request-bean as method-parameter and therefore I can guess that it will work properly when Request-bean injection is threadLocal. Can someone explain me how it's implemented in a thread-safe manner?
What you have injected in your bean is a proxy representing the real deal. The proxy will always forward the invocation to the correct bean
Intuition based answer
I believe it is thread safe, as request scope is thread safe (session and above are not, as a user can open multiple browser sessions and use the same session ID)
I tested it, although it's empiric evidence, but the injected HttpRequestProducer gets a new instance each request.
Note that the requestInitialized and requestDestroyed can be (and in practice are) different threads, so I will investigate further if you intend to use the same injected object on both methods.
Specs backed answer
The hard part was to find hard evidence for this claim in the specs.
I looked into the CDI spec and couldn't quickly find conclusive evidence that a #RequestScoped object is thread safe (e.g. using thread local) however I assume that a #RequestScoped bean is using the same scope as the scoped beans in Java EE 5: (see here)
In there this clause is interesting:
Controlling Concurrent Access to Shared Resources In a multithreaded
server, it is possible for shared resources to be accessed
concurrently. In addition to scope object attributes, shared resources
include in-memory data (such as instance or class variables) and
external objects such as files, database connections, and network
connections.
Concurrent access can arise in several situations:
Multiple web components accessing objects stored in the web context.
Multiple web components accessing objects stored in a session.
Multiple threads within a web component accessing instance variables.
A web container will typically create a thread to handle each request.
If you want to ensure that a servlet instance handles only one request
at a time, a servlet can implement the SingleThreadModel interface. If
a servlet implements this interface, you are guaranteed that no two
threads will execute concurrently in the servlet’s service method. A
web container can implement this guarantee by synchronizing access to
a single instance of the servlet, or by maintaining a pool of web
component instances and dispatching each new request to a free
instance. This interface does not prevent synchronization problems
that result from web components accessing shared resources such as
static class variables or external objects. In addition, the Servlet
2.4 specification deprecates the SingleThreadModel interface.
So in theory, it seems that the object itself is going to have one instance per request thread, however I couldn't find any hard evidence that this is supported.
am going through enterprise session bean material.i have doubts regarding below oints :-
1) lets say we mentioned the pool size as 50 for some statful session bean. Different 50 clients use them .
so now all the 50 beans maintain some state. At what point of time will these states be removed so that
if 51th clien ask for bean it does not get any previous spoilt state.?
2) lets say we mentioned the pool size as 50 for some stateless session bean and all are in use at some
point of time. If 51th client comes and ask for a bean, will that wait till some bean become free
or create new bean instance?
Stateful session beans are not normally pooled. It's possible, but their state makes them less ideal to pool as the client expects a fresh bean when obtaining a reference.
For stateless beans, yes the 51st client will have to wait. This is normally a good thing since it automatically moderates the resource consumption of your system. Depending on the resources you have, your workload and the amount of work being to in a single call to a ssb, you might want to tune the size of your pool.
As bkail states the pooling semantics of #Stateless beans are vendor-specific. That said in EJB 3.1 we added the #AccessTimeout annotation which can be used on the bean class or methods of a #Stateless, #Stateful or #Singleton bean.
#AccessTimeout
In a general sense this annotation portably specifies up to how long a caller will wait if a wait condition occurs with concurrent access. Specific to each bean type, wait conditions will occur when:
#Singleton - an #Lock(WRITE) method is being invoked and container-managed concurrency is being used. All methods are #Lock(WRITE) by default.
#Stateful - any method of the instance is being invoked and a second invocation occurs. OR the #Stateful bean is in a transaction and the caller is invoking it from outside that transaction.
#Stateless - no instances are available in the pool. As noted, however, pooling sematics, if any, are not covered by the spec. If the vendor's pooling semantics do involve a wait condition, the #AccessTimeout should apply.
Usage
The #AccessTimeout is simply a convenience wrapper around the long and TimeUnit tuples commonly used in the java.util.concurrent API.
import java.util.concurrent.TimeUnit;
#Target({METHOD, TYPE})
#Retention(RUNTIME)
public #interface AccessTimeout {
long value();
TimeUnit unit() default TimeUnit.MILLISECONDS;
}
When explicitly set on a bean class or method, it has three possible meanings:
#AccessTimeout(-1) - Never timeout, wait as long as it takes. Potentially forever.
#AccessTimeout(0) - Never wait. Immediately throw ConcurrentAccessException if a wait condition would have occurred.
#AccessTimout(30, TimeUnit.SECONDS) - Wait up to 30 seconds if a wait condition occurs. After that, throw ConcurrentAccessTimeoutExcpetion
No standard default
Note that the value attribute has no default. This was intentional and intended to communicate that if #AccessTimeout is not explicitly used, the behavior you get is vendor-specific.
Some vendors will wait for a preconfigured time and throw javax.ejb.ConcurrentAccessException, some vendors will throw it immediately. When we were defining this annotation it became clear that all of us vendors were doing things a bit differently and enforcing a default would cause problems for existing apps.
On a similar note, prior to EJB 3.0 there was no default transaction attribute and it was different for every vendor. Thank goodness EJB 3.0 was different enough that we could finally say, "For EJB 3.0 beans the default is REQUIRED."
I want to call to a method from an EJB in the same instant in which one deploys itself, without using a servlet.
Thanks.
David.
There seems to be no life-cycle methods defined by the EJB spec for this purpose. Individual vendors may provide extensions to allow this. For example Startup Beans in WebSphere would be a place to put the invocation logic you want.
Using techniques such as a static method seem slightly dangerous in that we don't know whether all dependency injection is complete before that static method fires, and hence whether you can safely use the business methods of the EJB.
Persoanlly, if I needed to be portable I would bite the bullet and use a servlet. It costs very little.
Try doing your initialization within a static block. This will run once when the classloader loads the class.
static { System.out.println("static"); }
The PostConstruct hook is right for that.
Find more info on about PostConstruct here:
in the javadoc
lifecycle of EJBs in the JavaEE 5 tutorial
Let's finish with a quick example:
#Stateless
public class TestEJB implements MyEJBInterface{
#PostConstruct
public void doThatAfterInitialization() {
//put your code here to be executed after creation and initialization of your bean
}
}
Static initializer blocks are technically not illegal in EJB but they are used to execute code before any constructor (which might be a problem) when instantiating a class. They are typically used to initialize static fields which may be illegal in EJB if they are not read only. So, what about using ejbCreate(), setSessionContext() or setEntityContext() methods instead (not even sure this would be appropriate without more details on the problem you are trying to solve)?
The EJB container, for a #Singleton bean, shall create the instance of the bean as soon as the application is deploy if it is annotated #Startup.
That will, of course, fire up static initialization blocks, the constructor, dependency injection setters, #PostConstruct methods etc.
Here is the appropriate referente to the Java EE 6 Tutorial.