Does anyone know whether the initialization of instance fields within a method annotated with PostConstruct is considered to be thread safe? I am not quite sure if i have to make my fields of my ApplicationScoped bean volatile or not so other threads can really see the values...
Thanks for any hints or answers!
I don't have a direct reference to the spec that absolutely guarantees this, but #PostConstruct should be thread safe.
The CDI runtime is fully in charge of creating beans and will only create one instance for a given scope. #PostConstruct runs before the bean is accessible in such a scope or via injection.
Related
My understanding is that these beans are simple java objects, but once they have survived being removed at build-time and have been (lazily) initialized, they are held in the context indefinitely and should not be GC-able even if they are idle for long times.
But I was unable to confirm it after running through the 2.0 CDI specs and the bean lifecycle/CDI related Quarkus docs.
Are there any specific cases where this could happen?
So in theory, you can do AlterableContext#destroy(Contextual<?>) - this would remove the contextual instance (i.e. the instance of your #ApplicationScoped bean) from the context, and then it can be garbage-collected if there are no other references.
For example, in quarkus you can do Arc.container().instance(MyApplicationScopedFoo.class).destroy(). This would call the #PreDestroy callback if present, #PreDestroy interceptors if bound, and remove the MyApplicationScopedFoo instance from the application context.
Each time, I go on a specific jsf page which bean is annotated with #ViewScoped, the heap increase.
How to destroy ViewScope context ? (to destroy all associated objects and clean memory heap)
Upgrading to 2.2.8 give me other errors, so i want to stay with jsf 2.2.6 implementation.
Question is relative to this : "ViewScope context is not destroyed when View Map is destroyed"
So what is the other method to achieve this ? Does it mean ViewScoped have a pegleg and that is not recommended to use it. So what is the alternative when you have a lot info to display and also ajax on the same page ?
I tried this solution too without sucess. (this post looks like the same)
I read that and also that , i have tried #PreDestroy annotation who doesn't work either in ViewScoped.
I don't want to increase too much memory heap of VM.
If i go on the same jsf page handled by a managed bean with a viewScoped, each time the memory increase until application crash.
Garbage Collector is not occuring during session even after multi-postback or if i close definitively the session and wait 5-10 minutes.
NB: #PreDestroy is still called when session is closed.
We're starting to experiment with implementing our backend services using CDI. The scenario is this:
EJB with #Startup is started when EAR deployed. An ApplicationScoped bean is injected onto this:
#ApplicationScoped
public class JobPlatform {
private PooledExecutor threadHolder;
#Inject #Any
private Instance<Worker> workerSource;
...
The bean also has an Observer method, which, when an event is observed, gets a worker bean from the Instance workerSource and puts it on the threadPool, where it eventually runs to completion.
All working nicely. However... we've started to see garbage collection issues. A JMAP heap histogram shows that there are many of these workers hanging around, un-garbage collected.
We believe that this is down to the combination of CDI scoping. The API page for #Dependant (http://docs.jboss.org/cdi/api/1.0-SP1/javax/enterprise/context/Dependent.html) reinforces more clearly what's in the docs:
An instance of a bean with scope #Dependent injected into a field, bean constructor or initializer method is a dependent object of the bean or Java EE component class instance into which it was injected.
An instance of a bean with scope #Dependent injected into a producer method is a dependent object of the producer method bean instance that is being produced.
An instance of a bean with scope #Dependent obtained by direct invocation of an Instance is a dependent object of the instance of Instance.
So, following this:
The workerSource bean is bound to JobPlatform, and therefore has an ApplicationScoped lifetime
Any worker beans retrieved using that instance are bound to it, and therefore have an ApplicationScoped lifetime
Because the beanstore of the ApplicationScoped context (my knowledge of the terminology gets a bit hazy here) still has a reference to worker beans, they're not destroyed/garbage collected
Does anyone using CDI agree with this? Have you experienced this lack of garbage collection and, if so, can you suggest any workarounds?
The workers cannot be ApplicationScoped, yet the platform has to be. If we were to create a custom WorkerScope (uh ohhh...) and annotate each worker class with it, would that be sufficient to separate the dependency between worker and instance source?
There're also some suggestions at Is it possible to destroy a CDI scope? that I will look at, but wanted some backup on whether scoping looks like a valid reason.
Hope you can help, thanks.
Your understanding is correct. This was an oversight in the spec, and something that will be fixed in CDI 1.1. Instance can have a memory leak just like you've described when used in a long running scope such as SessionScoped or ApplicationScoped. What you will need to do is get a hold of the Contextual or Bean for the instance and destroy it that way.
For what you're doing, and to avoid the memory leak you're best off to use the BeanManager methods to create instances (that way you'll also have a handle on the Bean and can destroy it) instead of Instance.
While looking into implementing Jason's suggested workaround, I found some more resources relating to the issue:
The issue: https://issues.jboss.org/browse/CDI-139 and https://issues.jboss.org/browse/WELD-920
Example beanManager operations:
https://issues.jboss.org/browse/CDI-14?focusedCommentId=12601344&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-12601344
or
org.jboss.seam.faces.util.BeanManagerUtils
I understand that App Server takes care of the threading so the developer should only concentrate on the business logic...
but consider an example. A stateless EJB has a member of type CountManager.
#WebService
#Stateless
public class StatelessEJB {
private CountManager countManager;
...
public void incrementCount() {countManager.incrementCount();}
public int getCount(){return countManager.getCount();}
}
And the CountManager
public class CountManager {
public void increaseCount() {
// read count from database
// increase count
// save the new count in database table.
}
public int getCount() {
// returns the count value from database.
}
}
The developer should think about multi-threading here. If you make CountManager also an EJB, I guess problem won't go away.
What would be the general guideline for developer to watch out for?
Update:
Changed the code. Assume that the methods of EJB are exposed as webservice, so we have no control what order client calls them. Transaction attribute is default. Does this code behave correctly under multi threaded scenario?
The fact that EJB are thread-safe doesn't mean that different methods invocations will give you consistent results.
EJB gives you the certainty that every method in your particular EJB instance will be executed by exactly one thread. This doesn't save you from multiple users accessing different instances of your EJB and inconsistent results dangers.
Your CountManager seems to be a regular Java class which means that you hold a state in Stateless EJB. This is not good and EJB thread-safety won't protect you from anything in such case. Your object can be accessed through multiple EJB instances at the same time.
Between your client's first method invocation StatelessEJB.incrementCount() (which starts a transaction - default TransactionAttribute) and the second client's method invocation StatelessEJB.getCount() (which starts new transaction) many things might happen and the value of the count could be changed.
If you'd change it to be an EJB I don't think you'd be any more safe. If it's a SLSB than it still can't have any state. If the state is not realized as a EJB field variable but a database fetched data, than it's definitely better but still - the transaction is not a real help for you because your WebService client still executes these two methods separately therefore landing in two different transactions.
The simple solution would be to:
use the database (no state in SLSB) which can be synchronized with your EJB transaction,
execute both of these methods within the transaction (like incrementAndGet(-) method for WebService client).
Than you can be fairly sure that the results you get are consistent.
Notice that is not really a problem of synchronization or multi-threading, but of transactional behavior.
The above code, if run inside an EJB, will take care of race conditions by delegating transaction support to the data base. Depending on the isolation level and transactional attributes, the data base can take care of locking the underlying tables to ensure that the information remains consistent, even in the face of concurrent access and/or modifications.
Why is the struts action class is singleton ?
Actually I am getting point that it is multithreaded. but at time when thousand of request hitting same action, and we put synchronized for preventing threading issue, then it not give good performance bcoz thread going in wait state and it take time to proced.
Is that any way to remove singleton from action class ?
for more info Please visit : http://rameshsengani.in
You are asking about why the Action class is a singleton but I think you also have some issues understanding thread safety so I will try to explain both.
First of all, a Struts Action class is not implemented as a singleton, the framework just uses one instance of it. But because only one instance is used to process all incoming requests, care must be taken not to do something with in the Action class that is not thread safe. But the thing is: by default, Struts Action classes are not thread safe.
Thread safety means that a piece of code or object can be safely used in a multi-threaded environment. An Action class can be safely used in a multi-threaded environment and you can have it used in a thousand threads at the same time with no issues... that is if you implement it correctly.
From the Action class JavaDoc:
Actions must be programmed in a thread-safe manner, because the controller will share the same instance for multiple simultaneous requests. This means you should design with the following items in mind:
Instance and static variables MUST NOT be used to store information related to the state of a particular request. They MAY be used to share global resources across requests for the same action.
Access to other resources (JavaBeans, session variables, etc.) MUST be synchronized if those resources require protection. (Generally, however, resource classes should be designed to provide their own protection where necessary.
You use the Struts Action by deriving it and creating your own. When you do that, you have to take care to respect the rules above. That means something like this is a NO-NO:
public class MyAction extends Action {
private Object someInstanceField;
public ActionForward execute(...) {
// modify someInstanceField here without proper synchronization ->> BAD
}
}
You don't need to synchronize Action classes unless you did something wrong with them like in the code above. The thing is that the entry point of execution into your action is the execute method.
This method receives all it needs as parameters. You can have a thousand threads executed at the same time in the execute method with no issues because each thread has its own execution stack for the method call but not for data that is in the heap (like someInstanceField) which is shared between all threads.
Without proper synchronization when modifying someInstanceField all threads will do as they please with it.
So yes, Struts 1 Action classes are not thread safe but this is in the sense that you can't safely store state in them (i.e.make them statefulf) or if you do it must be properly synchronized.
But if you keep your Action class implementation stateless you are OK, no synchronization needed and threads don't wait for one another.
Why is the struts action class is singleton ?
It's by design. Again the JavaDoc explains it:
An Action is an adapter between the contents of an incoming HTTP request and the corresponding business logic that should be executed to process this request
The request parameters are tied to the web tier and you don't want to send that type of data into your business logic classes because that will create a tight coupling
between the two layers which will then make it impossible to easily reuse your business layer.
Because transforming web objects into model objects (and I don't mean the ActionForm beans here) should be the main purpose of Action classes, they don't need to maintain any state (and shoudn't) and also, there is no reason to have more instances of these guys, all doing the same thing. Just one will do.
If you want you can safely maintain state in your model by persisting info to a database for example, or you can maintain web state by using the http session. It is wrong to maintain state in the Action classes as this introduces the need for syncronisation as explained above.
Is there a way to remove singleton from action class?
I guess you could extend Struts and override the default behavior of RequestProcessor.processActionCreate to create yourself an Action per request
but that means adding another layer on top of Struts to change its "normal" behavior. I've already seen stuff like this go bad in a few applications so I would not recommend it.
My suggestion is to keep your Action classes stateless and go for the single instance that is created for it.
If your app is new and you absolutely need statefull Actions, I guess you could go for Struts 2 (they changed the design there and the Action instances are now one per request).
But Struts 2 is very different from Struts 1 so if you app is old it might be difficult to migrate to Struts 2.
Hope this makes it clear now.
This has changed in Struts2 http://struts.apache.org/release/2.1.x/docs/comparing-struts-1-and-2.html
*Struts 2 Action objects are instantiated for each request, so there are no thread-safety issues. (In practice, servlet containers generate many throw-away objects per request, and one more object does not impose a performance penalty or impact garbage collection.) *
I don't know much about struts, but it appears that this changed in Struts 2, so perhaps you should switch to Struts 2?