I deployed a global module with remote ejbs defined, but I can't access them from deployed applications.
Here is the interface:
#Remote
public interface ICryptoAPI..
and bean definition:
#Stateless
public class CryptoAPI implements ICryptoAPI ...
How can I find jndi name of the ejbs deployed, since default #Ejb cannot find bean? Just to mention, /subsystem=naming:jndi-view() from jboss-cli doesn't print anything about deployed module and there are no errors in wildfly log.
Maybe, it is not possible to define injectable ejbs in global modules?
The portable JNDI name, an EJB is bound to, depends on how beans are deployed and some configurations (e.g. deployment descriptors).
In addition to the portable JNDI name, JBoss provides access from a remote VM within the java:jboss/exported namespace.
For your convenience, JBoss' default logging shows the JNDI names, an EJB is bound to, on console and in the server logfile upon deployment. The logger is org.jboss.as.ejb3.deployment on INFO level.
Example:
12:00:00,000 INFO [org.jboss.as.ejb3.deployment] (MSC service thread 1-6) WFLYEJB0473: JNDI bindings for session bean named 'MyBean' in deployment unit 'subdeployment "my-beans.jar" of deployment "my-app.ear"' are as follows:
java:global/my-app/my-beans/MyBean!my.package.MyBeanRemote
java:app/my-beans/MyBean!my.package.MyBeanRemote
java:module/MyBean!my.package.MyBeanRemote
java:jboss/exported/my-app/my-beans/MyBean!my.package.MyBeanRemote
For accesing the EJB, you can do a manual JNDI lookup or use the #EJB annotations lookup method for injection.
Related
Background
I am going to define some JMS queues on Wildfly 20.0.1.
I can list all the defined queue with /subsystem=naming:jndi-view in jboss-cli.
Problem
In the result of /subsystem=naming:jndi-view, the JNDI names are not based on ENC (java:comp/env/~). I want to know the JNDI names used in a Java application.
Question
Is there any way to show all the JNDI names under ENC (java:comp/env/~) that available in a web application on a Wildfly server?
Note: the way that available not only for Wildfly but also other Java EE servers are more preferable.
Every EJB container that is deployed in an application server has its own personal internal registry called the Enterprise Naming Context (ENC).
Anything registered in the JNDI ENC can be looked up by name under the java:comp/ env context.
InitialContext ctx = new InitialContext();
NamingEnumeration<NameClassPair> list = ctx.list("java:comp/env/");
while (list.hasMore()) {
System.out.println(list.next().getName());
}
Obs.: The JNDI name resolves to a different context depending on where you invoke the lookup. For example, if you invoke jndi.lookup(“java:comp/env”) within the MyEJB, you will get that EJB container’s ENC. If you do the same within another EJB, you will get a different ENC registry specific to that bean.
While deploying EAR via HUDSON to Websphere 9.0
WebSphere throws following error
ADMA0205E: A validation error occurred in task Binding enterprise Bean to JNDI names. Java Naming and Directory Interface (JNDI) names for the bean and its local/remote home are both specified for enterprise bean XXXXX in module XXXX. You can provide either JNDI name for the bean or JNDI names for its local/remote home. But you cannot provide both.
can you please let me know if am doing anything wrong.
This normally indicates that the application has a problem in the ibm-ejb-jar-bnd.xml file. Specifically, for the bean XXXXX in module XXXX, there is a binding configuration that specifies both the simple-binding-name attribute and one of the following : local-home-binding-name or remote-home-binding-name attributes, or the <interface> element. simple-binding-name is not compatible with these other attributes/element.
Information about the format of the ibm-ejb-jar-bnd.xml file is available here:
https://www.ibm.com/support/knowledgecenter/en/SSAW57_8.5.5/com.ibm.websphere.nd.doc/ae/cejb_bindingsejbfp.html
I have created two liberty instances on my local machine. I deployed a war module which contains a remote ejb in server X and deployed another war in server Y which has to remote lookup the ejb from server X.
Below is the code to lookup the ejb from a restful webservice.
Properties p = new Properties();
p.setProperty("java.naming.provider.url", "corbaname:iiop:localhost:2809");
InitialContext context = new InitialContext (p);
context.lookup("corbaname:rir:#ejb/global/caching/CachingServiceBean!com%5c.ejb%5c.CachingService");
When I try to call the web service I get below exception
DII operation not supported by local object
P.S.
I have enabled ejbRemote feature on both the servers with different port numbers.
I changed my lookup string to "corbaloc:iiop:localhost:2809/NameService#ejb/global/caching/CachingServiceBean!com%5c.ejb%5c.CachingService" and then I get the below error
Then I changed my lookup string to "corbaname:iiop:localhost:2809/NameService#ejb/global/caching/CachingServiceBean!com%5c.ejb%5c.CachingService" and then I got the below error
After checking apache geronimo-yoko implementation on GitHub, I understood that I have to use corbaloc:iiop:localhost:2809. But still I am getting exceptions caused by
org.omg.CORBA.OBJECT_NOT_EXIST: unable to dispatch - servant or POA not found
I used the following urls with no luck:
corbaloc:iiop:localhost:2809/global/caching/CachingServiceBean!com.ejb.CachingService
corbaloc:iiop:localhost:2809/#ejb/global/caching/CachingServiceBean!com.ejb.CachingService
3.corbaloc:iiop:localhost:2809/caching/CachingServiceBean!com.ejb.CachingService
4.corbaloc:iiop:localhost:2809/ejb/global/caching/CachingServiceBean!com.ejb.CachingService
I think the problem is with the packaging. I packed my ejb in a war module.
I followed the steps described in the PDF mentioned in this page http://www.redbooks.ibm.com/redpieces/abstracts/sg248076.html and everything is working now.
I used corbaname::host:port syntax to lookup the remote ejb instead of corbaloc:iiop:host:port
After packing my ejb in an ear then it started working.
In one hand, I have a Stateless EJB Bean which implements a remote interface.
#Stateless(name = "ejbBean")
#Remote(TimedBean.class)
public class TimedBeanImpl implements TimedBean
...
On the other hand, I have a Servlet client where I need to inject this EJB bean for invoking its operations. The injection referts to a JNDI automatically generated by the server:
public class LoadTimer implements ServletContextListener {
// EAR Local Mapping - EAR Dev Mapping
// #EJB(mappedName = "java:global/appTest/appTestModuleOne-01.00.00/ejbBean")
#EJB(mappedName = "java:global/appTest-01.00.00/appTestModuleOne-01.00.00/ejbBean")
private TimedBean timedBean;
#Override
public void contextInitialized(ServletContextEvent servletcontextevent) {
...
It works.
But the fact of referencing the jndi automatically generated makes the solution highly dependent on the specific environment:
It depends on the server. For example, my local server for testing it's a JBOSS 7.1 and my dev server it's a JBOSS EAP 6.2, and the automatically generated jndi's are different.
It depends on the packaging. Not is the same refers to the ejbBean deploying in a EAR file than in a WAR file.
And it depends on the version of artifacts. More changes.
I want, if possible, is to specify a unique name for the bean can be referred to the servlet in each server, for each version and packaging, in order not to have to be making continuous changes in development and avoid errors in deployments.
Greetings!
You can use <application-name> in application.xml and <module-name> in your module descriptor (web.xml or ejb-jar.xml) to mitigate the hardcoded version numbers. (Note that as of EE 6, you should use #EJB(lookup="...") rather mappedName.) The spec also requires that your application server give you an option to override the lookup name of the #EJB reference while deploying the application, so it should not matter what is hardcoded in your application at development time.
My environment is Weblogic 10.3.5 on Solaris box. EJB is version 3 and there is anotation in the Bean class. Sorry for the confusion as the code is new to me and they also have deployment descriptor to generate ejb2 client code for another client to call, so it's not straigtforward.
I have a stateless session bean deployed to a cluster which has 2 server members say they are member1 and member2.
The session bean is deployed as clusterable as this is in the anotation:
homeIsClusterable = Constants.Bool.TRUE
This is how my Stand alone Java client lookup and call the EJB methods:
private void testBean(){
bean.methodA();
bean.methodB();
}
In the provider URL I ONLY specify the provider URL to ONE server member:
env.put(Context.PROVIDER_URL, "t3://member1:7005");
env.lookup("remote#the.bean.qulified.remoteinterface")
The Jndi name above is using the "mapped name + qualified remote interface class name", the mapped name is defined in the anotation.
Now the problem is, I found out, bean.methodA() got invoked in member1, and methodB() got invoked on member2, I found this from the logs of each server member. So it's always like this, member1 log will only show debug information from methodA, and member2 will only show debug information from methodB.
So here is my conceptual question - is this possible at all ? Are the above 2 methods supposed to be called on member1 only ? I know it's possible when you lookup through home interface you could possibly get a bean from either server, but in this case the ejb3 lookup is not going through the home interface(like in ejb2 we get a home and then call create method) but directly getting a remote object.
This caused issue as our methodB has a dependancy on methodA(methodA is doing some cleanup job, and then method re-initialize the cache), we need to do this on each cluster member.
This is just extra info but please focus on the above question from a concept perspective.
From the documentation:
When home-is-clusterable is True, the EJB can be deployed from multiple WebLogic Servers in a cluster. Calls to the home stub are load-balanced between the servers on which this bean is deployed, and if a server hosting the bean is unreachable, the call automatically fails over to another server hosting the bean.
I believe this is the case even when you explicitly only connect to a single member. This has some pretty good info in the Replica-Aware Home section:
http://www.informit.com/articles/article.aspx?p=101737&seqNum=8
It's more or less the whole point of clustering... a cluster appears as if it's a single server instance to a client.