I am using Glassfish server. It seems that the #LocalBean is getting initialized at server startup. For other beans they are correctly initialized on look up. Is this the correct behaviour for LocalBean ?
There is no rule saying that #LocalBean should be eagerly initialized and others should not. It's left to the container provider to decide when particular bean should be initialized.
The only case you have control over when bean is initialized is to use #Singleton EJB with #Startup annotation. This will force container provider to create an instance of the singleton bean during server startup. This is a good place to put your initialization logic within.
The behavior you've observed might be correct in case of Glassfish but I would not relay on it because other container providers might choose different approach.
Related
We migrated from Jboss EAP 5 to EAP 6 in our development environment.
I now see the following in my JBOSS logs. I am trying to understand how this binding happens. I have read JBOSS docs on JNDI namespace binding. Still I am not totally clear how it works. Here is my log.
java:global/customerCare/services/UserDaoImpl!com.example.services.UserDao
java:app/services/UserDaoImpl!com.example.services.UserDao
java:module/UserDaoImpl!com.services.UserDao
java:global/customerCare/services/UserDaoImpl
java:app/services/UserDaoImpl
java:module/UserDaoImpl
Here are my EJBs
#Local
public interface UserDao {
public static final String JNDI_NAME = "java:global/customCare/services/UserDaoImpl";
//interface methods here
}
#Stateless
public class UserDaoImpl implements UserDao {
// implement methods
}
My doubts are:
I explicitly had JNDI binding to be java:global/customCare/services/UserDaoImpl in my UserDao interface.
Then why do I see I binding for others such as app and module.
what is the difference between app and module? when would binding to these components be needed? some example here to illustrate will be very helpful
The last three lines of log show binding to UserDaoImpl. Is it something that JBoss does without I ask it to bind? ( I set only UserDao but not UserDaoImpl for JNDI binding).
I am a bit illiterate on JNDI Namespace binding. Reading docs helped me but not to great extent.
Thanks
I can answer doubt 2:
All the names are the same thing but with different contexts.
The global name is a full JNDI context that is used to bind globally, ie. from a client or from another EAR file
The module name can be used to bind within the same application, ie different EJBs within the same EAR
The local name is used to bind locally, ie within an jar or war.
It is slightly more efficient to use the shorter names to bind locally than specifying a full global name each time.
From what I have seen JBoss EAP 6 will always list the three / six names for every enterprise bean during deployment. It is intended to help you as a developer identify the JNDI name(s) for the bean.
I like to know what is the main difference between EJB #EJB and #Resource annotation? In which case we have to go for #EJB and #resource
Specification states, regarding #EJB:
The Bean Provider uses the EJB annotation to annotate a field or setter
property method of the bean class as a target for the injection of an
EJB reference. The reference may be to a session bean’s business
interface or to the local home interface or remote home interface of a
session bean or entity bean.
regarding #Resource(section 16.2.2):
A field or method of a bean class may be annotated to request that an
entry from the bean’s environment be injected. Any of the types of
resources or other environment entries described in this chapter may
be injected.
Mentioned entries include: EJB reference, web service reference, resource manager connection factory reference, message destination reference, unit reference, persistence context reference, UserTransaction, CORBA ORB object, TimerService, EJBContext object
I've been working on a web application, deployed on Tomcat 7, which use EclipseLink JPA to handle the persistence layer.
Everything works fine in a test environment but we're having serious issues in the production environment due to a firewall cutting killing inactive connections. Basically if a connection is inactive for a while a firewall the sits between the Tomcat server and the DB server kill it, with the result of leaving "stale" connections in the pool.
The next time that connection is used the code never returns, until it gets a "Connection timed out" SQLException (full ex.getMessage() below).
EL Fine]: 2012-07-13
18:24:39.479--ServerSession(309463268)--Connection(69352859)--Thread(Thread[http-bio-8080-exec-5,5,main])--
MY QUERY REPLACED TO POST IT TO SO [EL Config]: 2012-07-13
18:40:10.229--ServerSession(309463268)--Connection(69352859)--Thread(Thread[http-bio-8080-exec-5,5,main])--disconnect
[EL Info]: 2012-07-13
18:40:10.23--UnitOfWork(1062365884)--Thread(Thread[http-bio-8080-exec-5,5,main])--Communication
failure detected when attempting to perform read query outside of a
transaction. Attempting to retry query. Error was: Exception
[EclipseLink-4002] (Eclipse Persistence Services -
2.3.0.v20110604-r9504): org.eclipse.persistence.exceptions.DatabaseException Internal
Exception: java.sql.SQLException: Eccezione IO: Connection timed out
I already tried several configuration in the persistence.xml, but since I have no access to the firewall configuration I had no luck with these methods. I also tried to use setCheckConnections()
ConnectionPool cp = ((JpaEntityManager)em).getServerSession().getDefaultConnectionPool();
cp.setCheckConnections();
cp.releaseConnection(cp.acquireConnection());
I managed to solve the issue in a test script using testOnBorrow, testWhileIdle and other features that are avalaible from DBCP Apache Commons. I'd like to know how to override the EclipseLink internal connection pool to use a custom connection pool so that I can provide an already configured pool, based on DBCP rather than just configuring the internal one using persistence.xml.
I know I should provide a SessionCustomizer, I'm uncertain which one is the correct pattern to use. Basically I would like to preserve the performance of DBCP in a JPA-like way.
I'm deploying on Tomcat 7, I know that if I switch to GF I won't have this problem, but for a matter of consistency with other webapp on the same server I'd prefere to stay on Tomcat.
What you want is definitely possible, but you might be hitting the limits of the "do it yourself" approach.
This is one of the more difficult things to explain, but there are effectively two ways to configure your EntityManagerFactory. The "do it yourself" approach and the "container" approach.
When you call Persistence.createEntityManagerFactory it eventually delegates to this method of the PersistenceProvider interface implemented by EclipseLink:
EntityManagerFactory createEntityManagerFactory(String emName, Map map)
The deal here is EclipseLink will then take it upon itself to do all the work, including its own connection creation and handling. This is the "do it yourself" approach. I don't know EclipseLink well enough to know if there is a way to feed it connections using this approach. After two days on Stackoverflow it doesn't seem like anyone else has that info either.
So here is why this "works in GF". When you let the container create the EntityManagerFactory for you by having it injected or looking it up, the container uses a different method on the PersistenceProvider interface implemented by EclipseLink:
EntityManagerFactory createContainerEntityManagerFactory(PersistenceUnitInfo info, Map map)
The long and short of it is that this PersistenceUnitInfo is an interface that the container implements and has these two very key methods on it:
public DataSource getJtaDataSource();
public DataSource getNonJtaDataSource();
With this mode EclipseLink will not try to do its own connection handling and will simply call these methods to get the DataSource from the container. This is really what you need.
There are two possible approaches you could take to solving this:
You could attempt to instantiate the EclipseLink PersistenceProvider implementation yourself and call the createContainerEntityManagerFactory method passing in your own implementation of the PersistenceUnitInfo interface and feed the DBCP configured DataSource instances into EclipseLink that way. You would need to parse the persistence.xml file yourself and feed that data in through the PersistenceUnitInfo. As well EclipseLink might also expect a TransactionManager, in which case you'll be stuck unless you hunt down a TransactionManager you can add to Tomcat.
You could use the Java EE 6 certified version of Tomcat, TomEE. DataSources are configured in the tomee.xml, created using DBCP with full support for all the options you need, and passed to the PersistenceProvider using the described createContainerEntityManagerFactory call. You then get the EntityManagerFactory injected via #PersistenceUnit or look it up.
If you do attempt to use TomEE, make sure your persistence.xml is updated to explicitly set transaction-type="RESOURCE_LOCAL" because the default is JTA. Even though it's non-compliant to use JTA with the Persistence.createEntityManagerFactory approach, there aren't any persistence providers that will complain and let you know you're doing something wrong, they treat it as RESOURCE_LOCAL ignoring the schema. So when you go to port your app to an actual certified server, it blows up.
Another note on TomEE is that in the current release, you'll have to put your EclipseLink libs in the <tomcat>/lib/ directory. This is fixed in trunk, just not released yet.
I'm not sure how useful these slides will be without the explanation that goes along with them, but the second part of this presentation is a deep dive into how container-managed EntityManager's work, specifically with regards to connection handling and transactions. You can ignore the transaction part as you aren't using them and already have an in production you're not likely to dramatically change, but it might be interesting for future development.
Best of luck!
I need to be able to circumvent the whole deployer malarkey and programmatically register/unregister (dependency-less) POJOs as services in JBoss.
Currently I'm dynamically creating an MBean interface and registering this with the JBoss MBeanServer, and then registering local/remote with Jndi.
This works ok (I can have a standard service from a vanilla SAR reference one of these service POJOs with the #EJB annotation) - however the container seems to leaves stale references behind as after calling unbind() and unregisterMBean().
Obviously I'm missing something by not dealing with the container in a way it expects, but what am I missing? Or is there an easier way (can't see much in the way of an API)?
thanks.
I have two ear applications (EJB 3.0) deployed on Jboss 5.1. SLSB from application A calls remote SLSB from application B via #EJB annotation.
Everything works fine, until I redeploy application B. Then the bean from A application tries to call the one from B and its reference turns to be null.
I suppose that SLSBs are pooled and references are injected on creation time, and after redeployment those proxies are not refreshed somehow.
How can I cope with that? Is it ok to put an interceptor on that bean and check if all annotated references are not null?
If the application is redeployed/undeployed or there is network failure, the proxy objects are invalidated.
You can use ServiceLocator pattern for caching the references of the remote objects. You can remove & again re-create them with JNDI lookup in case of failure.
Else, instead of using #EJB to inject remote bean, you have to manually lookup each time which is resource consuming, but former is much better approach.