Java heap retention due huge numbers of org.jboss.ejb.client.EJBClientContext
Environment
- JBoss Enterprise Application Platform (EAP) 6
Issue
- Poor GC performance.
- GC full collections are not able to reclaim old generation space.
- Heap analysis shows 1+ million org.jboss.ejb.client.EJBClientContext
- log file showing this error:
javax.naming.NamingException: No provider URL configured for connection
at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateCachedNamingStore(InitialContextFactory.java:196)
at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateCachedNamingStore(InitialContextFactory.java:196)
at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateNamingStore(InitialContextFactory.java:171)
at org.jboss.naming.remote.client.InitialContextFactory.getOrCreateNamingStore(InitialContextFactory.java:171)
at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:146)
at org.jboss.naming.remote.client.InitialContextFactory.getInitialContext(InitialContextFactory.java:146)
at org.jboss.as.naming.InitialContext.getDefaultInitCtx(InitialContext.java:122)
at org.jboss.as.naming.InitialContext.getDefaultInitCtx(InitialContext.java:122)
at org.jboss.as.naming.InitialContext.init(InitialContext.java:107)
at org.jboss.as.naming.InitialContext.init(InitialContext.java:107)
at javax.naming.ldap.InitialLdapContext.<init>(InitialLdapContext.java:154)
Resolution
When the EJB client application and EJB are running in the same JVM, you should not use Remote Naming or any other remote EJB configuration. The EJB client should just do new InitialContext().lookup(...) or @EJB to inject the EJB proxy.
Root Cause
Remote Naming should have java.naming.provider.url set. It cannot be left empty and it cannot be null. If the EJB is in the same JVM as the client, then you should just use new InitialContext().lookup(...)
So, for an EJB client application using code like this below, if providerUrl is null, it should not be setting these other properties.
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
env.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
if(providerUrl != null)
env.put("java.naming.provider.url", providerUrl);
env.put("jboss.naming.client.ejb.context", "true");
If providerUrl is null, it should be something like:
Context ctx = null;
if(providerUrl == null) {
ctx = new InitialContext();
} else {
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
env.put("java.naming.factory.initial", "org.jboss.naming.remote.client.InitialContextFactory");
env.put("java.naming.provider.url", providerUrl);
env.put("jboss.naming.client.ejb.context", "true");
ctx = new InitialContext(env);
}
This solution is part of Red Hat’s fast-track publication program, providing a huge library of solutions that Red Hat engineers have created while supporting our customers. To give you the knowledge you need the instant it becomes available, these articles may be presented in a raw and unedited form.