Here is my understanding, which is somewhat less than expert. (But, this has turned out to be VERY LONG.)
There often two names for the same resource, like the JDBC DataSource you cite or, often, for an EJB resource. There could be more than two names, but two is the usual case. The program accesses objects through either of these two names using "JNDI' lookups. However, not all JNDI lookups are provided alike.
Because it all looks the same, it is confusing.
Also, in JBoss it can be particularly confusing because references (names) used to identify another resource can be different for different EJBs, although these different references are, ultimately, stand-ins exactly the same ojbect. Basically, JBoss gives each EJB its own local naming context. Not all Application Servers do it this way. Sun puts all EJBs from the same EAR into the same naming context. Not as flexible, but at least names are used consistently across the application.
In EJB 1.1 and beyond (but not in EJB 1.0), each "container" (JBoss has many containers in one server), each container has to provide a JNDI ENC style of naming as well as the original "JNDI namimg" style.
JNDI names are global or direct names. The JNDI ENC names, on the other hand, are indirect names that map to the direct names. Its all JNDI, but the direct names are called JNDI names, whereas the JNDI ENC names are called references. Very confusing. ("ENC" = Environment Naming Context. It is where "references" go.)
Names in the JNDI ENC are like "environment variables" except that its a hierarchical name space and thus has a working scope for name look-up (like the working directory for file lookups). The programmer gets to choose the reference names (environment variable names) s/he will have in her/his code.
JNDI names, on the other hand, are more like hostnames on the Internet. They are "outside" resources with names that the programmer does not control.
In J2EE, someone (not necessarily the programmer) has to "deploy" the application. In doing so, s/he states what outside resources (identitified by JNDI names) are addressed by the "environment variables" whose names are in the JNDI ENC.
The point is, that you should not have to recompile code to redirect references from your code to a different outside resource, so long as the new resource is operationally identical to the old resource. This is exactly why environment variables have proved so useful in working programs. You get to do the "hook up" in the field, without changing the code.
The naming prefix "java:comp/env/..." is the JNDI ENC, which you can think of as the root directory of the environment variables. The "comp" is for "component", I think. Meaning that name is relative to the component (EJB container).
The JNDI names, on the other hand, are often "global names" that can span containers through a container-to-container name-service protocol. In JBoss this is the JNP, java name provider. (Do I have that right?? JBoss Name Profider ?? )
The name "java:SavingsAccountDB" you cited is such a global name and it can be referenced from external client programs by means of the JNP service that JBoss provides.
The name "java:comp/env/jdbc/SavingsAccountDB" is a reference name that is set up in JNDI ENC by the container. It is a name which can be referenced from within the container only. It must be mapped to the global name during deployment.
You can use the global name ("java:SavingsAccountDB") in your EJB code if you want to, but then you lose the flexibility of connecting to a different DataSource when you set up some new database server. Hard coding the DataSource name would be like programming without environment variables as stand-ins for database name.
There is no guarantee that JNDI ENC names (java:comp/env/...) can be used in remote clients (which are outside of the server). Some vendors support this; JBoss does not. (Yet) JBoss clients have to have someone setup the global naming for them so that they can find the operation objects through calss on the JBoss JNP. But client programs will themselves have simple containers and they don't need a full JNDI ENC. You can use OS environment variables, or System properties to set up ways to avoid embedding global names into your client code.. But Sun, for instance, provides a support package for this that makes your client look as though it was using the Server's JNDI ENC. It is convenient, but it is also deceiving. What Sun does is give you a local environment naming context (in standalone code) that has the cosmetic appearance of the server's JNDI ENC.
Client programs will have to change there environments individually when the global naming on the server changes.
Within a single server, there should be a more consistent management framework. Name mapping of JNDI ENC references to direct names (JNDI names) can be specified in the jboss.xml deployment descriptor. But the jboss.xml should be optional. There are default mappings (reference names to global names) based on the EJB names given in the (standard, requried) ejb-jar.xml deployment descriptor file. Often these conventional mappings appear to be some kind of stylist requirement. They are not. The jboss.xml can be used to set up all kinds of (deployment) name mappings that take the lookup references in the code into the physically present resources, which may be jdbc DataSource resources, as in your example.
But see my post (to follow) wherein I complain that JBoss 3.0 does not perform this mapping correctly where the resource to be mapped is an EJB local interface.
That's a good resource dsconnelly. Thanks.