Hey! I'm relative new to both Java EE and Stackowerflow, please be kind :-)
I have a bunch of devices triggering Java messages to be sent on any state change. These devices are typically active for about 30-90 minute intervals. Each event message contains a device id in addition to the event details.
Central in my application is a message driven bean subscribing to those events. Every time I get an event I have to hit the database to look up some info about the device.
It would be absolutely terrific if I could associate a stateful session bean with each active device! If this had been a web application I would have used the http session to store a handle or reference to the stateful bean (I'm I right?). Is there any way that I can archive this from my message bean?
It would be nice, except it can't be done like you explained. MDBs (and SLSBs) are stateless by definition so it's safe to keep a conversation only during the invocation.
You could eventually break the spec and create a static attribute somewhere (maybe in the MDB itself) but this would certainly be not portable, neither scalable.
My suggestion is to enable caching at the JPA level (see your persistence provider of preference for details), so you can lookup whatever data you need very fast (really fast). This is portable and cluster-friendly. That's the way I use to do it in my projects and I am very happy with it.
Hope it helps.
I'm not that comfortable recommending specific products, but isn't the Terracotta server adressing needs like this?
Related
This may be more of a conceptual than technical question however I hope you can provide me some advice on how to proceed.
We are developing a large Java EE 7 application that works stateless and is getting requests from clients. Each request contains a session ID and each session contains a large amount of domain objects that are session specific.
We created a RequestScoped class that contains all the producer methods for our domain objects. When a request comes in with a session ID we call a setter Method on the producer to set the session ID in the producer CDI bean.
Now if one of the RequestScoped classes along the chain needs one of the domain objects it has an #Inject definition at the beginning of the class to get the domain object from the producer. The Producer itself has a connection to an inmemory DB to retrieve the domain objects from there and keep them in a local variable for future use in this request.
Now to the question: Say Bean A injects Domain Object X and changes some properties on X. Do I have to call an "update" Method in my producer and pass Domain Object X as a parameter or is it updated automatically in the context?
Upon injection in the Request Scope the CDI container creates a proxy to access the actual bean. Would this proxy be usable just like a regular reference? E.g. if I call a method on my injected bean, would it update the bean behind the proxy?
I know this will probably get me downvoted, but I'll answer anyway because I'm hoping it'll be valuable to you. It sounds like you guys have put the cart a mile in front of the horse.
The Producer itself has a connection to an inmemory DB to retrieve the domain objects from there and keep them in a local variable for future use in this request.
You're trying to re-invent what's called replicated, distributed, sessions. Don't do this. Use #SessionScoped beans and keep the business logic in your app, and let your infrastructure handle the application state. Imagine yourself years from now looking at this application, when your boss wants a UI refresh and your customers are demanding new features. You're going to not only maintain the application, but an entire mess of a buggy distributed framework you built :(
Instead, you can use a distributed in-memory DB to hold your session state and cache it locally! Apache Tomcat/TomEE has great support for this (I'm not sure what application server you are using)
Take a look at:
https://github.com/magro/memcached-session-manager (Use Couchbase, Redis, Memcached, Hazelcast, GridGrain, or Apache Geode)
http://community.gemstone.com/display/gemfire/Setting+Up+GemFire+HTTP+Session+Management+for+Tomcat (Specific to Gemfire)
We use the first with great success. If the Tomcat instance encounters a session id it doesn't have locally, it pulls it from the data grid. When it's done processing the request, it publishes that session changes back to the data grid. This is extremely fast and scales beautifully.
If your application server does not have the ability to do this, instead of writing the application in the painful manner you are doing, I would concentrate your efforts on writing a session replicator like memcached-session-manager. Good luck!
JBoss seems to have a pretty easy set of annotations/configurations for clustering and load balancing session beans, but I'm not seeing the same features in the GlassFish 3.x docs.
Let's say I have both MyStatefulBean and MyStatelessBean beans. For both of them, I want the following capabilities:
I want to be able to create a cluster of the bean (to any number or scale) and put them behind a software load balancer that will round robin the beans; and
If 1 of the clustered beans fails for any reason I want it taken out of the pool
Does GlassFish free/(community edition) even support this or would I have to implement this myself?
Tangential to the first question: does clustering/load-balancing even make sense form stateful beans? I don't think it does now that I think of it...but still the question applies to both types of beans until proven otherwise!
First, you need to enable high availability for the application if you want to preserve the session state on failure. If using the admin console, there is a checkbox for this on the deploy app screen. If you are deploying from the command line, then use "asadmin deploy --availabilityenabled=true --target mycluster myapp.ear".
When the bean is looked up, the bean RMI proxy/stub that is generated has a list of all the clustered GlassFish instances that are available. The order of the servers is randomly generated, and the RMI stub will select the server at the top of the list. This is how the load is spread across the cluster. If the remote server fails, the next server in the list is selected. If the remote bean is a stateful session bean, then the session is preserved on failover.
As #pdudits mentions, please read the documentation on the subject for more in-depth coverage.
Hope this helps!
If you plan to invoke the beans via remote calls, this is the chapter in High Availability Guide you're looking for.
Failover of stateful beans makes sense, but load-balancing is also possible. Bear in mind that it has its limits, the greatest one being, that extended persistence context cannot be used.
The pool sizes for a bean is specified in EJB service settings and can be overrided in glassfish-ejb-jar.xml for specific bean
AFAIK this is what EJB Spec says - when a system exception occurs (this includes unchecked exceptions), the bean is destroyed.
Based on this post http://www.adam-bien.com/roller/abien/entry/ejb_3_1_killed_the I use in my app #Named #Stateless bean for communication with a database (injecting EntityManager here) and display information on a jsf page. It's great facilitation since Java EE 5, but I have one question.
Is it secure to use such beans for maintaining a user session (shopping cart etc)? I read a book about ejb 3.0 and I know that the same stateless bean could be used with many clients.
What's the best approach to use a managed bean with all ejb features (transactions, thread safety etc)? I mean any other way than managed bean + ejb interface with implementation + ejb injection as in Java EE 5?
I use GlassFish 3.1 WebProfile
Adding to the advice of duffymo; there are some additional considerations for using stateful session beans vs using the HTTP session.
The HTTP session basically has a map like structure. It's directly available to all threads (requests) that are part of the session. This makes manipulating several items a relatively unsafe action. It's possible to synchronize on the session itself, but this is a risky operation that can potentially dead-lock your entire application. The HTTP session does allow you to declare event listeners, which fire upon any kind of modification of the http session.
The Stateful session bean of course has a bean structure. It has a kind of auto synchronization feature, as only thread can be active in the bean at the same time. Via annotations you can declare if other threads wait (and if so, for how long) or immediately throw an exception in the face of concurrent access.
Where there is normally only one http session per user, a single user can make use of multiple stateful session beans at the same time. A particular advantage of stateful session beans is that they have a mechanism to passivate their state after some timeout, which can free up your server's memory (at the cost of disk space of course). Stateful session beans do not directly have the kind of event listeners that the http session does have.
I think that originally the "session" aspect of stateful session beans was to maintain a session with remote non-web clients (Swing, another AS, etc). This is much like the http session was created to maintain a session with remote web clients. Since a non-web client can request and hold on to multiple proxies for stateful session beans, the web analogy is actually more akin to that of the recently introduced conversation scope.
In the case of remote web clients talking to a server, where the server internally talks to a stateful session bean, the concepts greatly overlap. The remote web client only knows about the http session (via the JSESSIONID) and nothing about the stateful session bean's session. So if the http session was lost, you typically would not be able to connect the remote client with the specific stateful session bean again. The HTTP session in this case is thus always leading and you might as well store your shopping cart items inside a single (http) session scoped bean.
There is one specific case where stateful session beans come in handy for internal communication, and that's if you need JPA's extended persistence context. This can be used if e.g. locks on entities need to last between requests (which is possibly handy for a shopping cart if you have limited stock and don't want to confront the user with an "out of stock" message as soon as he actually checks out).
Stateless beans cannot maintain shopping carts or session; that's what "stateless" means.
You need either a stateful EJB or to do it in the web tier. Those are the only places where session is maintained.
It's simple: I have an MDB and an EJB that sends messages to a topic (or queue). JBoss complains that the topic is not bound to the JNDI context.
I want to have the topic/queue to be automatically created at best, or at least to have a standard way to define it, per application (say, in ejb-jar/META-INF)
this question and this blogpost show us how to do it in an application server specific way. This surely works, but:
I want to use the #MessageDriven annotation
I want the setting not to be global for the application server
I want the setting to be portable
It seems impossible to do this, with JavaEE 5 at least.
I'm just getting started with JPA, creating stateless session beans from the JPA entities, then accessing the beans through a web service. While I have a lot of experience developing database backed web services "the old way", I have some questions about what's going on behind the scenes with this new "annotation driven approach".
What I see is, NetBeans sort of directs you to build applications in this manner though their wizards.
Create an Enterprise Application with EJB and Web Application modules.
Create Entity classes. I created mine from an existing database.
Create session beans from the entity class.
Create Web services from the session bean.
It all looks pretty simple, but what's going on behind the scenes? Specifically:
I see that the web service (created with the #WebService annotation) references my stateless session bean (using the #EJB reference).
What happens here? Does it just grab an instance of the EJB from the application server's EJB pool?
Nevermind. I was thinking of an instance where there was more than 1 table - meaning more than 1 type of Entity class and more than 1 type of EJB. I was looking at the web service and just seeing the #EJB reference and didn't understand who it was getting the bean type from that annotation. Just below that however, it the reference to the local bean interface - so that's that.
If there is more than 1 type of EJB deployed to the server, how does it know which one to grab?
The EJB is defined via the #Stateless and #Local annotations. The bean implementation references an EnityManager via the #PersistenceContext annotation.
Where is the jndi lookup to the database done (maybe in the persistence.xml file)?
Do all of the EJBs share a common EntityManager (assuming the EntityManager is thread safe)? If not, I know that the EnityManager utilizes a second level cache to help reduce trips to the database, are these caches somehow kept in sync?
I know this is a lot of questions, but they're all sort of related and there seem to be a lot of complicated concepts for something that's so easy to build through the wizards. I want to make sure I understand what's all going on here.
Thanks in advance!
What happens here? Does it just grab an instance of the EJB from the application server's EJB pool?
A JAX-WS web component endpoint (as opposed to a JAX-WS EJB endpoint) follows the typical servlet threading model, which means that typically there is one instance that is executed concurrently for each client. JAX-WS implementations are free to leverage pools of bean instances to handle a request in a fashion similar to stateless session EJB components. (source: Developing Applications for the JavaTM EE Platform FJ-310).
In all cases, it is fine to inject/look-up stateless beans because the container guarantees that the beans will always be thread safe. In affect, the container automatically serializes clients calls but uses instance pooling to make sure you still get concurrency benefits.
If there is more than 1 EJB deployed to the server, how does it know which one to grab?
Hmm... I didn't get this one. Can you clarify what you mean exactly? Why would there be any ambiguity?
Where is the jndi lookup to the database done (maybe in the persistence.xml file)?
In a Java EE environment, you specify your data source in a <jta-data-source> element in each persistence unit of the persistence.xml file (which can contain several persistence units) and the data source will be obtained by the EntityManager (only when needed, i.e. only if a data access is really needed).
Do all of the EJBs share a common EntityManager?
No. The EntityManager is a non-thread-safe object that should be used once, for a single business process, a single unit of work, and then discarded. In a Java EE environment using EJB 3, the default pattern is "entitymanager-per-request". A request from the client is send to the EJB 3 persistence layer, a new EntityManager is opened, and all database operations are executed in this unit of work. Once the work has been completed (and the response for the client has been prepared), the persistence context is flushed and closed, as well as the entity manager object. (source: Chapter 4. Transactions and Concurrency).