0

I have an Eclipse project which uses java with struts 1.3.10 framework.

I use a .properties file (say configApp.properties) to manage production webapp, demo webapp and development webapp. This .properties file is used in the ServletContextListener and in a PropertyDecoder class which implements IntrospectionUtils.PropertySource (see this question).

Now, manually, I change the configApp.properties according to the task I have to accomplish (i.e. build a new production version).

How could I automatize this step?

As the .properties filename has to be the same for the three types of build, I thought to create three folder each cointaining the configApp.properties (one for production, one for demo and one for development).

Is there a better way, for example by passing a parameter to the build (I think it's not possible 'cause the PropertyDecoder class which implements IntrospectionUtils.PropertySource must be compiled and the .class put on the Tomcat lib folder)? If so, how can I parameterize ServletContextListener and the PropertyDecoder class so that they can take in input the right .properties file?

Community
  • 1
  • 1
Sefran
  • 375
  • 6
  • 24
  • Do you use any build tool like maven, gradle or ant? This kind of task is handled by maven, resource filtering and profiles. – nomoa Nov 02 '14 at 16:51
  • @nomoa: No, I don't. By using Maven is it possible to mantain the same directories' structure? The Maven build process finds source files in /src/main/java, but in Eclipse they are in /src/ folder and I wouldn't to change the dir tree. – Sefran Nov 03 '14 at 09:25
  • Maven is designed to work with default file structure so it's generally harder to configure maven for a custom structure than changing the project structure. If you really don't want to change your project structure opt for Gradle which is way more flexible. – nomoa Nov 03 '14 at 13:41
  • Note than Eclipse and Maven work nicely together. And most of eclipse configuration is automatically done when eclipse read the maven pom.xml file. We use maven only for most of our project and for some that requires some custom stuff we use maven+gradle. – nomoa Nov 03 '14 at 13:45
  • 1
    It's worth the effort to add an eclipse agnostic build tool to your project. The best advise I might tell you is configure your project with a build tool (maven or gradle). Things like the question you asked will be no more a problem. – nomoa Nov 03 '14 at 13:50
  • I'm also in favor of the eclipse agnostic build. It may be a little pain in the beginning, but it's definitely worth the effort (Esp. maven). – mike Nov 09 '14 at 13:25

3 Answers3

1

You can completely avoid building different versions of your application by externalising the configuration.

You can drop configApp.properties into the Tomcat "lib" directory where it will be accessible on your application class path. Technically, it will be available in the "common" class loader as defined in your conf/catalina.properties file.

It can then be source controlled with the rest of your Tomcat configuration, which is nearly always environment specific as well.

Steve C
  • 18,876
  • 5
  • 34
  • 37
  • I know I can put `configApp.properties` in Tomcat lib folder. The point is that I haven't only one `configApp.properties`, but one for demo app, one for production app, and one for the test app. I would to build the app according to the type of the chosen web app and create the relative .war – Sefran Nov 03 '14 at 14:35
  • And my point is that you really don't want to do that. It's an idea that does not scale well. What happens when you need another version for performance testing, and another version for that special demo for that special customer? For your use case you typically have quite different Tomcat configurations. Production may run in 4G of memory with maxThreads=200. A demo version may run in 1G with maxThreads=50. If you have datasources declared in your server.xml then they will point at different database servers. configApp.properties is a part of all that. – Steve C Nov 04 '14 at 12:15
0

Create a template with all the values you manually change as parameters. Then use a template engine to transform it into the final .properties file that you need. I use powershell but you can use Freemarker Template Language as well. The powershell script below takes a template file applies the transform by replacing the keywords in the templte with variables defined. The final result is a .properties file.

{$hg_version= hg identify -i set-variable -name language -value "%sonar.language%" set-variable -name projectKey -value "Key" set-variable -name projectName -value "XXXXXX" set-variable -name openCoverResultxml -value "Trident.sln.CoverageReport.xml"

(get-content %sonarProperty%\sonar-project.template | foreach-object {$_ -replace "phrase_to_replace_A", $hg_version} | foreach-object {$_ -replace "phrase_to_replace_B", $projectKey} | foreach-object {$_ -replace "phrase_to_replace_C", $language} | foreach-object {$_ -replace "phrase_to_replace_B", $projectName}) | set-content %sonarProperty%\sonar-project.properties}

Keep in mind that this script will not work for FreeMarker but there are instructions on how to use freemarker engine. Powershell works just fine for me though. You can automate the process by creating builds that for each of the configuration combination such that the variables passed to each build will generate the properties file that you would manually have created. TeamCity allows dropdowns when running a build so you can potentially select the parameters at build time to pass to powershell/whatever template engine is used.

delloPiro
  • 309
  • 3
  • 7
0

Normally, the best practice, IMHO, is to externalize those .properties files (at least the ones that will be changed per "customer") from the webapp. This is because we don't want a custom webapp build for each "customer" (production, demo, development, customer A, customer X, ...). You only want one version of your webapp and multiple versions of your config files (one per each "customer").

You can configure your own custom config folder. That folder will be just one more place were the classloader will lookup for resources:

In tomcat_dir\conf\catalina.properties, you can set the common.loader property like this:

common.loader=your_config_folder_path,${catalina.base}/lib,${catalina.base}/lib/.jar,${catalina.home}/lib,${catalina.home}/lib/.jar

So, if you now need to setup an environment for a demo, you just need to put in that config folder your demo version of configApp.properties.

If you want to have multiple environments running on the same machine, you can configure multiple instances of tomcat. Basicaly you just need to install tomcat once, and then, for each instance, you need to have different webapps, conf, logs, temp, work folders. You can do this creating a .bat|.sh script for each instance. In that script you only have to specify the CATALINA_HOME environment variable, which can point to a relative path of the parent folder (to be more generic).
You can google for "running multiple instances of tomcat" or check the following tutorial for more details: http://www.ramkitech.com/2011/07/running-multiple-tomcat-instances-on.html

I would sugest you to configure the common.loader property (in catalina.properties) to point to ${catalina.base}/conf folder:

common.loader=${catalina.base}/conf,${catalina.base}/lib,${catalina.base}/lib/.jar,${catalina.home}/lib,${catalina.home}/lib/.jar

So, if you need to have a demo and a production environment running on the same machine, you must have something like this:

tomcat_production
   |__ webapps
   |__ conf
   |        |__ configApp.properties (production settings)
   |        |__ catalina.properties
   |        |__ (...)
   |__ logs
   |__ temp
   |__ work
   |__ startup.bat (script that will start this instance of tomcat)

tomcat_demo
   |__ webapps
   |__ conf
   |        |__ configApp.properties (demo settings)
   |        |__ catalina.properties
   |        |__ (...)
   |__ logs
   |__ temp
   |__ work
   |__ startup.bat (script that will start this instance of tomcat)

I hope this helps...

tuga
  • 331
  • 2
  • 5
  • the issue is that I've only one environment for demo and production webapp. Now I trying to understand if I have to setup multiple Tomcat or if I can do all the stuff with a .properties in the webapp chosen in the right way by using a build tool – Sefran Nov 10 '14 at 11:34