JNDI object not shared among TC instances

A

Albretch

Hi,

as, I understand things, the JNDI can be used to share an object among different JVMs even from J2SE applications running on different machines. Right?

I need a relatively light object (that is why I am avoiding EJBs altogether) which would simply:
1._ poll a backend database at configurable periods, and if some data has changed
2._ update its internal state, which is then
3._ administered to and updated in a number of independent tomcat instances

Well, I did the following exp. and repeated it even compiling TC 5.5.5 from source in case I had to check it, but before I start diving deeper into what I think might be the reason for this anomaly, I want to check that I don't have a silly conf problem I haven't seen or there is something I am not quite understanding here.

Here is the method to my madness:

1._ I first downloaded TC's source code, 'built it' with ant, ran and tested it.
2._ Then I set up a number (3) of separate instances running from independent JVMs using the same files as in the original, plain installation, as describe in 1; by:
2.1_ setting up three independent directories, <...> /tc00/, /tc02/, and /tc04/ off the original installation
2.2_ just copying /conf/ and /bin/ from the original installation and dumping similar files on each dir described in 2.1
2.3_ changing then in each of the /conf/server.xml
2.3.1_ the Server port="8005"
2.3.2_ the non-SSL HTTP/1.1 Connector port="8080"
2.3.3_ the AJP 1.3 Connector port="8009" (<- will need it for later tinkering with Apache)
for all three independent instances, and
2.4_ making sure that the same absolute directory was used in the appBase attribute of the <Host name="localhost" . . . context
2.5_ then, making sure that the same;
2.5.1_ JAVA_HOME
2.5.2_ CATALINA_HOME
but different
2.5.3_ CATALINA_BASE
was set in the respective .../tcXX/bin/catalina.bat files (client wants me to 'try' windows 'too'), pointing to the respective .../tcXX
3._ I then ran all three instances and tested every thing was OK and scanned log
files for any errors, warnings, . . .

Everything seemed to be working just fine!

// - - - - - - - - - - - - - - - - - - - - -

Then I used the following slimmed down classes from example code sections in the jakarta JNDI howto, in order to illustrate my point.

Both classes were placed in the original installation's /common/classes/JNDITest/ directory

// - - - - - - - - - - - - - - - - - - - - -
package JNDITest;

public class JNDI00{
private int bar = 0;
private long lCreatTime = System.currentTimeMillis();
private String foo = "Default Foo, created at " + lCreatTime + "";
// __
public String getFoo() { return (this.foo); }
public void setFoo(String foo) { this.foo = foo; }
// __
public int getBar() { return (this.bar); }
public void setBar(int bar) { this.bar = bar; }
// __
public long getCreatTime() { return (lCreatTime); }
public void setCreatTime(long l){}
// __
}

// - - - - - - - - - - - - - - - - - - - - -
package JNDITest;

import java.util.*;
import javax.naming.*;
import javax.naming.spi.*;

public class JNDI00Factory implements ObjectFactory {

public Object getObjectInstance(Object obj, Name name, Context nameCtx, Hashtable environment) throws NamingException {

JNDI00 JNDI_Obj = new JNDI00();

Reference ref = (Reference) obj;
Enumeration addrs = ref.getAll();
while (addrs.hasMoreElements()) {
RefAddr addr = (RefAddr) addrs.nextElement();
String aSNm = addr.getType();
String value = (String) addr.getContent();
if (aSNm.equals("foo")) {
JNDI_Obj.setFoo(value);
} else if (aSNm.equals("bar")) {
try {
JNDI_Obj.setBar(Integer.parseInt(value));
} catch (NumberFormatException e) {
throw new NamingException("Invalid 'bar' value " + value);
}
}
}

return (JNDI_Obj);
}
}

// - - - - - - - - - - - - - - - - - - - - -
then included for each TC instance in the <GlobalNamingResources> element of $CATALINA_HOME/conf/server.xml

