On Jun 21, 2007, at 10:32 PM, Karan Malhi wrote:

This is cool. Reminds me something similar to what JDO does for
lookups on package.jdo.

What would happen in this scenario (Assuming we are caching)

org.apache.openejb.core.stateless.StatelessContainer  references
classNotFound=A msg
org.apache.openejb.core.SomeCoreClass references classNotFound=A CORE msg

StatelessContainer is invoked first and its classNotFound key is cached
Now SomeCoreClass is invoked, but the one from cache is used, so there
is a possibility of a wrong message for SomeCoreClass


Doesn't that depend on what the "virtual key" is? So, lets say you're in package a.b.c, and call log.info(key1). If this turns into log(a.b.c.key1) no matter whether the key1 was actually found in the message.properties file for package a, package a.b, or package a.b.c, I don't think there will be any collisions. However I admit I don't see any reasonable way to precompute the set of all used "virtual keys", so with this scheme caching on first lookup seems required.

On the other hand, you can precompute all the "specified virtual keys". so if you have key1 in the message properties for a and a.b.c, you'd precompute a.key1 and a.b.c.key1. At runtime if you then called log.info(key1) from package a.b.c or a.b.c.d you'd get the a.b.c.key1, whereas from packages a, a.b, a.b.e you'd get a.key1.

I guess these can be combined to some extent -- precomputing all the "specified virtual keys" and then adding more as they are used. This could be a good use for the lock-free hash map :-)

thanks
david jencks

Walking forward or backward on demand would lead to a conflict like
above, because what if because of an if condition or something
SomeCoreClass is used first and its message is cached, at that point
StatelessContainer will show the  wrong message.

With unrolling upfront, the question is where do we stop looking. Does
the first key found win or the last key found win if there were
duplicates in different Messages.properties. In either case, if a key
wins, it might cause the same problem I described above.

Overriding should not be allowed. Key names should be unique and we
should encourage to keep them unique, this will reduce the work we
will have to do to keep track of overriding rules etc. The rule could
be simple, first look in the parent, if not look in the child or the
reverse look in same package, then look in parent.

What I would suggest is also writing a TestCase which would search all
Messages.properties and fail on finding a duplicate key. This way if
anybody added a key and ran the build, they would be able to
immediately catch a duplicate key . The point I am trying to make is
to enforce a little rule to not allow naming duplicate keys , which
means overriding of keys would not be permitted. I think this will
save tons of time for newcomers who might accidentally add a key and
then ponder over the output for hours as to why they are not getting
the correct message (just because some other key somewhere overrode it
because it was found first and cached). This will also be effective in
terms of performance and caching.


Another option is that if we do want to allow duplicates, because lets
say I dont want to think about where other keys were declared and what
were their names, i.e. a key belongs to a package kind of scenario,
the cache should namespace the keys with the package name.
So for example, org/apache/openejb/Messages.properties has a
classNotFound key, then after namespacing, the "real key" would be
org.apache.openejb.classNotFound. This is another way we can avoid
conflicts in the cache. But we should look for a key in the same
package first.

But in this scenario we will have to make the "decision " in the cache
itself. Lets say for example,
A  org/apache/openejb/Messages.properties   , classNotFound= Msg A
B  org/apache/openejb/core/Messages.properties

org.apache.openejb.core.SomeCoreClass references classNotFound. Since
there is not classNotFound in its Messages.properties, it looks it up
in the parent i.e. org.apache.openejb. This is where it finds the key
and stores it in the cache as org.apache.openejb.classNotFound. and so
on.


So if SomeCoreClass references classNotFound, the cache should be
searched for org.apache.openejb.core.classNotFound, then it should be
searched for org.apache.openejb.classNotFound.

To me caching everything upfront looks like a good option

If we are searching on demand, then when we search a properties file,
we should cache all the properties instead of finding a property and
just caching that property. This will make sure we dont hit the same
properties file twice.




On 6/21/07, David Blevins <[EMAIL PROTECTED]> wrote:
There have been a couple things I thought would be neat additions for
the i18n side of our logging code.  Basically, inheritance.


Say you have the following Messages.properties files in the classpath.

A  org/apache/openejb/Messages.properties
B  org/apache/openejb/core/Messages.properties
C  org/apache/openejb/core/stateless/Messages.properties

Then you have a class such as
org.apache.openejb.core.stateless.StatelessContainer (note the package)

If that class referenced a message key "classNotFound" for example,
the i18n code would look for the message first in Messages.properties
C, then B, then A and so on until it found the required message.

This would allow better reuse of messages, more flexibility in where
we put the Message.properties properties files, as well as the added
bonus in that we no longer need to pass in the location of where our
Message.properties file is like we do now -- we'd just use the class'
package name.

The trick would be performance.  On that regard we could unroll
upfront and do no backwards walking during actual usage or we could
backwards walk on demand and cache for future lookups.  Maybe some
other clever tricks we could do.

Thoughts?

-David




--
Karan Malhi

Reply via email to