Details

    • Type: New Feature New Feature
    • Status: Open
    • Priority: Major Major
    • Resolution: Unresolved
    • Labels:
      None

      Description

      In a Java EE application deployment descriptors are used to configure and setup the application. One major issue is that these deployment descriptors are mostly static. In practice, there's often a need to have a different set of configuration files for different situations.

      For instance, for a development environment I might want a link configured by a context-param in web.xml to point to 'localhost:8080/someapp/myresource', while in a QA environment I want it to point to 'qa.mycompany.com/myresource' etc.

      As another example, since Java EE 6 a data source can be configured in among others web.xml using the data-source element. Especially in this case there is a pressing need to have different data sources pointing to different databases depending on the context.

      Yet another example is a Servlet Filter that provides some development utilities, which should definitely not be activated in a production environment.

      A possible solution for this could be the introduction of descriptor fragments that are included from the main descriptor based on a placeholder. E.g. in web.xml:

      <web-app> 
          ... 
          <fragment>WEB-INF/conf/${mycompany.staging}/web-fragment.xml</fragment>
      </web-app>
      

      Inside the WEB-INF/conf directory, multiple folders could be created, each corresponding to a stage, e.g.

      WEB-INF
          conf
              dev
                  web-fragment.xml
              qa
                  web-fragment.xml
              live
                  web-fragment.xml
      

      Starting up the application with -Dmycompany.staging=dev would then cause WEB-INF/conf/dev/web-fragment.xml to be processed.

      Besides being useful for directing different fragment descriptors to be processed, placeholders can also be used to externalize some values completely. E.g. the password in a production datasource:

      <data-source>
          <name>java:app/someDS</name>
          <class-name>org.example.Something</class-name>
          <url>jdbc:someDB</url>
          <user>${mycompany.someDS.user}</user>
          <password>${mycompany.someDS.password}</password>
      </data-source>
      

      For the above to be really useful, another concept should be introduced: the ability to load system properties from an external properties file. Specifying the above password via a -D command line option is of course not secure, since it can be seen in the running processes (e.g. using the ps command). Something like the following would be more suitable:

      -Djavax.config.properties=/somepath/config.properties.

        Activity

        arjan tijms created issue -
        Hide
        Gunnar Wagenknecht added a comment - - edited

        May I add three additional wishes for this proposal or is it too early in the process?

        • Support for environment variables
          In addition to system variables it should also be possible to lookup configuration values from environment variables. It's a very pragmatic and common approach for specifying configuration information before launching an application.
        • Variable defaults
          It may be desirable for a configuration value to have a default value if a system property or environment variable is not set.
          In the following example "dev" will be the default value.
          <web-app> 
              ... 
              <fragment>WEB-INF/conf/${mycompany.staging:-dev}/web-fragment.xml</fragment>
          </web-app>
          
        • Variable nesting
          Allow variable to reference other variable is very convenient, especially in property files.
          USER_HOME=/home/foo  # may also come from environment variable
          file=myApp.log
          destination=${USER_HOME}/${file}
          
        Show
        Gunnar Wagenknecht added a comment - - edited May I add three additional wishes for this proposal or is it too early in the process? Support for environment variables In addition to system variables it should also be possible to lookup configuration values from environment variables. It's a very pragmatic and common approach for specifying configuration information before launching an application. Variable defaults It may be desirable for a configuration value to have a default value if a system property or environment variable is not set. In the following example " dev " will be the default value. <web-app> ... <fragment> WEB-INF/conf/${mycompany.staging:-dev}/web-fragment.xml </fragment> </web-app> Variable nesting Allow variable to reference other variable is very convenient, especially in property files. USER_HOME=/home/foo # may also come from environment variable file=myApp.log destination=${USER_HOME}/${file}
        Hide
        arjan tijms added a comment -

        @gwagenknecht Good additions.

        Indeed, there should be some form of support for defaults. The simple default already works for a lot of situations, but one step further could be to take advantage of the already available support for EL in the platform. If the placeholders were full EL expressions (with the free variables referring to system properties), then this would really enable a very powerful configuration model.

        E.g.

        <web-app> 
            ... 
            <fragment>WEB-INF/conf/${staging eq 'dev' and debug eq true? : dev_debug : !empty staging? staging : 'dev'}/web-fragment.xml</fragment>
        </web-app>
        
        Show
        arjan tijms added a comment - @gwagenknecht Good additions. Indeed, there should be some form of support for defaults. The simple default already works for a lot of situations, but one step further could be to take advantage of the already available support for EL in the platform. If the placeholders were full EL expressions (with the free variables referring to system properties), then this would really enable a very powerful configuration model. E.g. <web-app> ... <fragment> WEB-INF/conf/${staging eq 'dev' and debug eq true? : dev_debug : !empty staging? staging : 'dev'}/web-fragment.xml </fragment> </web-app>
        Hide
        chasetec added a comment -

        For this to work I think you would need EL support in deployment descriptors with the addition of several implicit objects. My list of useful implicit objects:

        • $ {systemProperties}

          Gives you the ability to read from a system property. For example -Dstage=dev could be read with ${systemProperties.stage)

        • $ {propertyFile}

          Would give access to property files in the resource path (or maybe classpath). For example $

          {propertyFile.WEB-INF.dev.properties.stage}

          would load the WEB-INF/dev.properties files and read the stage key's value.

        • $ {jmx}

          lets you read attributes from mbeans.

        • $ {jndi}

          lets you read values from your local JNDI context.

        Servers could support additional implicit objects like $

        {env}

        for environment variables through CDI named beans.

        The ability to reference earlier values would also be useful. For servlet context paramaters: $

        {servletContext.paramName}

        and for servlet params $

        {servletContext.servlets.servletname.paramName}

        and filters $

        {servletContext.filters.filterName.paramName}

        . Maybe shorten those last two to $

        {this.paramName}

        if you are using the EL expression within the servlet or fitler tags. The $

        {this.name}

        syntax would work well for nesting in properties files too if that was also needed.

        In JSF you have the javax.faces.CONFIG_FILES init param you can use right now, a similar configuration option for web.xml fragements named javax.servlet.CONFIG_FILES would be good. Behavior would be that it loaded additional, non-default web.xml fragements within an archive. Basically specifying some additional custom web.xml fragments within my archive but don't break web.xml fragments in embedded library jars.

        Of course EL values would have to be supported when used as annotation attribute values.

        Show
        chasetec added a comment - For this to work I think you would need EL support in deployment descriptors with the addition of several implicit objects. My list of useful implicit objects: $ {systemProperties} Gives you the ability to read from a system property. For example -Dstage=dev could be read with ${systemProperties.stage) $ {propertyFile} Would give access to property files in the resource path (or maybe classpath). For example $ {propertyFile.WEB-INF.dev.properties.stage} would load the WEB-INF/dev.properties files and read the stage key's value. $ {jmx} lets you read attributes from mbeans. $ {jndi} lets you read values from your local JNDI context. Servers could support additional implicit objects like $ {env} for environment variables through CDI named beans. The ability to reference earlier values would also be useful. For servlet context paramaters: $ {servletContext.paramName} and for servlet params $ {servletContext.servlets.servletname.paramName} and filters $ {servletContext.filters.filterName.paramName} . Maybe shorten those last two to $ {this.paramName} if you are using the EL expression within the servlet or fitler tags. The $ {this.name} syntax would work well for nesting in properties files too if that was also needed. In JSF you have the javax.faces.CONFIG_FILES init param you can use right now, a similar configuration option for web.xml fragements named javax.servlet.CONFIG_FILES would be good. Behavior would be that it loaded additional, non-default web.xml fragements within an archive. Basically specifying some additional custom web.xml fragments within my archive but don't break web.xml fragments in embedded library jars. Of course EL values would have to be supported when used as annotation attribute values.
        Show
        arjan tijms added a comment - References to related articles: http://blog.ringerc.id.au/2012/07/java-ee-7-needs-improvements-in-app.html http://antoniogoncalves.org/2011/06/10/debate-and-what-about-configuration-in-java-ee-7
        Hide
        ldemichiel added a comment -

        We hope to address this area as part of Java EE 8.

        Show
        ldemichiel added a comment - We hope to address this area as part of Java EE 8.
        Hide
        kithouna added a comment -

        +1 for EL values in annotation attribute values. Care should be taken that this really functions platform-wide, i.e. in Servlet, JSF, EJB, CDI, etc annotations.

        Show
        kithouna added a comment - +1 for EL values in annotation attribute values. Care should be taken that this really functions platform-wide, i.e. in Servlet, JSF, EJB, CDI, etc annotations.
        Hide
        arjan tijms added a comment -

        This proposal, originally for Java EE 7, is strongly related to the problems outlined in this issue as well: http://java.net/projects/javaee-spec/downloads/download/password-aliasing-ee7-proposal.pdf

        Show
        arjan tijms added a comment - This proposal, originally for Java EE 7, is strongly related to the problems outlined in this issue as well: http://java.net/projects/javaee-spec/downloads/download/password-aliasing-ee7-proposal.pdf
        Hide
        arjan tijms added a comment - - edited

        Another strongly related proposal is an impending JSR for a "configuration service" in Java EE 8. See e.g. http://www.jfokus.se/jfokus13/preso/jf13_JavaEEConfiguration.pdf

        Show
        arjan tijms added a comment - - edited Another strongly related proposal is an impending JSR for a "configuration service" in Java EE 8. See e.g. http://www.jfokus.se/jfokus13/preso/jf13_JavaEEConfiguration.pdf
        Hide
        arjan tijms added a comment -

        Also related: In recent versions of JBoss EAP spec deployment descriptors can have property replacements using limited EL like expressions.

        See https://issues.jboss.org/browse/AS7-5835 (this is a bug report, but it gives a much more complete example than the official documentation at Enabling/Disabling Descriptor Based Property Replacement)

        Show
        arjan tijms added a comment - Also related: In recent versions of JBoss EAP spec deployment descriptors can have property replacements using limited EL like expressions. See https://issues.jboss.org/browse/AS7-5835 (this is a bug report, but it gives a much more complete example than the official documentation at Enabling/Disabling Descriptor Based Property Replacement )
        Hide
        reza_rahman added a comment -

        These are good ideas. I proposed something along the same lines in the Java EE EG some time ago. I believe Resin has added something similar now as well.

        Please note that these are purely my personal views and certainly not of Oracle's as a company.

        Show
        reza_rahman added a comment - These are good ideas. I proposed something along the same lines in the Java EE EG some time ago. I believe Resin has added something similar now as well. Please note that these are purely my personal views and certainly not of Oracle's as a company.
        Hide
        Bill Shannon added a comment -

        Years ago we proposed a way to extend deployment descriptors to allow
        vendor-specific information. We heard loud and clear that both developers
        and vendors alike wanted the standard deployment descriptors to include
        only spec-defined, vendor-independent, information. Always.

        I won't comment on whether some of the proposed product extensions
        violate the Java compatibility rules (which seek to enforce the attribute
        everyone wanted of completely portable deployment descriptors), but it
        certainly sounds like they violate the spirit of portability.

        The general idea of more configurable deployment descriptors is definitely
        interesting, and something we hope to explore for Java EE 8. Until then,
        I hope that vendors confine their extensions to their product-specific
        deployment descriptors.

        Show
        Bill Shannon added a comment - Years ago we proposed a way to extend deployment descriptors to allow vendor-specific information. We heard loud and clear that both developers and vendors alike wanted the standard deployment descriptors to include only spec-defined, vendor-independent, information. Always. I won't comment on whether some of the proposed product extensions violate the Java compatibility rules (which seek to enforce the attribute everyone wanted of completely portable deployment descriptors), but it certainly sounds like they violate the spirit of portability. The general idea of more configurable deployment descriptors is definitely interesting, and something we hope to explore for Java EE 8. Until then, I hope that vendors confine their extensions to their product-specific deployment descriptors.
        Hide
        Darious3 added a comment -

        Bill, I don't know about Resin but in JBoss you have to activate this feature explicitly by making a change in standalone.xml. Everybody who makes this change should know the result is not Java EE compatible anymore.

        I believe JBoss has kept this functionality to their product-specific deployment descriptors (e.g. jboss-web.xml) for years, but I guess the demand for having this in the standard descriptors as well was so huge that they could no longer ignore it.

        It's a big, very big tradeoff for application architects to make now. Portable deployment descriptors are almost holy. Like you said, their most important virtue is being portable. But, not being able to substitute settings in web.xml is such a nuisance and has always been such a nuisance that this feature is just to good to ignore.

        Case in point; we need the Facelets refresh setting in web.xml be a -1 (no refresh) for production and 0 (always refresh) for development. Having a $

        {facelets.refresh:-1}

        there so developers can configure their JBoss server to start up with -Dfacelets-refresh=0 makes a lot of things so much easier for everyone. Same goes for things like JPA query logging.

        Show
        Darious3 added a comment - Bill, I don't know about Resin but in JBoss you have to activate this feature explicitly by making a change in standalone.xml. Everybody who makes this change should know the result is not Java EE compatible anymore. I believe JBoss has kept this functionality to their product-specific deployment descriptors (e.g. jboss-web.xml) for years, but I guess the demand for having this in the standard descriptors as well was so huge that they could no longer ignore it. It's a big, very big tradeoff for application architects to make now. Portable deployment descriptors are almost holy. Like you said, their most important virtue is being portable. But, not being able to substitute settings in web.xml is such a nuisance and has always been such a nuisance that this feature is just to good to ignore. Case in point; we need the Facelets refresh setting in web.xml be a -1 (no refresh) for production and 0 (always refresh) for development. Having a $ {facelets.refresh:-1} there so developers can configure their JBoss server to start up with -Dfacelets-refresh=0 makes a lot of things so much easier for everyone. Same goes for things like JPA query logging.
        Hide
        reza_rahman added a comment -

        This is how Resin does it: http://wiki4.caucho.com/Resin:_Application_Server:_Parameterized_Web_Server_Cluster. It is completely Resin specific and bound to Resin deployment descriptors. This is a general pattern in Resin (favoring Resin deployment descriptors and even creating outright one-to-one alternatives to standard XML deployment descriptors - perhaps too much so) as the standard XML descriptors are seen as needing a significant overhaul/modernization. This is something I've mentioned in the EG in the past as well.

        Please note that these are purely my personal views and certainly not of Oracle's as a company.

        Show
        reza_rahman added a comment - This is how Resin does it: http://wiki4.caucho.com/Resin:_Application_Server:_Parameterized_Web_Server_Cluster . It is completely Resin specific and bound to Resin deployment descriptors. This is a general pattern in Resin (favoring Resin deployment descriptors and even creating outright one-to-one alternatives to standard XML deployment descriptors - perhaps too much so) as the standard XML descriptors are seen as needing a significant overhaul/modernization. This is something I've mentioned in the EG in the past as well. Please note that these are purely my personal views and certainly not of Oracle's as a company.
        Hide
        Bill Shannon added a comment -

        Darious3, it's important to remember the key Java compatibility rule
        that we call the "all modes" rule - a product must be compatible
        all the time, in all modes, no matter how you configure it. There
        can be no documented settings that make the product behave differently
        than required by the specs.

        (Further discussion of this issue is best done on the mailing list.)

        Show
        Bill Shannon added a comment - Darious3, it's important to remember the key Java compatibility rule that we call the "all modes" rule - a product must be compatible all the time, in all modes, no matter how you configure it. There can be no documented settings that make the product behave differently than required by the specs. (Further discussion of this issue is best done on the mailing list.)
        Hide
        arjan tijms added a comment -

        A related discussion on the JBoss mailing list: http://lists.jboss.org/pipermail/wildfly-dev/2014-January/001522.html

        It also looks like the Java EE configuration as proposed by e.g. http://www.jfokus.se/jfokus13/preso/jf13_JavaEEConfiguration.pdf is not actually happening. Instead there's a Java configuration JSR proposal, but for now if I understand it correctly it seems to focus more on Java SE and injection and not really on Java EE deployment descriptors (but maybe I misunderstood). See https://groups.google.com/forum/#!forum/java-config

        Show
        arjan tijms added a comment - A related discussion on the JBoss mailing list: http://lists.jboss.org/pipermail/wildfly-dev/2014-January/001522.html It also looks like the Java EE configuration as proposed by e.g. http://www.jfokus.se/jfokus13/preso/jf13_JavaEEConfiguration.pdf is not actually happening. Instead there's a Java configuration JSR proposal, but for now if I understand it correctly it seems to focus more on Java SE and injection and not really on Java EE deployment descriptors (but maybe I misunderstood). See https://groups.google.com/forum/#!forum/java-config
        Hide
        atsticks added a comment - - edited

        Hi all, I have talked with Mike Keith at JavaOne 2013. Mike told me, that he will not be able to lead the config JSR. Nevertheless, we are on the way preparing such a JSR, so it should happen The JSR will run under the EE umbrella, but since it should also cover deployment aspects, it must quite probably also be executable before CDI and other resources are available. So the configuration service must be capable of running on the system context already. From a runtime perspective (despite security manager being active, and some other aspects), this matches quite well with a pure SE environment. Also I highly recommend separating concerns to have better control on the complexity and to be able to focus the JSR from the start (having more effective discussions).
        Summarizing I currently think we need:

        • a basic configuration service, with a configurable meta model, that is defining the base configuration services available. It will out of the box support system and environment properties, program arguments as well as reading property (and XML property) files from any resolvable resources.
        • the basic service will also have to provide extension points to add functionality, e.g. by some adapter, operator and query patterns.
        • the EE part then should define, how the configuration service should be setup and deployed in a EE container (e.g. shared on system level, or within the ear/war context).
        • And it should define, in collaboration with the other EE specs, how descriptors can be provided/extended/overriden using the new capabilities available(or descriptor parameters, and also other resources). There are different possibilities how to achieve this and I assume we will have some discussions how this should be done best.

        So the aspects described in this ticket will be definitively in focus for the upcoming JSR

        Regards,
        Anatole

        Show
        atsticks added a comment - - edited Hi all, I have talked with Mike Keith at JavaOne 2013. Mike told me, that he will not be able to lead the config JSR. Nevertheless, we are on the way preparing such a JSR, so it should happen The JSR will run under the EE umbrella, but since it should also cover deployment aspects, it must quite probably also be executable before CDI and other resources are available. So the configuration service must be capable of running on the system context already. From a runtime perspective (despite security manager being active, and some other aspects), this matches quite well with a pure SE environment. Also I highly recommend separating concerns to have better control on the complexity and to be able to focus the JSR from the start (having more effective discussions). Summarizing I currently think we need: a basic configuration service, with a configurable meta model , that is defining the base configuration services available. It will out of the box support system and environment properties, program arguments as well as reading property (and XML property) files from any resolvable resources. the basic service will also have to provide extension points to add functionality, e.g. by some adapter, operator and query patterns . the EE part then should define, how the configuration service should be setup and deployed in a EE container (e.g. shared on system level, or within the ear/war context). And it should define, in collaboration with the other EE specs, how descriptors can be provided/extended/overriden using the new capabilities available (or descriptor parameters, and also other resources). There are different possibilities how to achieve this and I assume we will have some discussions how this should be done best. So the aspects described in this ticket will be definitively in focus for the upcoming JSR Regards, Anatole
        ljnelson made changes -
        Field Original Value New Value
        Assignee ldemichiel [ ldemichiel ] ljnelson [ ljnelson ]

          People

          • Assignee:
            ljnelson
            Reporter:
            arjan tijms
          • Votes:
            17 Vote for this issue
            Watchers:
            9 Start watching this issue

            Dates

            • Created:
              Updated: