users@javaee-spec.java.net

[javaee-spec users] Re: Persistent application configuration

From: Bill Shannon <bill.shannon_at_oracle.com>
Date: Fri, 27 Jul 2012 12:39:28 -0700

Craig Ringer wrote on 07/27/12 06:23:
> Thanks for taking the time to think about and respond to this. My reply
> follows in-line; I hope that's OK.
>
> On 07/27/2012 07:06 AM, Bill Shannon wrote:
>
>>
>> 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.
>
> Accessing them has improved, but defining them hasn't. It's still a PITA that
> requires an EAR wrapper or, if you're lucky, container-specific admin command
> line incantations - even a web console in some containers.
You don't need an ear wrapper. You can define them in web.xml.

> I can't produce an application with "download, edit a few details in a config
> file, deploy/run" complexity if the user has to repackage it into an EAR to
> use it, or if I have to provide per-app-server listings of command line
> incantations, web UI nav paths, server-specific descriptors, etc to explain
> how to set some environment entries up.
Understood.

I know many users would like us to standardize the command line tools used for
operations such as application deployment, but I haven't seen a lot of
enthusiasm from vendors for that! :-)

Still, if you could provide an xml file with the settings and the user could
modify that file and then supply it along with the application when they deploy
the application (even if such deployment uses different tools for each vendor),
I think that would help a lot.

> I guess it all just seems like a lot of hoops to jump through to configure an
> application - instead of just deploying a configuration file directly.
Instead of saying "deploy foo.war", is it sufficient to be able to say "deploy
--config myconfig.xml foo.war"? Or do you want a way to deploy the config file
separately, before the application is deployed?

>> You can now do things like
>>
>> @Resource(name = "myTimeout")
>> int timeout = 10;
>>
>> From a usability perspective, injected environment entries are not too bad.
>
> ... in sites where injection is available, like EJBs, CDI managed beans, etc,
> yes. That's many, but far from all, places. A JNDI access wrapper isn't
> exactly hard to write where injection isn't available, though it does require
> the user to understand JNDI - something that's obvious to you and is now
> obvious to my, but I assure you is /not/ obvious when learning.
What *would* be obvious when learning?

I'm not sure Preferences is obvious; most people don't even know about it.

> The main issue with this from a usability PoV is that if injection isn't
> supported for a given site, it's just silently left null. I know there's
> probably no better answer in an extensible, flexible system where all sorts of
> different code takes responsibility for injection in different places, but
> it's pretty confusing for users.
I guess I was expecting that for people just getting started, the classes they
were going to write are the classes that support injection.

Still, I agree that at some point it might be confusing to people that injection
doesn't just work everywhere.

>> They're settable separately from the application code and exposed in a way
>> that tools can manage them (although not in a portable way).
> I'd argue that their settability is poor and app-server-specific at best, but
> they are settable.
>>
>> 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).
> Actually, injection can still work for non-primitives. That's an interesting
> idea. Something like CDI's Instance<T> could easily be used for injection of
> mutable properties, with a suitable set(..) method. Essentially an injected
> wrapper for the entry.
Which suddenly becomes a lot less obvious. But yes, doable.

> The main issue is that if it's app-settable it'd have to be injected that way
> everywhere or changes wouldn't be updated at all injection sites. Proxies
> would help with this, but they don't work on primitives and - since injection
> sites can't be final (sadly) applications can easily accidentally replace the
> proxy by assignment.
And a related issue... If configuration entries can be changed externally, does
there need to be a way to notify the application of any such changes?

> This could work if env entries were only app-settable if explicitly marked as
> such, and such entries could *only* be injected via an Instance<T>-like
> wrapper to prevent accidents like the above.
That's starting to get pretty complex...

> The main trouble is that it'd be a pain to work with structured resources like
> lists and maps, especially when it comes to modifying them from outside the
> application via admin tools, configuration dumps/loads, etc.
If you want to support external configuration of arbitrary Java objects, this
all becomes much more complex. If you can live with strings, it's a lot easier.

>>
>> 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.
> Handily, the preferences API is pretty backend-agnostic. That's part of why I
> thought it might be an attractive option. App servers can easily store prefs
> in an app-server-provided embedded DB or an external database shared across a
> cluster.
Yes, the implementation details can be hidden, but the application-visible
semantics need to be defined. If I change a configuration parameter and then
write an entry to the database, will other instances of the application see
those changes in the same order? Do configuration changes need to be transactional?

> It's a pity the "system" and "user" levels are designed into the API, because
> being able to designate "global", "cluster", and "application" levels without
> having to extend the API would be handy.
Yup.

>> 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.
> They are simple, but unlike preferences they don't cater for much in the way
> of structure. Not that the preferences API is exactly /nice/ for storing maps,
> lists and sets, but it works better than property name hacks in a properties file.
>
> A tree of properties files, with appropriate injection, could work - but
> surely the prefs API folks went down that path and rejected it for good reasons.
I believe Preferences was largely designed to match what the Windows registry
can do.

>> 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'd be a real pain for containers that want to offer web UI or command line
> management of the JNDI env. When the props file is updated, what's the
> container to do?
>
> It doesn't answer application updates either.
Right, it solves 40% of the problem but costs 5% of a complete solution. It's a
cost/benefit tradeoff.

>> 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.
> Absolutely, and I'm one of them.
>> Managing the lifecycle of application configuration data independently of
>> applications is another problem to address.
> +1 on that
>> 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.
> Agreed, that's certainly an interesting target area but one with no obvious
> answers. JMX and MBeans don't seem like the answer. Containers that support
> remote management are mostly doing it via REST, so this would seem the logical
> approach, but it's hard to know where to go without having an underlying API
> to expose.
>
> I don't think this can be answered without knowing what the underlying
> mechanism for storing and setting preferences will be.
>
>> I'm hoping we can find the resources to do this "soon", although it will
>> almost certainly have to come after Java EE 7.
>
> That's ... disheartening. This problem is old, and as Java EE works on a
> nearly geological time scale it's going to be really hard to maintain
> enthusiasm for it over the several years required. It'd be three or four years
> before the solution could actually start hitting real world deployments.
It's conceivable that a solution could be delivered independently of Java EE 8,
and could be applied to Java EE 7 products. Depending on the complexity of the
solution, a portable implementation might be possible, although the biggest
challenge is probably cluster support.

> I wonder if there a reasonable subset of functionality that can be considered,
> one container vendors can extend for other needs?
I hope it's been clear in this conversation that there's a lot of issues to
address, even if it means deciding *not* to address them. You didn't seem
particularly willing to give up the aspects that were important to you in order
to have a simpler solution, and I think you're very representative of everyone
else who has been involved in this discussion. And that's why it's going to
take longer than you think. :-)