8

For a long time in many IT services, I see some complex process to manage Java EE application configuration depending of the environments: - custom tools, with Database or not, to manage replacement in the properties file (unzip war, replace, zip war...) - Externalize properties file in obscure directory in the server (and some process to update it some time) and some time with a JNDI configuration... - maven profile and lot of big properties files

But for database connection everybody use jndi datasource.

Why this is not generalized for all configurations that depend of environment ?

Update : I want deal with other variable than datasource, there is no question about datasource : it's in configured in JNDI for Java EE application. After if you want hack JNDI...

Mr_Thorynque
  • 1,749
  • 1
  • 20
  • 31
  • Take a look at this [link](http://stackoverflow.com/questions/15064260/tomcat-jndi-configuration-best-practice) – Abdelhak Dec 03 '15 at 09:43
  • It deal about datasource on tomcat, and tomcat isn't a real Java EE server. But they deal with the same logic while putting configuration in web app or on the server. – Mr_Thorynque Dec 03 '15 at 10:23
  • What's the question? Where to put something? Why is this not generalised? – user207421 Dec 03 '15 at 11:08
  • Usually everyone is ok to use JNDI Datasource but for other configuration (wsdl endpoint or whatever), I don't know the good practice JNDI vs properties. JNDI Datasource is well documented for every Application Server, but using JNDI has key/value as properties file is another usage. – Mr_Thorynque Dec 03 '15 at 12:36

1 Answers1

8

Setting up database connectivity (like user name, password, URL, driver etc.) somewhere in the application server has several advantages over doing it yourself in the WAR:

  • The app server can be a central point where the DB is configured, and you might have several WARs running on that server sharing a DB. So you need to set it up only once.
  • The DB settings, especially the credentials (username, password) are stored somewhere in the app server instead of somewhere in the WAR. That can have security implications (for instance, restricting access to that file is easier done than in a WAR archive).
  • You can set up one JNDI path to retrieve a DataSource instance pointing to the DB and do not need to worry about username and password anymore. If you have multiple app servers (one live system, one test system, several developer machines) with different DB URLs and credentials, then you can just configure that in each app server individually and deploy the WAR files without the need to change DB settings (see below).
  • The server might provide additional services, like connection pools, container managed transactions, etc. So again, you don't have to do it on your own in the WAR.

This is true for other services provided by the app server as well, for example JavaMail.

There are other cases where it you want to configure something that is specific to one web application and does not rely on the environment (the app server), like logging (although that may be set up in the app server, too). In those cases you might prefer using static config files, for instance log4j.properties.


I want to illustrate the third bullet point a bit further ...
Suppose you have one WAR in three app servers (developer machine, test server, live server).

Option 1 (DB setup in WAR)

Create a database.properties :

db.url=jdbc:mysql://localhost:3306/localdb
db.user=myusername
db.pass=mysecretpassword

#db.url=jdbc:mysql://10.1.2.3:3306/testdb
#db.user=myusername
#db.pass=mysecretpassword

#db.url=jdbc:mysql://10.2.3.4:3306/livedb
#db.user=myusername
#db.pass=mysecretpassword

Before you deploy it somewhere, you need to check if your settings are pointing to the right DB!

Also, if you check this file in to some version control system, then you might not want to publish your DB username/password to your local machine.

Option 2 (DB setup in App Server)

Imagine you have configured the three servers with their individual DB settings, and each of them registers the DB with the JNDI path java:database/mydb.

Then you can retrieve the DataSource like so:

Context context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup("java:database/mydb");

This is working on every app server instance and you can deploy your WAR without the need to modify anything.


Conclusion

By moving the configuration to the app server you'll have the advantage of separating settings depending on the environment from your app code. I would prefer this whenever you have settings involving IP addresses, credentials, etc.

Using a static .properties file on the other hand is simpler to manage. I would prefer this option when dealing with settings that have no dependencies to the environment or are app specific.

jabu.10245
  • 1,884
  • 1
  • 11
  • 20
  • 1
    Ok JNDI is usually use for DataSource, no probleme but for other configuration variable. What's the best practice ? – Mr_Thorynque Dec 03 '15 at 10:29
  • 1
    There's no general answer, it depends on your goals. I'd say, if you configure something for your WAR only, and it doesn't change when deploying to different servers, then stick with `.properties` files, they're simpler. Some technologies/framework are required to be configured the one or the other way, so it depends... Also, if your JavaEE server supports configuration, you should use that instead of `.properties` files. No need to reinvent the wheel here. – jabu.10245 Dec 03 '15 at 10:31
  • 1
    @Mr_Thorynque I have extended my answer. – jabu.10245 Dec 03 '15 at 12:47
  • Yes I understand, JNDI that all. – Mr_Thorynque Dec 03 '15 at 13:28
  • Why not created an executable jar rather than deploying to an application server? This simplifies deployment, and also gives you an opportunity to start it whilst giving it the path to whatever property file you want to use. There are also configuration servers that do this nicely, such spring cloud contract. Feels very old school to be building wars and deploying to tomcat still. – mogronalol Dec 28 '16 at 15:36