javaee / javaee-spec

Java EE Platform Specification
https://javaee.github.io/javaee-spec
Other
389 stars 69 forks source link

Configurable deployment descriptors #19

Open glassfishrobot opened 11 years ago

glassfishrobot commented 11 years ago

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.

glassfishrobot commented 11 years ago

Reported by arjan_t

glassfishrobot commented 11 years ago

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

glassfishrobot commented 11 years ago

arjan_t said: @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>
glassfishrobot commented 11 years ago

chasetec said: 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:

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.

glassfishrobot commented 11 years ago

arjan_t said: References to related articles:

glassfishrobot commented 11 years ago

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

glassfishrobot commented 11 years ago

kithouna said: +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.

glassfishrobot commented 11 years ago

arjan_t said: 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

glassfishrobot commented 11 years ago

arjan_t said: 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

glassfishrobot commented 11 years ago

arjan_t said: 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)

glassfishrobot commented 11 years ago

reza_rahman said: 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.

glassfishrobot commented 11 years ago

@bshannon said: 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.

glassfishrobot commented 11 years ago

darious3 said: 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.

glassfishrobot commented 11 years ago

reza_rahman said: 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.

glassfishrobot commented 11 years ago

@bshannon said: 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.)

glassfishrobot commented 10 years ago

arjan_t said: 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

glassfishrobot commented 10 years ago

atsticks said: 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:

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

Regards, Anatole

glassfishrobot commented 7 years ago

This issue was imported from java.net JIRA JAVAEE_SPEC-19