<Resource name="JNDICtxt/JNDI00Factory"
auth="Container"
type="JNDITest.JNDI00"
factory="org.apache.naming.factory.BeanFactory"
bar="23"/>


// - - - - - - - - - - - - - - - - - - - - -
in $CATALINA_HOME/conf/ Catalina/localhost/ROOT.xml

<ResourceLink name="jndiName"
global="JNDICtxt/JNDI00Factory"
type="JNDITest.JNDI00"/>


// - - - - - - - - - - - - - - - - - - - - -
and at the end of $CATALINA_HOME/webapps/ROOT/WEB-INF/web.xml

<resource-env-ref>
<description>JNDICtxt JNDI00Factory Test</description>
<resource-env-ref-name>jndiName</resource-env-ref-name>
<resource-env-ref-type>JNDITest.JNDI00</resource-env-ref-type>
</resource-env-ref>

// - - - - - - - - - - - - - - - - - - - - -
Then included right on /ROOT/index.jsp code segments looking like:

<%@ page language="java" %>
<%@ page import="java.util.*" %>
<%@ page import="java.io.*" %>
<%@ page import="javax.naming.*" %>

<%@ page import="JNDItest.*" %>

<%@ page session="false" %>

<%!
// __
private Context initCtxt;
private Context envCtxt;
private JNDI00 JNDIObj;
// __
public void jspInit(){
// __ JNDI resources
String aBug = "<ul>";
// __
try{
initCtxt = new InitialContext();
envCtxt = (Context)initCtxt.lookup("java:comp/env");
// __
String aInitCtxt = initCtxt.toString();
String aEnvCtxt = envCtxt.toString();
// __
aBug += "<li>initCtxt: " + aInitCtxt + "</li>";
aBug += "<li>EnvCtxt: " + aEnvCtxt + "</li>";
// __
System.err.println(" initCtxt: |" + initCtxt + "|");
System.err.println(" envCtxt: |" + envCtxt + "|");
// __
System.err.println(" (new JNDI00()): |" + (new JNDI00()) + "|");
// __
String aCtxtURL = "JNDICtxt/JNDI00Factory";
aCtxtURL = "jndiName";

JNDIObj = (JNDI00)envCtxt.lookup(aCtxtURL);
System.err.println(" JNDIObj: |" + JNDIObj + "|");
if(JNDIObj != null){
System.err.println(" JNDIObj: |" + JNDIObj + "|");
System.err.println(" JNDIObj.getBar(): |" + (new Integer(JNDIObj.getBar())).toString() + "|");
System.err.println(" JNDIObj.getCreatTime(): |" + JNDIObj.getCreatTime() + "|");
System.err.println(" JNDIObj.getFoo(): |" + JNDIObj.getFoo() + "|");
// __
aBug += "<li>JNDIObj: |" + JNDIObj.toString() + "|</li>";
aBug += "<li>JNDIObj.getBar(): |" + (new Integer(JNDIObj.getBar())).toString() + "|</li>";
aBug += "<li>JNDIObj.getCreatTime(): |" + JNDIObj.getCreatTime() + "|</li>";
aBug += "<li>JNDIObj.getFoo(): |" + JNDIObj.getFoo() + "|</li>";
}
// __
aBug += "</ul>";
}catch(NamingException NmX){ NmX.printStackTrace(); }
// __
}// jspInit()
// __
public void JspDestroy(){}
%>

<%
// __ Response Headers
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
response.setDateHeader("Expires", 0);
// __
%>

// - - - - - - - - - - - - - - - - - - - - -
and inside the actual page just after <body>

<%=aBug%>

// - - - - - - - - - - - - - - - - - - - - -

You will see each TC instance has its own instances of:
* javax.naming.InitialContext
* org.apache.naming.NamingContext
* JNDITest.JNDI00


What is it I am doing wrong here?

How could you achieve what I want, namely, read (kind of a singleton object) from different TOmcat instances?
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top