Weblogic Stateless Session methods invoked from different cluster member servers - ejb

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.

Related

How to get current channel domain in pipeline based on the current application

In pipeline, I need to get channel domain to which current application is assigned.
I get current ApplicationBO instance but I haven't been able to get channel domain from it (I tried inspecting it in debugger, but I can only get domain for the application but not for the channel).
This is how currently applications and channels are assigned:
Company organization:
Channel 1
App 1 <--- Get Channel1 if in this app
Channel 2
App 2 <--- Get Channel2 if in this app
Both applications share the common cartridge which contains pipeline in which I need to get current channel
There are two options:
Call pipeline DetermineRepositories-Channel which returns you a Repository object (that is the Channel). On the Repository use object path Repository:RepositoryDomain to get the Domain. I'm not sure how big the performance implication is though..
Use object path ApplicationBO:Extension("PersistentObjectBOExtension"):PersistentObject:Domain to get the owning domain of the application itself. That will always be the channel(Domain). Because that's where storefront applications are born.
In case you need to convert the Domain object to a Repository object you can use pipelet GetRepositoryByRepositoryDomain.

websphere liberty 8.5.5.9 remote ejb lookup fails

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.

Same stateless bean in two ears

I have the same EJB module with a bean inside an EAR that is server side and an EAR that is the client side.
Can I have this situation?
Because I'm getting this error http://justpaste.it/gfs3
without understand how to fix it.
You have answer in the stack trace:
The short-form default binding 'com.demo.view.RitornaPersonaRemote'
is ambiguous because multiple beans implement the interface :
[RitornaPersonaSenzaClientEAR#RitornaPersonaSenzaClient.jar#RitornaPersona,
RitornaPersonaWebSenzaClientEAR#RitornaPersonaSenzaClient.jar#RitornaPersona].
Provide an interface specific binding or use the long-form default binding on lookup.]
If you are asking whether you may have same EJB jar in multiple project - the answer is yes you can. However during deployment you have to use long-form JNDI, provide different JNDI name for beans in other module or disable short names. You cannot register two beans under same name.
Long name would be in the form RitornaPersonaSenzaClientEAR#RitornaPersonaSenzaClient.jar#com.demo.view.RitornaPersonaRemote
See detailed info here - EJB 3.0 and EJB 3.1 application bindings overview
UPDATE
To disable short names perform the following steps:
Go to Application servers > server1 > Process definition > Java Virtual Machine > Custom properties
Define new custom property com.ibm.websphere.ejbcontainer.disableShortDefaultBindings with value * to disable short bindings for all apps or AppName1|AppName2 to just disable short bindings in selected apps.
Example default bindings are shown in SystemOut.log:
The binding location is: ejblocal:JPADepEar/JPADepEJB.jar/TableTester#ejb.TableTester
The binding location is: ejblocal:ejb.TableTester
The binding location is: java:global/JPADepEar/JPADepEJB/TableTester!ejb.TableTester
And with disableShortDefaultBindings property set there is no short form:
The binding location is: ejblocal:JPADepEar/JPADepEJB.jar/TableTester#ejb.TableTester
The binding location is: java:global/JPADepEar/JPADepEJB/TableTester!ejb.TableTester
There is a bug in the documentation and the correct property is com.ibm.websphere.ejbcontainer.disableShortDefaultBindings not com.ibm.websphere.ejbcontainer.disableShortFormBinding
In my case:- i did install abc.ear and xyz.ear both ear was independent do dependency with each other.
I was calling abc.ear using client-lookup but that was giving me
com.ibm.websphere.naming.CannotInstantiateObjectException: Exception occurred while the JNDI NamingManager was processing a javax.naming.Reference object.
[Root exception is com.ibm.websphere.ejbcontainer.AmbiguousEJBReferenceException: The short-form default binding
'com.ejb.abc' is ambiguous because multiple beans implement the interface :
[xyz-ear#rabc-ejb-1.0.jar#abcInrerfaceImpl, rabc-ear#rabc-ejb-1.0.jar
abcInrerfaceImpl]. Provide an interface specific binding or use the long-form default binding on lookup.]
my Solution was:-
i removed the abc.jar that was inside another application(xyz.ear)
C:\Program Files\IBM\WebSphere\AppServer\profiles\AppSrv01\wstemp\92668751\workspace\cells\mypc00Node01Cell\applications\xyz-ear.ear
'
Then solution client-lookup works fine.
To avoid this in future this is better practice to create separate node on your IBM-WAS server and install both application on different node.
So both application component will not mess up.

