Comments inline.
On Sep 9, 2009, at 11:54 AM, Les Hazlewood wrote:
On Tue, Sep 8, 2009 at 3:43 PM, Jeremy Haile <[email protected]> wrote:
It is confusing for me to discuss how Shiro's configuration should be
overhauled, because there are different types of configuration that
are
suited to different configuration mechanisms. I think in order to
have an
effective discussion about overhauling the configuration, we need
to break
these down.
Whatever mechanism(s) we choose, I feel they should all be in the same
physical file (or single block of text). I wouldn't want end-users to
specify multiple files - that would be an inconvenience that I at
least would like to avoid as an end user.
I agree to some extent (properties file perhaps excluded) - but to me
this implies if I'm using Spring I shouldn't have to go configure some
groovy script too. This is part of what feels wrong to me about the
current config - why do I have to configure somethings in an ini file
and others in Spring?
#1 Properties
Currently Shiro treats properties the same as objects and
essentially has a
"poor man's" IoC framework for injecting these. The problem is that
sometimes these properties need to be used deep in the hierarchy,
resulting
in either ugly nested property names or "pass through" property
code which
is equally ugly and strange. (see
DefaultWebSecurityManager.setRememberMeCookiePath() and
WebRememberMeManager.setCookiePath() for an example)
I think the best solution here is to introduce a true properties
file that
would be available (somehow) to anyone no matter how deep they are
in the
hierarchy. This would essentially define defaults that could be
used by
internal classes without having to pass the variables deep into the
hierarchy.
I don't know how to support this cleanly - there could be tons of
properties to support and we'd still have to find a way to define them
and then set those values on the underlying objects.
Would we be required then to use a 'pull' model, where our classes
need to know how to acquire these values themselves? I don't
particularly like that model - all of our classes are configuration
agnostic, which is very nice. Maybe some mediator that would know how
to apply configured values...
Tons of libraries and frameworks do this cleanly. There *aren't* tons
of properties to support; there are a handful. It's also an
extensible solution because once you figure out how deep objects can
retrieve the properties they need for their configuration you are
done. You don't have to keep writing the ugly pass-through code that
you see in our current codebase. A mediator that applies configured
values is a good idea - just not sure if it's over-engineering a
configuration solution that should be simple.
#2 Defining realms, filters, and overriding default implementations
Currently this is done with the "poor man's" IoC implementation as
well. At
this level I think we should support using several IoC frameworks
but NOT
WRITE OUR OWN. Support Guice out of the box for this. Support
Spring out
of the box for this. Support programmatically doing this out of
the box.
But if you want to use IoC - dang it, use one that already exists.
We've already done this with our .ini mechanism, but it falls short in
a few key areas. This is something I was looking to Groovy for - to
'pick up the slack' so to speak. Not a full blown IoC container, but
still useful while remaining simple.
But why should people need to use groovy if they're already using a
"full blown" IoC container. And why should our documentation and
default examples show using groovy to do programmatic configuration
when we actually think it's a better decision for our users to just
embrace an actual "full blown" IoC container? I don't want to require
any particular IoC container - but I don't see building our own IoC/
configuration/whatever system as adding any value.
Using Groovy could allow us to do other things as well - it'd be easy
to config urls and 'global' properties in #1 using Groovy syntax,
given how nice it is for custom Domain Specific Languages.
But what if I don't want to use groovy - can I still configure these
in Spring? Can I configure them in Guice? I don't understand the big
picture being proposed here.
#3 Declarative URL security
Currently this is declared in INI format either in the web.xml file
or in a
shiro.ini file. I think this actually still makes sense.
Alternatively it
could be injected directly into the ShiroFilter (if you are using
an IoC
container.
See my thoughts above on groovy-based configuration - it can handle
declarative security just fine and would still be easy to read.
But I wonder - should our default Lowest Common Denominator
configuration mechanism have _zero_ dependencies?
I agree here. Our Lowest Common Denominator is Java. "Want zero
dependencies? Use Java and programmatically configure your Shiro
installation. Want nice configuration and dependency injection - then
use an actual IoC container. We have great integration with Spring,
Grails, Guice, X, Y, and Z."
Currently we don't even meet that criteria - our .ini mechanism
requires Commons BeanUtils, and I haven't heard anyone complain about
that as a dependency. If we went the Groovy config-based approach,
we'd just swap out the BeanUtils dependency for the groovy .jar.
Seems like a fair trade-off for the additional benefits it would
provide.
BeanUtils is an apache-commons project that most big Java projects use
anyway. Groovy seems a much stranger core dependency to me. Don't
get me wrong - I heavily use Groovy at work and love it. I just don't
see how it makes sense here as a core dependency of the Shiro
project. Seems like we're reinventing the wheel and going way out of
our way to not use actual IoC, when in reality most of our users will
be using actual IoC.
One last point: if our Lowest Common Denominator is Java configuration
- there's no reason you can't write Groovy code that does the
programmatic Java configuration. Why do we need to add a dependency
for that?
Jeremy