Hi all,
As @Bill mentioned on his first email "Scoping the problem and agreeing on
the important uses cases is likely to be far more work than implementing
the solution". We all agree that configuration is an important topic and we
might not be able to specify it for Java EE 7. But what about scoping it
and targetting just a sub-part of configuration ? What are the topics
covered by configuration and what should we focus on now ?
What do we have at the moment :
- Several deployment descriptors (application.xml, ejb-jar.xml,
persistence.xml...)
- JNDI configuration entries
- JMX
What are we looking for :
- Single deployment descriptor vs several ?
- Configuration entries storage (JNDI vs Properties vs Preferences vs
Database vs XML) ?
- Configuration should be outside the package (ear, war, jar)
- i18n of configuration entries
- Overriding or overlaying configuration entries
- Clustering
- Multi-tenant (same configuration entries with different value
depending on the tenant)
- REST vs JMX
- (anything else ?)
What should we focus on for Java EE 7 (because we don't have much time and
this is a first stone on configuration, for me, the most important thing is
to be able to configure my application easily in a file (not in JNDI nor
Database) and not to package it within the ear/war) :
- Configuration entries storage (JNDI vs Properties vs Preferences vs
Database vs XML)
- Configuration should be outside the package (ear, war)
- i18n of configuration entries
We could start with a short list of concerns (this is just my 2 cents),
forget the rest for now, and try to come with a solution. What do you think
?
I've already expressed it in this ML long time ago, but for me, something
like Seam Config (
http://docs.jboss.org/seam/3/config/latest/reference/en-US/html_single/)
would do : configuration is in XML with a strong namespace typing, anything
is configurable (a primitive type in a bean, an EJB reference, a
datasource...), it's i18n (important for non EN application).
Antonio
On Mon, Jul 30, 2012 at 11:18 PM, Bill Shannon <bill.shannon_at_oracle.com>wrote:
> It's true that Java EE doesn't define anything that helps support
> heterogeneous clusters. For that matter, it says very little (too little)
> about even homogeneous clusters, the general assumption being that a
> properly written application on a properly implemented cluster won't know
> or care that it's running in a cluster. I'd really like to see more in the
> spec about how to "properly" write such an application.
>
> Standardizing support for heterogeneous clusters seems like a much lower
> priority. I'd be very interested in hearing from users that this is more
> important than I think it is, and from vendors that they're wiling to
> implement such a standard, especially if they already support such features.
>
> Enrico Olivelli wrote on 07/27/12 10:31:
>
> there is no direct relation between multi-tenancy and clustered deployment
>
> Clustered Deployment
> the application is deployed on a cluster, a group of JVMs running on
> diferrent hosts
> machines can have specific hardware tuned for some specific operation or
> can have different network configuration
> some examples of configuration parameters that can be different for each
> JVM:
> - enable some operation (for example an MDB) only on some machine (because
> that machine hardware is better for some kind of processing....)
> - enable some scheduled (EJB timer) operation only on some machine
> - enable the execution of an operation that need a particular network
> setup (for example firewall ports....)
> - enable the execution of some interface (for example a webservice
> endpoint) only on machines that can be accessed from the public network
>
> Multi-Tenant Configuration:
> each "tenant" has an instance of the same application that is deployed on
> a container (which can be deployed on a single machine or a cluster)
> resources are "logically" separated between tenants
>
> some examples of configuration parameters that can be different for each
> tenant:
> - some parameter that enables/disables some feature of the application
> - name of the app (for example a logo in the header of the webapp) ?, help
> desk email addesses/phone numbers
> - resource usage limits ?
> - datasources ?
> - javamail sessions ?
> - jms destinations ?
>
> - Enrico
>
>
> Il 27/07/2012 09:10, Bill Shannon ha scritto:
>
> Are you using "tenant" to mean "an application instance running on one
> server in a cluster"? Otherwise, I don't understand the connection between
> clusters and multi-tenant apps.
>
> What are some examples of parameters that need to be configured
> differently on instances in a cluster?
>
> Enrico Olivelli wrote on 07/26/2012 10:38 PM:
>
> I have another kind of problems, related to this issue(s), that is
> configuring apps deployed in clusters.
> Most of config parameters are shared between all instances in the cluster,
> but some other config parameters have to be configured slightly in a
> different way for each instance.
>
> Therefore in a multi-tenant environment I would like that configuration
> could be overriden for each tenant
>
> -
> Enrico Olivelli
>
> Il 27/07/2012 01:06, Bill Shannon ha scritto:
>
> Hi Craig. Thanks for your comments.
>
> In this message, let's talk about application configuration.
>
> I believe you've seen the discussion in this expert group on the topic of
> application configuration some time ago. There seems to be general
> agreement that we need something here, but I'm still trying to decide
> whether we're all describing the same elephant or whether there are
> actually multiple animals involved. :-)
>
> One of the big questions here is how do we make this configuration
> information available to applications. We've had a way to do that for
> quite some time - JNDI environment variables. I understand that people
> generally haven't used them because, among other reasons, they've been kind
> of hard to use. That's improved in recent versions. You can now do things
> like
>
> @Resource(name = "myTimeout")
> int timeout = 10;
>
> To access your "myTimeout" configuration parameter. That's comparable to
>
> int timeout = prefs.getInt("myTimeout", 10);
>
> From a usability perspective, injected environment entries are not too
> bad. They're settable separately from the application code and exposed in
> a way that tools can manage them (although not in a portable way). But...
>
> Environment entries are read-only to the application. If we want to allow
> the application to update its configuration parameters, we need something
> different, or we need to remove that restriction on environment entries (in
> which case injection isn't going to work).
>
> Preferences is a reasonable alternative API to consider, although many
> others have been proposed, each with its own advantages and disadvantages.
>
> As you mention, once the data can be updated by the application, we need
> to define the semantics of such updates in a cluster. The only existing
> APIs that do that are the database-based APIs, which is why using JPA
> entities to model application configuration data is attractive.
>
> Yet another issue is the desire to be able to provide configuration data
> separately from the application. Properties files are simple and well
> understood and suitable for most such uses, which is why it's worth
> considering using Properties as the API. Or we could just define a way to
> initialize JNDI environment entries using a properties file. That would be
> a really cheap solution for a part of the problem, but can it go far enough
> or is it a dead end?
>
> It's easy to preserve application configuration data across a redeploy of
> the application, but some people want the ability to specify the
> application's configuration before the application is ever deployed.
> Managing the lifecycle of application configuration data independently of
> applications is another problem to address.
>
> Some people also want a portable way to read and update the application
> configuration data for some application running in a remote app server,
> e.g., to enable writing separate management tools for an application. None
> of the existing APIs is really designed for this. Do we need to define a
> new web service or ReST interface for this? Should we use JMX? It would
> be nice if we had a standard management technology for Java EE app servers
> that we could build on, but we don't.
>
> By the time you're done considering all the issues in this space, this is
> no longer a simple problem. A simple solution *is* possible, but it
> means rejecting some of the use cases people have proposed. Can we find an
> 80% solution here? I believe so, but I believe it's going to take more
> effort than "just do it". Scoping the problem and agreeing on the
> important uses cases is likely to be far more work than implementing the
> solution.
>
> And unfortunately, that's why it hasn't been done yet.
>
> I'm hoping we can find the resources to do this "soon", although it will
> almost certainly have to come after Java EE 7.
>
>
> Craig Ringer wrote on 07/16/2012 09:16 PM:
>
> Hi all
>
> I'd like to raise two related areas of difficulty I've encountered with
> Java EE 6 projects:
>
>
> - The lack of a simple, user-friendly and reliable mechanism for
> application configuration; and
> - The difficulty of overriding or overlaying deployment descriptors
> like beans.xml on a per-deployment basis.
>
>
> I've written a detailed post about the topic here:
>
>
> http://blog.ringerc.id.au/2012/07/java-ee-7-needs-improvements-in-app.html
>
> which I reproduce below. I'd appreciate your thoughts, especially on the
> suggestions for improvements at the end of the piece. This seems like a
> HTML-friendly mailing list so I've retained the original formatting rather
> than reformatting in plain text. Hope that's OK.
>
>
>
> Most applications need configuration options or preferences, a way for
> the user to edit them, and a way for the application to read and edit them.
> Java EE applications are no exception. Right now Java EE applications have
> numerous options for such settings - but no single choice that's simple,
> admin- and app-author friendly, and easy for both admin and app to modify.
>
> Java EE is supposed to provide much of the groundwork for apps as part of
> the container, so the app author can get on with solving their problem.
> Right now it doesn't help much with application settings, and this needs
> improvement so that apps:
>
> - Don't need to each provide a custom UI in order to edit even the
> simplest settings
> - Can easily modify their own settings
> - Can guarantee the persistence of their settings across redeploys and
> across cluster nodes
> - Don't require a full database and data access layer / JPA / etc just
> to store simple configuration options.
>
> I'd like to highlight this as an issue for Java EE 7 or 8.
>
> Approaches A Java SE app can:
>
> - Use a .properties file stored in a well-known location like the
> user's homedir. The user can edit this file and/or the app can load and
> rewrite it easily.
> - Use the Preferences API. This doesn't provide easy direct editing by
> the user, but gives the app a very simple way to store its settings.
> - Have the user set system properties
>
> All these options are available to Java EE apps, but with caveats that
> render them unappealing as noted below. Java EE apps also have some
> additional options:
>
> - Servlet context parameters
> - JNDI environment resources
> - Storing settings in a container-defined SQL datasource
> - For JBoss AS 7: Deploy a companion archive
>
> Again, none of them are particularly nice, though keeping the
> configuration in the database is usually the most reasonable choice.
>
> Direct file system access Direct file system access for storing
> configuration isn't trivial, because there's no clear and obvious place for
> configuration files to live. Should they be stored in the homedir of the
> user who's running the app server? In the app server's directory? In some
> arbitrary platform-specific location?
>
> More importantly, will the app actually have rights to read or write the
> file wherever it lands up, given that a SecurityManager may be in effect?
>
> Preferences API The Preferences API would seem like the ideal solution
> despite the lack of direct .properties editing by users. Unfortunately, at
> least some application servers seem to like to overwrite preferences when
> an application is re-deployed. Replication of preferences in a clustered
> app server is undefined and app-server specific. It's a mess.
>
> The app must also provide an editing UI for settings in the preferences
> API; there's no way for the user to edit it directly.
>
> System properties System properties work well, but they're set via
> different methods in each application server. They're globally visible
> across all applications, which could be a security concern for some
> properties. Most importantly, they're difficult or impossible for the
> application to update - they're effectively read-only.
>
> Servlet context parameters Servlet context parameters can be difficult to
> access globally across the application without hacks like adding a servlet
> filter to capture them. Methods for setting them without source changes are
> application-server specific and not at all friendly.
>
> JNDI environment resources JNDI environment resources are even less fun
> to define for the admin, and can be clumsy to use within the application.
> They have a legacy Java EE 5-or-older feel and appear little-used.
>
> JBoss AS 7 deployment companion JARs JBoss AS 7's ability to deploy
> companion JARs with a deployment archive is extremely useful. These JARs
> are private to the deployment and on the classpath. They provide an easy
> mechanism for customising some application descriptors and configuration.
> Unfortunately you can't deploy a companion jar as a jar overlay to override
> descriptors in the original jar, but you *can* use it to provide
> app-server-specific injectable beans and services, and to provide
> deployment-specific configuration. However, this feature (a) isn't
> available on Glassfish and (b) requires the user to build a .jar and deploy
> it with your app using jboss-cli. Again, the app cannot easily modify the
> configuration bundled in the archive.
>
> Best choice: Configuration in the database A very common solution for
> Java EE applications is to store their configuration in a database. Many
> (most) EE apps are database driven anyway, so keeping the configuration in
> the DB makes sense. The DB is generally accessible to all instances of a
> distributed/clustered app.
>
> This is all fine so long as you're using a container-provided JDBC / JTA
> datasource. However it isn't suitable for apps that want to use
> @DataSourceDefinition or a bundled datasource like a -ds.xml file to make
> deployment easier for users.
>
> It's also useless for the purpose of *specifying the name of the data
> source you want the application to connect to* if you need to avoid
> hard-coding that. You can use a system property for that purpose and get
> the rest of the configuration from the database, though.
>
> Even for apps that require a container data source anyway, one annoyance
> with this approach is that it's hard for users to go in and edit it. You
> are likely to need to write configuration pages for everything; you can't
> just direct them to a config file. That's OK for highly dynamic
> configuration, but it's a real pain for largely static stuff that gets set
> at the start of the deployment and forgotten.
>
> Alternative choice: System properties pointing to properties files If
> your app isn't database driven you probably don't want to make the user set
> up a datasource in the container for your app to store its settings. You
> just want them to be able to deploy the app. This isn't really practical at
> the moment.
>
> A system property pointing to a properties file location can be a somewhat
> ugly but reasonable compromise in this case. It avoids the user needing to
> deal with per-app-server quirks re how to configure a new persistent H2 /
> Derby datasource. Setting system properties is at least usually easier.
>
> So what do I think should be available?
> Preferences API constrained for Java EE applications
> My ideal would be for the Java EE 7 spec to constrain the Preferences API
> support on Java EE 7 compliant app servers with the following additional
> requirements:
>
> - Implementations *must* preserve the preferences API settings across
> re-deploys of an application. They *may* offer a deployment option to
> clear and reset preferences.
> - Implementations *must* provide an interface to edit, back up, clear,
> and restore/load stored preferences for a deployment. Command line, web,
> whatever; just provide an interface for it. This interface *must* accept
> and produce compliant preferences XML<http://docs.oracle.com/javase/6/docs/api/java/util/prefs/Preferences.html#importPreferences%28java.io.InputStream%29>;
> it *may* accept and produce other formats.
> - On EE7 implementations that provide clustering features,
> java.util.prefs.Preferences<http://docs.oracle.com/javase/6/docs/api/java/util/prefs/Preferences.html>
> *must* implement the new java.util.prefs.SharedPreferences interface,
> which provides methods (yet to be defined) to allow applications to control
> synchronization of preferences across the cluster. SharedPreferences *
> must* be injectable via CDI.
> - On non-clusterable EE7 implementations,
> java.util.prefs.SharedPreferences must be CDI-injectable as a stub
> that throws UnsupportedOperationException on implemented methods.
>
>
> This would make j.u.p.Preferences useful in EE apps. I'm sure the details
> would need work - for example, maybe java.util.prefs.SharedPreferences
> shouldn't be injectable unless supported, so you'd use an Instance** to
> inject it.
>
> Standardize a deployment overlay mechanism
> Right now it's a real pain to change things like bean alternatives in
> beans.xml or the settings inpersistence.xml on a per-deployment or
> per-app-server basis.
>
> How can we make it easy to override or merge/overlay deployment arbitrary
> deployment descriptors on a per-deployment basis? Things like:
>
> - persistence.xml
> - beans.xml
> - JBoss's -ds.xml files
> - glassfish-resource.xml
> - ... and you name it, lots more
>
> Right now, changing most of these involves modifying unpacking the jar,
> editing the contents, and repacking it, or requires altering the source
> tree and rebuilding. That isn't good for users or app developers/deployers:
>
> - It makes it hard for "end users" to just deploy an app in a
> fuss-free manner;
> - It dramatically reduces the utility of CDI's beans.xml configuration
> file
> - It forces the creation of per-app-server flavours of many app builds
> - It's slow, fiddly, and annoying
>
> What's needed is a standard way to deploy additional descriptors alongside
> a deployment archive, with control over whether these descriptors *
> override* the bundled descriptor, or are *merged with* the bundled
> descriptor. The latter case would probably only be supported for selected
> descriptors like beans.xml where merging could be made relatively
> well-defined.**
>
>
> --
> Craig Ringer
>
>
>
>
>
>
>
--
Antonio Goncalves
Software architect and Java Champion
Web site <http://www.antoniogoncalves.org> |
Twitter<http://twitter.com/agoncal>|
LinkedIn <http://www.linkedin.com/in/agoncal> | Paris
JUG<http://www.parisjug.org> |
Devoxx France <http://www.devoxx.fr>