-
1. Re: How to call a remote EJB without a property file?
jaikiran Jan 12, 2012 5:08 AM (in response to bernd.koecke)The EJB client code does need to know about the connection information, so some kind of configuration is required. We have had some feedback around this and we have changed the code to allow the configurations to come from any source. By default we use the properties file, but you can implement your own logic to provide those configurations. These changes aren't yet merged upstream (since we are implementing some clustering support around this), but will be available upstream soon.
-
2. Re: How to call a remote EJB without a property file?
prasad.deshpande Jan 12, 2012 5:12 AM (in response to bernd.koecke)Bernd Koecke wrote:
when a client wants to call remote EJBs on more than one JBoss instance (7.1.CR1) it needs a jboss-ejb-client.properties file with
the routing information, on which JBoss the bean is deployed. This file must be changed and the client restarted, when any of these
endpoints changed. Is there a possibility to setup the information from the properties file by code?
This is exactly a reason for which https://issues.jboss.org/browse/EJBCLIENT-12 is raise & is under development.
I see some posts here which look similar and that it should be possible, but 7.1.CR1 uses still the properties file.
This issue is addressed by EJBClient API which is not yet published, if you wait for few more days, development on this one should be finished & hopefully should be in nightly builds for testing before AS7.1 final release.
Current proposal is to pass properties that you'd normally specify in jboss-ejb-client.properties & then initiate the remote receivers. Once it's in nightly build (which I'm waiting for myself ) I might be able to provide you exact way to pass properties programatically so that you won't need jboss-ejb-client.properties file.
-
3. Re: How to call a remote EJB without a property file?
bernd.koecke Jan 12, 2012 5:33 AM (in response to prasad.deshpande)These are very good news, thanks a lot! I haven't seen this issue. The line "EJBClient.setSelector(..." is exactly what I thought of and it its nice see that my idea was not wrong. This saves me a lot of time when there is something ready to use. If you need someone to test and play around with it, I would be happy to help .
-
4. Re: How to call a remote EJB without a property file?
bernd.koecke Jan 12, 2012 5:33 AM (in response to prasad.deshpande)These are very good news, thanks a lot! I haven't seen this issue. The line "EJBClient.setSelector(..." is exactly what I thought of and it its nice see that my idea was not wrong. This saves me a lot of time when there is something ready to use. If you need someone to test and play around with it, I would be happy to help .
-
5. Re: How to call a remote EJB without a property file?
jaikiran Jan 18, 2012 12:19 AM (in response to bernd.koecke)1 of 1 people found this helpfulI'll write up a more detailed documentation soon. But as a quick overview, the current AS7 upstream has been upgraded to 1.0.0.Beta12 of ejb-client library which is much more flexible for configuring the client context. By default we use the jboss-ejb-client.properties for the configurations, but with this latest version we can now accept the configurations from any source (not just properties file). The configuration comes from a https://github.com/jbossas/jboss-ejb-client/blob/master/src/main/java/org/jboss/ejb/client/EJBClientConfiguration.java.
If a user application wants to use a different approach for configuring the EJB client context, then the typical approach would look like:
// Create a EJB client configuration final EJBClientConfiguration ejbClientConfiguration = .... // somehow create the EJBClientConfiguration depending on the user application's necessity. // EJB client context selection is based on selectors. So let's create a ConfigBasedEJBClientContextSelector which uses our EJBClientConfiguration created in previous step final ContextSelector<EJBClientContext> ejbClientContextSelector = new ConfigBasedEJBClientContextSelector(ejbClientConfiguration); // Now let's setup the EJBClientContext to use this selector final ContextSelector<EJBClientContext> previousSelector = EJBClientContext.setSelector(ejbClientContextSelector); // Now that we have setup the EJB client context (backed by our client configuration and receiver information), let's now do the JNDI lookup and invoke on the proxies final Hashtable props = new Hashtable(); // setup the ejb: namespace URL factory props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming"); // create the InitialContext final Context context = new javax.naming.InitialContext(props); final MyBeanInterface bean = ctx.lookup("ejb:appName/moduleName/distinctName/beanName!viewClassName"); // invoke on bean bean.doSomething();
If the user application wants to create the EJBClientConfiguration from a properties file (where the keys in the properties file are well-known) but wants to have more control on where the properties file comes from or how the Properties are created, then you can reuse the PropertiesBasedEJBClientConfiguration which accepts a Properties object in its constructor. You can then pass that PropertiesBasedEJBClientConfiguration to the ConfigBasedEJBClientContextSelector:
// fetch the Properties somehow (depending on user application's requirement) final Properties clientConfigProps = ... // Create a EJB client configuration from the properties final EJBClientConfiguration ejbClientConfiguration = new PropertiesBasedEJBClientConfiguration(myproperties); // EJB client context selection is based on selectors. So let's create a ConfigBasedEJBClientContextSelector which uses our EJBClientConfiguration created in previous step final ContextSelector<EJBClientContext> ejbClientContextSelector = new ConfigBasedEJBClientContextSelector(ejbClientConfiguration); // rest of the steps remain the same as explained previously
Edited by jaikiran: Minor change/fix to the example code
-
6. Re: How to call a remote EJB without a property file?
stepanov Jan 17, 2012 1:52 PM (in response to bernd.koecke)It's probably too late to ask this but it is still worth mentioning. Why have you guys decided to move from a completely JBoss-agnostic way of constructing the InitialContext (with a good choice of programmatic construction of its Properties argument with all JBoss-specific information encapsulated) to basically the same thing but with an additional JBoss API dependant step?
-
7. Re: How to call a remote EJB without a property file?
bernd.koecke Jan 18, 2012 2:58 AM (in response to jaikiran)Its cool to have an API for setting my own configuration implementation. And the JBoss specific code is not a problem in my environment. I think the above approach gives me more flexibility to implement the combination of our registry with the JNDI context. Thanks a lot for the quick solution!
-
8. Re: How to call a remote EJB without a property file?
jaikiran Jan 18, 2012 3:15 AM (in response to stepanov)Oleg Stepanov wrote:
Why have you guys decided to move from a completely JBoss-agnostic way of constructing the InitialContext (with a good choice of programmatic construction of its Properties argument with all JBoss-specific information encapsulated)
The InitialContext creation hasn't changed. It's the same and nothing JBoss specific. We register a URL factory for ejb: namespace as allowed by the JNDI APIs. The only thing that's changed is the way we communicate from the client to the server during these EJB invocations. A previous discussion is here https://community.jboss.org/message/637563#637563
-
9. Re: How to call a remote EJB without a property file?
rodakr Jan 18, 2012 7:10 AM (in response to jaikiran)Sorry but it has changed... I can't dynamically initiate InitialContext just passing Hashtable with all properties to context idependent of any implementations...
I need now jboss propriätary EJBClientConfiguration , EJBClientContext .... in my sources.
Even with commercial App Server like Oracle weblogic I can do this withous implementation dependency in my source code..
I wonder why you just don't want to use passed Hashtable to new InitialContext(props) to pass all your jboss remote properties to your jboss remote client for configuration...
Why not something like this:
//invoke on the proxies
final Hashtable props = new Hashtable();
// fill Hashtable with Jboss client properties
Properties prop = new Properties();
prop.load(new FileInputStream(new File("jboss-client.properties")));
// setup the ejb: namespace URL factory
props.put(Context.URL_PKG_PREFIXES, "org.jboss.ejb.client.naming");
// create the InitialContext
final Context context = new javax.naming.InitialContext(props);
And everything else yo do in jboss-remote implementation reading from passed Hashtable in InitialContext ( Properties extends Hashtable.. )...
-
10. Re: How to call a remote EJB without a property file?
jaikiran Jan 18, 2012 7:51 AM (in response to rodakr)Radek Rodak wrote:
I need now jboss propriätary EJBClientConfiguration , EJBClientContext .... in my sources.
No. Have you checked the https://docs.jboss.org/author/display/AS71/EJB+invocations+from+a+remote+client+using+JNDI article. That shows that you can use JNDI access with zero usage of JBoss specific APIs. You just have to have a jboss-ejb-client.properties file in the classpath. This thread is discussing advanced uses where users want to use JBoss specific APIs to have more control over the configuration.
-
11. Re: How to call a remote EJB without a property file?
rodakr Jan 18, 2012 8:06 AM (in response to jaikiran)No. My last post starts with ".. I can't dynamically initiate InitialContext"
You document says jboss-ejb-client.properties file in the classpath , this is static nothing dynamic....
I can't change value like connection URL which is configured in static jboss-ejb-client.properties file .. , dynamically without using Jboss specific API.... ( except when I start to deal with CLassloader.. )
Only purpose of this JBoss Specific API... is to change Properties for current
EJBClientContext ....
This will be not needed, if you could use Hashtable from new InitialContext to initila your Jboss specific API.
-
12. Re: How to call a remote EJB without a property file?
stepanov Jan 18, 2012 2:41 PM (in response to bernd.koecke)Radek is precisely right, that's what I meant saying that now I got to have JBoss-specific lines in my client's code just to be able to change server's IP dynamically (which is a primary use case for the majority of the remote clients). Do you guys think it can/should be fixed?
-
13. Re: How to call a remote EJB without a property file?
bernd.koecke Jan 20, 2012 11:00 AM (in response to jaikiran)I looked at the above solution and have an additional issue. Can I define the combination of bean and endpoint from the configuration for each created context?
With the old implementation it was possible to make sure that a lookup and a later call to a bean was made against one node or cluster.
I can't find an "easy" way to do that with the current implementation. I can define a number of endpoints in a dynamic way with the above API. But during the initialisation each node is asked which beans are deployed and this is stored in a map on the client side. The key is build from the JNDI lookup name, but not a cluster or node name. When a bean method is called the code uses the beans lookup name to see on which cluster it is reachable and routes the call to it. But I can't find a way to set an option on the client side for a context that only one endpoint, cluster or node, should be used as destination.
I could do it with thread local variables, but I think this is dangerous when the client is a JBossAS and the current thread comes from a pool. Its difficult to make sure that this variable is deleted when all calls are done and that there can't be a value from the previous thread user. This can happen when a developer doesn't use the right startup code before he uses the bean proxy.
I have two situations in mind when this feature would be nice. The first one is when the client is a JBossAS 7.1 with two apps, X and Y and two additional cluster A and B. X expects a bean on cluster A and Y on cluster B. Both configure their endpoints. But in reality both dependant beans are deployed on cluster B. This is a deployment bug, but no one recognizes it. The above selector is stored in a static field and is used for all calls of the client and all works well. Next Y is undeployed and the endpoint to B is removed. Now X fails, too. With a defined routing it would have been failed at the deployment of X.
Another situation is a test environment with a number of JBossAS instances where beans with the same JNDI name are deployed in a different development state on different cluster and there is another JBoss which has to call both from two indipendent deployed apps.
My two examples will not happen very often. The JNDI names will be destinct enough most of the time. Especially when I change my deployment procedure and use the optional "distinct name". May be the general feature to set an option on the context which is visible in the interceptor chain is useful for others. But may be the feature is still there and I can't see it. Then it would be nice, if you can give me a hint where to look at.
Thanks a lot and have a nice weekend
Bernd
-
14. Re: How to call a remote EJB without a property file?
rzd Jan 26, 2012 5:14 AM (in response to bernd.koecke)I think the EJB spec as well as JBoss AS are heading in a different direction than what you try to do. Just as with DI, where you don't have/want to specify the implementation any more, the new JBoss EJB stack allows you to inject (more or less) the remote business interface, and the container does the wiring to the correct implementation.
There are use cases, though, that need more fine grained control. In CDI you'd use qualifiers, which currently have no equivalent for remote EJBs.
Ask yourself: Why do I need the control over the host to be contacted if I can get that automatically? There must be a difference, if the same EJB ist deployed multiple times (if not for clustering). Can I directly express this difference, instead of agreeing that one host has these, while the other host has those properties? Documenting these requirements in the code instead of on a wiki page is a Good Thing!
These use cases exist, and taking away the option to (mis-)use the host name for that, means we need other ways to specify such qualifiers. I understand that right now you can't pass those qualifiers from the lookup/injection point to the selector, as it's (oversimplified) passed through the ejb context, which is a singleton.
For more details please see here.