----- "Phil Steitz" <phil.ste...@gmail.com> a écrit : > Gilles Sadowski wrote: > > Hi. > > > >>> I'd like to suggest that there could be a nicer way to handle > localization > >>> of error messages. Please have a look at > >>> http://cal10n.qos.ch/ > >> This looks promising, and I also considered developing a maven > plugin > >> with some asm magic to help make sure all messages are translated > >> properly. However, I wanted to have a tool that would be only use > at > >> build time. > > > > Could you explain, by examples, how you imagine the separation > between > > build time and run time?
At build time, you can check all defined messages are used and all messages do have an available translation in the supported locale. A very smart framework could even check the number of expected and provided arguments are equal. At run time, you only use the messages. > > > >>> Of course, the first point that will be raised is that it creates > an > >>> external dependency. Is this a "no-no" or, given some benefits, > could it be > >>> acceptable? > >> The runtime dependency is a no-no (at least from me). Is it > possible to > >> use only the build part and not the runtime part ? > > > > Maybe I'll understand this with the examples, but rigth now, I don't > see how > > it would be possible: localization is a runtime feature; so in order > to > > benefit from a library, it must (also) be a runtime dependency. > > Let's say that the compile time part creates a "dictionary" > structure, you'd > > still need the runtime to access it. If you don't want the > dependency, > > you'll need to re-implement all the look-up code that access the > > "dictionary" from its persistent format, with the danger that this > format > > can be subject to change without notice (as it is created by the > build time > > dependency which you accepted). Yes, you have to get the dictionary. The simplest is if your framework does all the checking for you in the build phase but does rely on a very simple access, for example simply reusing the basic Java properties files for example. The dictionary is static: one key, one value for each locale. There is no need for fancy formats for that. I don't see smart features like automatic reloading of messages useful: we hardly change them from release to release so don't care if we can't change them at runtime. > > > >>> Basically, I think that dealing with strings inside the math > library code is > >>> ugly and error-prone. E.g. > >>> > >>> throw MathRuntimeException.createIllegalArgumentException("{0} > out of [{1}, {2}] range", > >>> x, > xval[0], xval[xval.length - 1]); > >>> > >>> A simple spelling mistake will defeat the purpose, as the > localized version > >>> will not be found. > >> You are right. > > > > OK. So even without deciding on the use of an external library, can > we start > > using "enum"s (in a way similar to what "cal10n" does)? > > > >>> The above library takes care of this problem. > >>> > >>> Even so, I think that *messages* should not appear at this level. > It is much > >>> simpler to use a set of specific exceptions. I.e. instead of the > above > >>> statement, one would use: > >>> > >>> throw new OutOfRangeException(x, xval[0], xval[xval.length - > 1]); > >>> > >>> where the exception is defined as > >>> > >>> public OutOfRangeException extends IllegalArgumentException { > >>> private double val, min, max; > >>> > >>> public OutOfRangeException(val, min, max) { > >>> this.val = val; > >>> this.min = min; > >>> this.max = max; > >>> } > >>> > >>> public String getMessage() { > >>> // ... The string (or "enum" if using the "cal10n" > library) > >>> // should appear at this level. > >>> } > >>> } > >>> > >>> Admittedly, this means creating a lot of exception classes; but > the > >>> advantage is that they will allow more control. > >> Perhaps some intermediate solution with more exception classes than > we > >> have but not one class for each message. > > > > I didn't do an exhaustive search but it seems that there are a lot > of > > redundant message strings: > > > > "must have n >= 0 for binomial coefficient (n,k), got n = {0}" > > "must have n >= 0 for n!, got n = {0}" > > "brightness exponent should be positive or null, but got {0}" > > "number of microsphere elements must be positive, but got {0}" > > "polynomial degree must be positive: degree={0}" > > "upper bound must be positive ({0})" > > "length must be positive ({0})" > > "permutation k ({0}) must be positive" > > "invalid row dimension: {0} (must be positive)" > > "invalid column dimension: {0} (must be positive)" > > "initial capacity ({0}) is not positive" > > "index ({0}) is not positive" > > "window size must be positive ({0})" > > "element {0} is not positive: {1}" > > "mean must be positive ({0})" > > "degrees of freedom must be positive ({0})" > > "alpha must be positive ({0})" > > "beta must be positive ({0})" > > "number of successes must be non-negative ({0})" > > "standard deviation must be positive ({0})" > > "the Poisson mean must be positive ({0})" > > "invalid number of elements {0} (must be positive)" > > "invalid exponent {0} (must be positive)" > > "number of sample is not positive: {0}" > > > > I think that all of these could be reduced to one or two > exceptions. > > Not without losing information in some cases. alpha and beta are > different parameters in the context of the messages above, for > example. > > > Conceptually, the error is the same ("value should not be > negative"). > > The message supposedly gives more information than that, but > actually the > > additional info is redundant with the line number that is part of > the stack > > trace: from it, it's straightforward to figure out which input is > wrong; we > > don't need the message to specify that it is "alpha" or "beta" or > "mean" or > > "degree" etc. No, the message is intended to be displayed to users, but the stack trace may not. For example, the message can be directed in a message line at the bottom of some graphical user interface. The exception mechanism in Java wraps two different concepts in one class: the message and the stack trace. The first one is intended for end users that may even not know about the structure of the code and the stack trace is intended for developers. > > > >> At least, I agree the messages should be defined only once. > >> > >> Are there good localization framework with no runtime dependency > >> available somewhere ? > > > > I didn't find one. [Same question as above: How is such a thing > supposed to > > work?] > > > > Concerning localization itself, I think that it's not the business > of a > > low-level library. > > IMHO, CM should only be using exception objects. The Javadoc of > those > > exception classes and the "@throws" clauses are the places where the > users > > (i.e. *application* developers) can find the meaning and > circumstance of the > > problem. > > Strictly speaking, that won't work. You really do need a way to > minimally communicate parameter values or other exception context > information to application developers reading stack traces. There > is a reason that java.lang.Exception has a message property ;) > > Having spent many hours poring through stack traces as a developer > over the years, I have come to appreciate those who provide > meaningful messages with good context information. We do a decent > job of that in [math] now and I do not want to see us regress. I am > open to suggestions on how to make the localization more manageable, > though. It is a mild PITA to maintain now; but as I said above, it > is at least approachable. > > Phil > > > Now, if, for political reasons ;-), you want to help the users by > providing > > a localization framework, why couldn't we consider it as an > "add-on" > > higher-level *optional* feature requiring an external dependency? > > > > > > Best, > > Gilles > > > > > --------------------------------------------------------------------- > > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > > For additional commands, e-mail: dev-h...@commons.apache.org > > > > > --------------------------------------------------------------------- > To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org > For additional commands, e-mail: dev-h...@commons.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@commons.apache.org For additional commands, e-mail: dev-h...@commons.apache.org