On Jul 31, 2007, at 7:23 PM, Karan Malhi wrote:

I'm sorry if I scared you away from working on this.
Not at all. I learnt a lot from this discussion and the link which you
sent on the "LockFree HashMap" was invaluable. It was just that I
wasn't sure on what needs to be done because of different types of
logging frameworks and that I do not know enough to tell which logging
framework is better. I was just waiting for a concrete decision on
this topic and wanted to get this issue resolved  so that I could
start work on some documentation stuff.

Well, we'll need to support log4j for Geronimo anyway, so we could keep going with that for now. As long as we keep it hidden under the Logger class we can always abstract it out later and support both java.util.logging and log4j. But one change at a time, no need to make this too big to solve now. The it'll be great to get the hierarchical logging stuff in regardless of who is doing the actual logging.

On the note about making the logging code always do the i18n stuff and assume you're passing in a message key and array of details, that could work. There are a few places in the code where we need to log something and throw an exception and have been doing stuff like this:

String msg = messages.format("config.noContainerFound", d.getContainerId(), d.getEjbName());
        logger.fatal(msg);
        throw new OpenEJBException(msg);

But I suppose if we had each logger return the formatted message it could still be fine, such as:

String msg = logger.fatal("config.noContainerFound", d.getContainerId(), d.getEjbName());
        throw new OpenEJBException(msg);

Maybe even throw a method on the Logger to get the Messages instance out so people could still use it to construct error messages that aren't logged.

-David




On 7/30/07, Karan Malhi <[EMAIL PROTECTED]> wrote:
Sorry,

I see what you mean by a lock-free hashmap. The code is available on
sourceforge . I am not sure about the licensing stuff for this code
and need to know how to go about bringing in the jar into OpenEJB.

On 7/27/07, Karan Malhi <[EMAIL PROTECTED]> wrote:
David,


I did implement using ConcurrentHashMap and a Memoizer. You had
suggested a
LockFreeHashMap in an earlier mail also. The way I did it is
that  once a
ResourceBundle is computed, it is cached and the same
ResourceBundle is
never computed again. Also, if a key is not found in a properties
file of a
sub-package, it is looked up in the parent package and so on.


On 7/27/07, David Jencks <[EMAIL PROTECTED]> wrote:

On Jul 27, 2007, at 4:20 PM, Karan Malhi wrote:

So I have re-written logging using java.util.Logging.

Is there general agreement this is a good idea? I have yet to talk
in person to anyone who likes java.util.Logging.

There are some issues
which are blockers right now
1. The logging levels are different between log4j and
java.util.logging. Can
anybody suggest how these should be mapped
2. Most of the logging being done right now is not using
Messages.propertiesfile (i18n) . What i wrote, solely assumes
that one
is using the keys from
Messages.properties. How do we want to do this, should all logging
be done
through Messages.properties or should one be allowed to log
messages without
Messages.properties. I would prefer to go through
Messages.properties, I
need to know your opinion. This is lots of work for me if we go
through
Messages.properties (and probably we can share it so that we can
clean up
logging faster), and I want to make sure that once we decide upon
it, we
stick to it. This way the logging framework itself will force the
user to
use Messages.properties.

On 6/24/07, Karan Malhi <[EMAIL PROTECTED]> wrote:

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.
Correct. The second part of my email talks about "namespacing"
which
is kind of on the same lines as what you are saying here .

I guess these can be combined to some extent -- precomputing
all the
"specified virtual keys" and then adding more as they are used.
What does adding more as they are used means?. Would'nt all
keys be
"specified virtual keys" and be precomputed? I assume by pre-
computing
you mean "go through every messages.properties and cache the
keys"

This could be a good use for the lock-free hash map :-)
and that would be the
java.util.concurrent.ConcurrentHashMap,
correct?

no, that one has plenty of locking.  I was thinking of the one
described at javaone...

http://www.azulsystems.com/events/ javaone_2007/2007_LockFreeHash.pdf

thanks
david jencks


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




--
Karan Malhi




--
Karan Singh Malhi





--
Karan Singh Malhi


--
Karan Singh Malhi



--
Karan Singh Malhi




--
Karan Singh Malhi


Reply via email to