I am having a strange issue regarding OpenEJB and integration tests.
I am using Open EJB 4.5.1, JUnit 4.10 and Maven3 with surefire plugin 2.13
I start OpenEJB from my test doing:
InitialContext ic = new InitialContext();
It works (apparently) fine and deploys the EJB (CentrosBeanFacade) correctly, but after that it tries to bind it again, which causes the server to fail.
These are the interesting log parts:
First time --> [OK] :
DEBUG - bound ejb at name: openejb/Deployment/CentrosBeanFacade/com.csc.health.xhis.arqtest.api.CentrosLogica, ref: org.apache.openejb.core.ivm.naming.BusinessRemoteReference#6506fe2b
DEBUG - bound ejb at name: openejb/Deployment/CentrosBeanFacade/com.csc.health.xhis.arqtest.api.CentrosLogica!Remote, ref: org.apache.openejb.core.ivm.naming.BusinessRemoteReference#6506fe2b
INFO - Jndi(name=CentrosBeanFacade) --> Ejb(deployment-id=CentrosBeanFacade)
INFO - Jndi(name=global/classpath.ear/test-ejb/CentrosBeanFacade!com.csc.health.xhis.arqtest.api.CentrosLogica) --> Ejb(deployment-id=CentrosBeanFacade)
INFO - Jndi(name=global/classpath.ear/test-ejb/CentrosBeanFacade) --> Ejb(deployment-id=CentrosBeanFacade)
But then it tries to deploy it a second time.
DEBUG - failed to bind ejb at name: openejb/Deployment/CentrosBeanFacade/com.csc.health.xhis.arqtest.api.CentrosLogica, ref: org.apache.openejb.core.ivm.naming.BusinessRemoteReference#32f00d9a
ERROR - Jndi name could not be bound; it may be taken by another ejb. Jndi(name=openejb/Deployment/CentrosBeanFacade/com.csc.health.xhis.arqtest.api.CentrosLogica!Remote)
The internal BusinessRemoteReference from EJB is a different object than the first time, so it is trying to deploy it a second time. But I have checked the classpath and the EJB is not included twice. If I execute a similar procedure but from a plain Java class, it also fails.
Any clues?
Related
I am trying to deploy a JSF portlet into a Liferay portal 6.2 running on top of a JBoss EAP 6.4, with OpenJDK 8. The portlet is deployed as a WAR file, but invokes some methods of an EJB through a remote interface. The EJB is deployed as an EAR file directly on JBoss.
On my developing machine it is working fine. But in a test machine it is not. There are exactly the same WAR and EAR files, the standalone.xml setup is almost the same for both machines, and also the JBoss modules are the same.
The stacktrace printed in the log is the following:
JBWEB000236: Servlet.service() for servlet Adminis Servlet threw exception: javax.portlet.faces.BridgeException: javax.faces.FacesException
at com.liferay.faces.bridge.BridgePhaseRenderImpl.execute(BridgePhaseRenderImpl.java:91) [liferay-faces-bridge-impl-3.2.4-ga5.jar:3.2.4-ga5 (Ephesus / Feb 15, 2014 AD)]
at com.liferay.faces.bridge.BridgeImpl.doFacesRequest(BridgeImpl.java:112) [liferay-faces-bridge-impl-3.2.4-ga5.jar:3.2.4-ga5 (Ephesus / Feb 15, 2014 AD)]
...
at java.lang.Thread.run(Thread.java:745) [rt.jar:1.8.0_121]
Caused by: javax.faces.FacesException
at com.sun.faces.context.ExceptionHandlerImpl.handle(ExceptionHandlerImpl.java:139) [jsf-impl-2.1.28.redhat-8.jar:2.1.28.redhat-8]
at org.icefaces.impl.application.ExtendedExceptionHandler.handle(ExtendedExceptionHandler.java:113) [icefaces-3.3.0.jar:]
... 194 more
Caused by: java.util.NoSuchElementException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1439) [rt.jar:1.8.0_121]
at java.util.HashMap$KeyIterator.next(HashMap.java:1461) [rt.jar:1.8.0_121]
at org.jboss.ejb.client.EJBClientContext.getEJBReceiver(EJBClientContext.java:725) [jboss-ejb-client-1.0.30.Final-redhat-1.jar:1.0.30.Final-redhat-1]
at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:146) [jboss-ejb-client-1.0.30.Final-redhat-1.jar:1.0.30.Final-redhat-1]
...
at com.sun.proxy.$Proxy459.obtenerUsuarioPorCodigo(Unknown Source)
at com.sofis.adminis.delegates.PermisosDelegate.obtenerUsuarioPorCodigo(PermisosDelegate.java:450) [adminis-delegate-1.0.jar:]
at com.sofis.security.web.UsuariosSessionBeanWeb.autenticar(UsuariosSessionBeanWeb.java:1927) [classes:]
at com.sofis.security.web.listeners.SofisAutologinLiferayPhaseListener.afterPhase(SofisAutologinLiferayPhaseListener.java:54) [classes:]
at com.sun.faces.lifecycle.Phase.handleAfterPhase(Phase.java:189) [jsf-impl-2.1.28.redhat-8.jar:2.1.28.redhat-8]
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:107) [jsf-impl-2.1.28.redhat-8.jar:2.1.28.redhat-8]
... 198 more
I rised the log level to "org.jboss.ejb.client" and now I see two interesting messages just before the stactrace:
22:13:16,684 DEBUG [org.jboss.ejb.client.EJBClientContext] (ajp-/0.0.0.0:8009-5) org.jboss.as.ejb3.remote.LocalEJBReceiverPreferringDeploymentNodeSelector#4bc9113e deployment node selector selected node for appname=SS-ADMINIS-ear-1.0,modulename=SS-ADMINIS-MAVEN-EJB-1.0,distinctname=
22:13:16,687 DEBUG [org.jboss.ejb.client.EJBClientContext] (ajp-/0.0.0.0:8009-5) Selected node doesn't belong to eligible receivers. Continuing with a random eligible receiver
Note that there is no node name in both messages (two blanks before "node").
In my developing machine, where it works, the first message does include a node name, and the second message does not appear:
18:56:37,902 DEBUG [org.jboss.ejb.client.EJBClientContext] (http-/0.0.0.0:8080-2) org.jboss.as.ejb3.remote.LocalEJBReceiverPreferringDeploymentNodeSelector#6db73304 deployment node selector selected spio node for appname=SS-ADMINIS-ear-1.0,modulename=SS-ADMINIS-MAVEN-EJB-1.0,distinctname=
The only diference is that in my machine I am going directly with the browser to the server ([Browser] -- HTTP --> [JBoss]) while in the testing machine I go through a load balancer ([Browser] -- HTTP --> [Apache] -- AJP --> [JBoss]). That is reflected in the messages (ajp-/0.0.0.0 vs http-/0.0.0.0).
The exception is thrown when I try to invoke a method from the EJB through the remote interface. The reference to the local stub is gotten by means of a lookup, and the result is not null. There are no errors at deploy and the lookup does not throw an error neither.
What can be happening or what am I missing?
A friend of mine found the solution.
Something a did't say is that the testing machine was in fact a docker container. And it seems that there is a bug in JBoss with docker making the former to not read the hostname to pick a node name, so de node name when it starts is empty. So the message above a empty name node being selected is shown, and then the error.
The workaround is to specify a node name with the -Djboss.node.name parameter to JBoss. I put that setting in the standalone.conf, restarted the JBoss and it worked fine. Now, the first message shows the name I specified, and the second message does not appear, nor the exception.
I already have a integration-test phase, when I ran the selenium tests. I also want to run some unit tests in this phase, because the app is too much complex and have a lot of dependencies between his modules (a hell), so, after a week fighting against OpenEJB and Arquillian, I believe that this would be easier.
The thing is: how do I made it work?
I have the instance already running, if I instantiate an InitialContext and try to lookup some bean, I got an exception telling me that I have not set the java.naming.initial.factory, and I don't know what to put in there.
I'm also complaining about the annotated beans.
Suppose a Bean like this:
#Stateless
public class ABeanImpl implements ABean {
#EJB
private BBean;
}
Will the container automatically get right the BBean?
Thanks in advance
How to connect to JBoss 7.1 remote JNDI:
Here is the code snippet that I use for JBoss 7.1:
Properties props = new Properties();
String JBOSS_CONTEXT = "org.jboss.naming.remote.client.InitialContextFactory";
props.put("jboss.naming.client.ejb.context", true);
props.put(Context.INITIAL_CONTEXT_FACTORY, JBOSS_CONTEXT);
props.put(Context.PROVIDER_URL, "remote://localhost:4447");
props.put(Context.SECURITY_PRINCIPAL, "jboss");
props.put(Context.SECURITY_CREDENTIALS, "jboss123");
InitialContext ctx = new InitialContext(props);
Resolution of ambiguous ejb references:
According to JBoss EJB 3 reference, if at any level of your EJB environment (EJB/EAR/Server) are duplicates in used interfaces, exception will be thrown during resolution of injected beans.
Based on above, if you have got a reference to EJB bean which interface:
has two implementations in your EJB module (JAR/WAR) - exception will be thrown
has two implementations in your application (other EJB JAR's in same EAR) - exception will be thrown
has two implementations, one in module with bean ABeanImpl, second somewhere else - implemetation from current module is used.
I'm using camel 2.11-SNAPSHOT in an ear which is running on JBoss AS 7.1.
When deploying the app and while the routes are being constucted (in a #Singleton #Startup bean, using an #Injected CdiCamelContext) i get a lot of warnings (ca. 30) like this in my server log:
2013-03-20 16:40:55,153 WARNING [org.apache.deltaspike.core.api.provider.BeanManagerProvider] (MSC service thread 1-2) When using the BeanManager to retrieve Beans before the Container is started, non-portable behaviour results!
and after the the context has been started i get this WARNINGs:
2013-03-20 16:40:56,339 WARNING [org.apache.deltaspike.core.api.provider.BeanManagerProvider] (Camel (camel-2) thread #1 - file:///tmp/exchange/tmobile/in) When using the BeanManager to retrieve Beans before the Container is started, non-portable behaviour results!
What does it mean? I couldn't find anything useful on google. Is it a bug? Did i configure camel wrong?
It is simply a warning from Apache Deltaspike that the bean manager was accessed before the container was booted. It seems Camel's integration with CDI uses some non-portable features, but assuming that they know what they're doing, it could be nothing.
My application is deployed on JBoss 7.1 (standalone).
I am getting an exception on the following line:
MBeanServerConnection server = MBeanServerLocator.locateJBoss();
The exception is:
JBoss: java.lang.IllegalStateException: No 'jboss' MBeanServer found!
That code above worked fine when the app was deployed on JBoss 5.
From what I was reading online, the code is supposed to work only when it's called from the same JVM in which the MBeanServer was created. Otherwise it's a remote call and I have to use JNDI. But is it not a local call (same JVM - i.e. the JBoss JVM)? How did it work on JBoss 5 then?
How do I make it work on JBoss 7.1 standalone, without changing this specific code?
Here is the solution:
https://community.jboss.org/thread/221708
Quote:
Above problem is dueto locateJboss implementation that is compatible with older version of Jboss. The MBeanServer used by JBoss 7 (by default) is the platform MBeanServer. The class name iscom.sun.jmx.mbeanserver.JmxMBeanServer and the default domain is DefaultDomain. Accordingly, you can simply use:
java.lang.management.ManagementFactory.getPlatformMBeanServer()
Alternatively:
for(MBeanServer server: javax.management.MBeanServerFactory.findMBeanServer(null)) {
if("DefaultDomain".equals(server.getDefaultDomain())) return server;
}
throw new Exception("Failed to locate MBeanServer");
On another note, jboss.system:type=ServerInfo object name doesn't work in AS 7.1 I had to use JVM specific parameters to nail down to MBean attributes. 'java.lang:type=Memory' and attribute as 'HeapMemoryUsage'.
I am new in the world of EJB 3.1 and trying to get some basics with the JBoss Application Server 7.1.
At the moment I am stuck at a - really basic - problem. When a bean on the server wants to use another bean I need to use the InitialContext.lookup() method. If I look in the literature I found calls like:
TheBean = (<Interface>) new InitialContext().lookup("<NameOfTheBean>/local");
But this call doesn’t work for me. Every time I get an error like this:
javax.ejb.EJBException: javax.naming.NameNotFoundException
After hours of looking for a solution I found code examples which use another call, something like this:
TheBean = (<Interface>) new InitialContext().lookup("ejb:/<Package>//<NameOfTheBean>!<Package>.<Interface>");
Well this solution works for me but the question is why? Does somebody know why the first call produces exceptions while the second one works fine?
Thanks a lot!
Why? Different versions of JBoss deploys beans with differently default names in JNDI namespace.
ctx.lookup("BeanName/local")
was right for the JBoss 4.x.x and higher but not for JBoss v7.
You can see in you server.log of JB7 how your beans mapped to JNDI names,
for example (see java:/jboss/exported/... and how it correspond to your second successive call):
13:57:05,550 INFO [org.jboss.as.ejb3.deployment.processors.EjbJndiBindingsDeploymentUnitProcessor] (MSC service thread 1-4) JNDI bindings for session bean named ProductionHistoryBean in deployment unit deployment "navi-ejb3.jar" are as follows:
java:global/navi-ejb3/ProductionHistoryBean!navi.ejb3.production.history
.ProductionHistoryRemote
java:app/navi-ejb3/ProductionHistoryBean!navi.ejb3.production.history.Pr
oductionHistoryRemote
java:module/ProductionHistoryBean!navi.ejb3.production.history.Productio
nHistoryRemote
java:jboss/exported/navi-ejb3/ProductionHistoryBean!navi.ejb3.production
.history.ProductionHistoryRemote
java:global/navi-ejb3/ProductionHistoryBean
java:app/navi-ejb3/ProductionHistoryBean
java:module/ProductionHistoryBean