ejb jndi lookup throws ClassCastexception only when invoked from IBM Message Broker

When i try to make a remote ejb jndi look up, IBM message Broker throws ClassCastexception for the factory object.
But the same code works fine for a normal local java application and junit.Why this problem occurs when called only from IBM WMB
Context context = new InitialContext(ejbJndiProperties);
Object factoryObj = context.lookup("SampleBeanTAFJ/remote");
return (SampleBeanRemote) factoryObj;
This is often called by loading parts of the interface in a different classloader to the implementation classes.
I would use the env var:
IBM_JAVA_OPTIONS=-Dibm.cl.verbose=*
Then restart the broker, this will dump classloading trace to stdout / console.txt which might give you some clues.
What are the exact classes involved in the error and what jars are they stored in? Deployed to the EG or referenced via a SHARED-CLASSES? The exact details determine which classloaders should be in use here.

One Flex client connecting to two webapps using BlazeDS - Detected duplicate HTTP-based FlexSessions

I have a flex application that communicates via BlazeDS with two webapps running inside a single instance of Tomcat.
The flex client is loaded by the browser from the first webapp and all is well. However on the initial call to the second webapp the client receives the following error:
Detected duplicate HTTP-based FlexSessions, generally due to the remote host disabling session cookies. Session cookies must be enabled to manage the client connection correctly.
Subsequent calls to the same service method succeed.
I've seen a few posts around referring to the same error in the context of two flex apps calling a single webapp from the same browser page, but nothing which seems to help my situation - so I'd be very grateful if anyone could help out....
Cheers, Mark
Three potential solutions for you:
I found once that if I hit a remote object before setting up a messaging channel then the CientID would get screwed up. Try to establish an initial messaging channel once the application loads, and before any remote object calls are made.
Flash Builder's network monitoring tool can cause some problems with BlazeDS. I set up a configuration option on application load that checks to see if I'm in the dev environment (it is called just before setting up my channel from #1). If I'm in dev, I assign a UID manually. For some reason this doesn't take well outside the dev environment... been awhile since I set it all up so I can't remember the finer points as to why:
if (!(AppSettingsModel.getInstance().dev))
FlexClient.getInstance().id = UIDUtil.createUID();
BlazeDS by default only allows for a single HTTP session to be setup per client/browser. In my streaming channel definitions I added the following to allow for additional sessions per browser:
<channel-definition id="my-secure-amf-stream" class="mx.messaging.channels.SecureStreamingAMFChannel">
<endpoint url="https://{server.name}:{server.port}/FlexClient/messagebroker/securestreamingamf"
class="flex.messaging.endpoints.SecureStreamingAMFEndpoint"/>
<properties>
<add-no-cache-headers>false</add-no-cache-headers>
<idle-timeout-minutes>0</idle-timeout-minutes>
<max-streaming-clients>10</max-streaming-clients>
<server-to-client-heartbeat-millis>5000</server-to-client-heartbeat-millis>
<user-agent-settings>
<user-agent match-on="MSIE" kickstart-bytes="2048" max-streaming-connections-per-session="3" />
<user-agent match-on="Firefox" kickstart-bytes="2048" max-streaming-connections-per-session="3" />
</user-agent-settings>
</properties>
Problem: Duplicate session errors when flex.war and Livecycle.lca files are hosted in separate JVMs on WebSphere Server.
Solution:
Inside the command file for the event, set FlexClientId to null in execute method before calling remote service (Java method or LC Process).
Guess this approach can be used in other scenarios as well to prevent Duplicate session errors.
EventCommand.as file
—————————–
import mx.messaging.FlexClient;
//other imports as per your code
public function execute(event:CairngormEvent):void
{
var evt:EventName = event as EventName ;
var delegate:Delegate = new DelegateImpl(this as IResponder);
//***set client ID to null
FlexClient.getInstance().id = null;
delegate.functionName(evt.data);
}

Resources