cancel
Showing results for 
Search instead for 
Did you mean: 

Problem with JNDI in cluster in SAP WAS SS9

Former Member
0 Kudos

Hello, dear experts.

We have the following problem:

In a clustered SAP WAS SS9 on Win 2K/Oracle/JDK 1.4.2_07, if a server in the cluster is shut down its JNDI entries are still visible by other servers' initial context lookup calls.

Piece of code to reproduce is as follows:

LookupTest.java:

package lookuptest;

import javax.naming.*;

import java.util.*;

public class LookupTest {

private static InitialContext ctx=null;

static {

final Properties props=new Properties();

props.put(Context.INITIAL_CONTEXT_FACTORY,

"com.sap.engine.services.jndi.InitialReplicatingContextFactoryImpl");

props.put("Replicate","true");

props.put("clear_cache","true");

try {

ctx=new InitialContext(props);

} catch (NamingException e) {

e.printStackTrace();

}

}

public LookupTest() {

}

public static synchronized String get(String name) throws NamingException {

return (String) ctx.lookup(name);

}

public static synchronized void put(String name, String value) throws NamingException, NameAlreadyBoundException {

ctx.bind(name,value);

}

}

// from JSP

<%

String name=null;

try {

name=LookupTest.get("test");

out.prinltn("Found!");

} catch (NamingException e) {

out.prinltn("Not Found!");

// not found

try {

LookupTest.put("test","test");

} catch (NameAlreadyBoundException e) {

}

}

%>

To reproduce:

Start up a cluster.

Run JSP from both servers in a cluster.

Shut down the SAP WAS server on the node that returned Not Found!.

Run JSP from another server - Found appears, although the originating server went down.

I would really appreciate any comments or suggestions.

Regards,

-Yuri

Accepted Solutions (1)

Accepted Solutions (1)

Former Member
0 Kudos

In case someone else needs this here is a workaround: In order to solve our problem we've implemented a refresh algorythm ("leasing" strategy) which keeps the entry "fresh" (or leased) for a certain period of time by a server-side timer thread. If server stops refreshing it we assume it's down and clean the entry from JNDI.

elitsa_pancheva
Explorer
0 Kudos

Hi Yuri,

Why are you using InitialReplicatingContextFactoryImpl when creating InitialContext instead of InitialContextFactoryImpl?

Default behavior of naming service is used with InitialContextFactoryImpl and supports local naming operations i.e. when binding an object it will be available only on the server process where it is bound.

This implementation should be used especially from applications as they should not care for anything outside the server they are running in.

InitialReplicatingContextFactoryImpl is a limited implementation which has to be used very carefully. Operations made with Context returned by this factory are global i.e. replicated in the cluster. You have to make sure that the object is bound from exactly one server because the feature is not synchronized so if it is used concurrently inconsistencies in the naming tree in different servers may occur.

If the object is bound using context got from InitialReplicatingContextFactoryImpl it will become available in all the servers in the cluster.

1. If this object is serializable it simply will be sent to all the servers as byte[] and every time a lookup is performed the object will be deserialized in the VM of the client that makes the lookup. In this case even if the server from which originates the object goes down there is no reason a client to be prevented from looking up the object because it is connected in no way to the down server. So there is no need to remove this object moreover the client that has bound it deliberately had made it globally available.

2. If the object is a remote one only a wrapper of it is bound in the naming and sent to all the other services. After lookup the client gets a stub connected directly to the skeleton placed on the server where the object was originally bound. In this case it is very crucial if this server goes down. If this happens the next lookup of this object will initiate its removal from the naming system of the server in which the operation is performed. So in case of remote object - the binding is removed from the other servers and the lookup operation returns NameNotFoundException.

Anyway my advice is not to use InitialReplicatingContextFactoryImpl. Instead you should use Configuration manager/service if you need to keep objects in a central for the cluster place.

Regards,

Elitsa

Former Member
0 Kudos

Thank you Elitsa.

>>Why are you using InitialReplicatingContextFactoryImpl when creating InitialContext instead of InitialContextFactoryImpl?

We need the object to be available across cluster. We use this for cluster-wide synchronization of certain operations.

>>. If the object is a remote one only a wrapper of it is bound in the naming and sent to all the other services. After lookup the client gets a stub connected directly to the skeleton placed on the server where the object was originally bound. In this case it is very crucial if this server goes down. If this happens the next lookup of this object will initiate its removal from the naming system of the server in which the operation is performed. So in case of remote object - the binding is removed from the other servers and the lookup operation returns NameNotFoundException.

This is exactly what we need - now how do we make an object "a remote one"?

Thanks a lot,

-Yuri

elitsa_pancheva
Explorer
0 Kudos

Hi Yuri,

Basically a remote object is an object that implements a remote interface. Remote interface is any interface that extends java.rmi.Remote. By extending the interface java.rmi.Remote, this interface marks itself as one whose methods can be called from any virtual machine.

For more detailed information on designing and developing remote objects you may refer:

http://java.sun.com/docs/books/tutorial/rmi/designing.html

Once you create a remote interface and implementing object you have to bind a new instance of the implementation in the naming service. The lookup of such an object insists the classloader of the client that makes the lookup to be able to load the remote interface and the stub generated for this interface.

Use the remote interface to cast the object returned by lookup operation and call its methods.

If you don't want to generate explicitly stub and skeleton for your remote object and interface the p4 service of the engine will generate Proxy objects for the remote communication. In this case the client must have only the remote interface in its classpath.

Hope that helps,

Best Regards,

Elitsa

Former Member
0 Kudos

OK, I will give it a try. Thanks, Elitsa.

Answers (0)