Issue
I am learning Java EE. My instructor told me to implement JNDI DataSource in my learning project. I have found some articles on the subject but I can't see clearly the steps to doing this.
My training project is a Spring MVC application. On the front end it has some Thymeleaf templates, and the data are taken from a PostgreSQL database.
What should be done to implement JNDI here? I don't even know why I need it. I was only told that this configuration should be considered obsolete and low-level, but I have no idea why.
Now the database is configured as follows:
- a props file with the following content:
driver=org.postgresql.Driver
url=jdbc:postgresql://localhost/trainingproject
dbuser=postgres
dbpassword=Password
- a .sql file which looks like this:
DROP TABLE IF EXISTS table1;
CREATE TABLE table1
(
row1 SERIAL PRIMARY KEY,
row2 CHARACTER VARYING(64)
);
- a DataSource bean:
@Bean
public DataSource datasource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getProperty(DRIVER));
dataSource.setUrl(environment.getProperty(URL));
dataSource.setUsername(environment.getProperty(USER));
dataSource.setPassword(environment.getProperty(PASSWORD));
}
Solution
PGSimpleDataSource
implementation of DataSource
is bundled with JDBC driver.
The JDBC driver for Postgres at https://jdbc.postgresql.org includes an implementation of DataSource
: PGSimpleDataSource
PGSimpleDataSource ds = new PGSimpleDataSource() ;
ds.setServerName( "localhost" );
ds.setDatabaseName( "your_db_name_here" );
ds.setUser( "scott" );
ds.setPassword( "tiger" );
For more info:
- The Javadoc for
DataSource
. - The Javadoc
PGSimpleDataSource
. - My Answer to the Question, Produce a
DataSource
object for Postgres JDBC, programmatically - The JDBC driver’s manual.
JNDI
Your question conflates two issues: DataSource
and JNDI
.
A DataSource
is a simple object holding all the connection info needed to make a connection to a database. This includes a username, a password, the address of the database server, and any number of standard and proprietary feature settings. By proprietary, I mean Postgres-specific feature settings versus Microsoft SQL Server-specific versus Oracle-specific, etc. Look at the Javadoc for DataSource
to see how simple it is, basically just a getConnection
method. You can obtain a DataSource
object with or without JNDI; the two are orthogonal issues.
JNDI is much more complex. JNDI is an interface for obtaining from a naming/directory server the configuration info needed by your app at runtime. Using this interface to such a server means you need not include deployment details in your codebase; you look up needed details on-the-fly at runtime.
Database connection info is but one of many kinds of info you might want to obtain from a JNDI server. You might also look up web services servers, logging services, and so on.
So rather than hard-coding your database connection info, you might want to “discover” the proper database connection info when launching your app. Your testing machines will use a bogus database server while your production deployment machines will use a different database server. These database servers may not be known to the programmer at compile time, or may not even exist yet. A look-up needs to be done, and JNDI is a standard way to do so without vendor lock-in.
How you configure database connection info to be delivered by a JNDI-compliant naming/directory server as a DataSource
object to your app differs wildly depending on the particular server environment of your enterprise. Given your last code example, it looks like you are not actually accessing a JNDI server in your class, so JNDI is moot.
Answered By - Basil Bourque