Is it bad practice to include properties/configuaration files within jars?

前端 未结 11 967
谎友^
谎友^ 2021-02-07 00:34

For example:

MyApp is a web app that contains a properties file (server.properties) that describes config data (e.g. server names) for the app. In the development phase

相关标签:
11条回答
  • 2021-02-07 01:03

    I use property files in webapps (WARs), but mostly for default values and stuff that's more or less immutable (since webapps shouldn't be updating their WARs even when they can).

    For stuff like what you're talking about, however, I use JNDI. You can define the properties as resources in your web.xml file. That way, at worst, you update web.xml and not the app itself.

    For some servers there are ways of overriding these resource values without touching the WAR at all. For example, in Tomcat.

    I normally make one WAR for test, Q/A and production and override the environment-sensitive resources in exactly this was, using Tomcat's Context xml files. I consider this a lot better than having to build multiple WARs or to modify WARS, since the app I'm testing is almost identical to the app that's in production.

    0 讨论(0)
  • 2021-02-07 01:07

    Remember, that in J2EE, you are NOT guaranteed to be able to access files from outside the J2EE environment (no direct file access).

    You would have to use JNDI to point to a datasource containing your data, or a properties file in your deployment artifacts.

    Websphere, for example, doesn't allow direct file access by default.

    0 讨论(0)
  • 2021-02-07 01:10

    If you are using Spring then you can make use of the property placeholder to do the work.

    <!-- try and resolve the config from the filesystem first and then fallback to the classpath -->
    <context:property-placeholder location="file:config.properties, classpath:config.properties"
                                  ignore-resource-not-found="true"/>
    

    You can specify a resource on the filesystem and also on the classpath, Spring will first try and resolve all of the properties from the filesystem and then fallback to the classpath. By specifying the "ignore-resource-not-found" attribute as "true" it will prevent Spring from throwing an exception if the file isn't present on the filesystem and allow it to resolve the properties from the classpath instead.

    Using this combination also allows you to split the properties over two files, for example you might never want to specify passwords in the file on the classpath and expect them to be specified externally on the filesystem. Any properties missing from the filesystem will be resolved from the classpath.

    In a folder containing:

    application.jar
    config.properties
    

    You should be able to use:

    java -jar application.jar
    

    This is a sample config.properties for reference:

    # This file contains properties that are used to configure the application
    database.url=127.0.0.1
    database.port=3306
    database.user=root
    database.pass=p4ssw0rd
    
    0 讨论(0)
  • 2021-02-07 01:15

    Option D. In different environments you may need to specify want to specify environmental properties such as connecting to the database or proxy etc.

    Other thing worth noting is that in production you may want to quickly change a property without having to prepackage a jar or replace the properties file in the jar.

    E.g. The database server is fallen over and you need to point to a different server (if not using a load balancer of the databases). So all you need to do is replace the database properties and restart. You save a lot of time there.

    0 讨论(0)
  • 2021-02-07 01:15

    I think the answer depends on whether you think you need to version control for the configs. (They could be production configs or configs for regression testing ...)

    • If you don't need version control, then option D with an external property file that overrides a property file is a good one. Options B and C are more open to stuff-ups, but if you really cared you'd be using version control :-)
    • If you need version control, option A gives you more control, but if you have the possibility of multiple deployments you may also want/need to version control the configs for each deployment. An example is separate deployments to test and production platforms.

    Here's how we do this using Maven modules and Maven WAR file "overlays".

    1. We have multiple modules for the Java code components. These are JAR modules.
    2. We have "base webapp" module for the static content, JSPs and core configuration data (Spring wiring, default properties). This is a WAR module, so the result of building is a WAR that contains the above + all JAR files.
    3. Each distinct "site configuration" is a WAR module that contains site-specific overrides for properties, wiring files and content. The overriding is described using the Maven WAR "overlay" mechanism, and results in a new WAR being assembled from the "base" WAR and the overrides.

    All of this is checked into version control, and you need to do a Maven build and WAR deployment to make configuration changes.

    0 讨论(0)
提交回复
热议问题