On Sat, Jun 25, 2016 at 4:02 PM, Ralph Goers <[email protected]>
wrote:

> Why wouldn’t you just do:
>
> %m{ansi}
> %m{html}
> %m{styled}
>

Please see my experiment in the branch called StyledMessage.

Tests:

org.apache.logging.log4j.core.pattern.MessageJansiConverterTest
org.apache.logging.log4j.core.pattern.MessageStyledConverterTest

Sample config fragment from
log4j-core/src/test/resources/log4j-message-styled.xml:

<Pattern>%message{ansi}{WarningStyle=red,bold DataStyle=blue}%n</Pattern>

Code without styles:

logger.error("@|red,bold Warning!|@ Pants on @|red fire!|@");

Code with styles:

logger.error("@|WarningStyle Warning!|@ Pants on @|WarningStyle fire!|@");

Gary


>
> Ralph
>
> On Jun 25, 2016, at 3:09 PM, Gary Gregory <[email protected]> wrote:
>
> Rambling thoughts:
>
> I use the term message as the message string from the log event (probably
> after parameters has been processed.)
>
> - Add to PatternLayout a %ansiMessage, use that instead of %m and the
> layout will rewrite the message as an ANSI message. Use that on a file
> layout and you get ANSI codes in your file.
> - Add to PatternLayout a %htmlMessage, use that instead of %m and the
> layout will rewrite the message as an HTML fragment. The produced HTML
> would not be a whole HTML document, just a fragment that fits in an HTML
> page/
>
> More general:
>
> Add to PatternLayout a %styledMessage, use that instead of %m and:
> - A console appends rewrites the message as an ANSI message.
> - An HTML layout rewrites the message as an HTML fragment.
>
> The message syntax is TDB.
>
> My focus in on the console appender but thinking about HTML as well helps
> consider a more general solution (I hope).
>
> Gary
>
>
>
> On Sat, Jun 25, 2016 at 2:51 PM, Paul Benedict <[email protected]>
> wrote:
>
>> Do you guys have a policy like HTML for ignoring unknown tags/styles when
>> parsing a message? So if a message is, for example, "Hey {%s color:red}",
>> and the formatter doesn't support colors, it completely ignores the
>> "color:red" token? I am implying a backward and forward compatibility.
>>
>> Cheers,
>> Paul
>>
>> On Sat, Jun 25, 2016 at 2:16 PM, Gary Gregory <[email protected]>
>> wrote:
>>
>>> I meant something like (b). I used the word "render" to try to convey a
>>> different concept form "formatting" a message with its parameter. An
>>> appender knows how to render a formatted message on itself.
>>>
>>> The question is how to get no styles on certain appenders and layouts
>>> seem to be one good place to do it if I set up that layout for just the one
>>> appender that needs it.
>>>
>>> Gary
>>> ?
>>>
>>> Every appender accepts a Layout for rendering and they all use one. A
>>> File appender can use a Pattern layout, a JSON layout, etc. So it is
>>> incorrect to say any appender wants no rendering.
>>>
>>> I think what you are really wanting is a way to either a) enhance the
>>> Message.getFormattedMessage() to process the styles in accordance with the
>>> Appender type or b) have the Appender process the styles after
>>> getFormattedMessage() is called. Architecturally, I like the idea of having
>>> the Message handle it but it may be harder to implement.
>>>
>>> Ralph
>>>
>>>
>>> On Jun 24, 2016, at 12:22 PM, Gary Gregory <[email protected]>
>>> wrote:
>>>
>>> Since an HTML layout and a Console JAnsi layout need different
>>> interpretation of the message string, why not allow each appender to do its
>>> own rendering? Also, you want no rendering for other appenders like file,
>>> JMS, and so on.
>>>
>>> Gary
>>> On Jun 24, 2016 11:07 AM, "Ralph Goers" <[email protected]>
>>> wrote:
>>>
>>>> Yes. Of course the converter would need to be aware what the target is,
>>>> which I am not sure is currently available.  In this case I would think you
>>>> would want to just enhance the %m converter to support these new plugins,
>>>> rather than creating a new message converter.
>>>>
>>>> If you didn’t want to have the output formatted differently depending
>>>> on the target I could see having the formatting being done in the Message.
>>>>
>>>> Ralph
>>>>
>>>> On Jun 24, 2016, at 10:37 AM, Gary Gregory <[email protected]>
>>>> wrote:
>>>>
>>>> Thank you for the feedback.
>>>>
>>>> I can see that I could invent a new kind of %m converter that parses
>>>> the message and does the coloring. I could have an ANSI kind of %m, an HTML
>>>> %m, and so on.
>>>>
>>>> Gary
>>>> On Jun 24, 2016 10:00 AM, "Ralph Goers" <[email protected]>
>>>> wrote:
>>>>
>>>>>
>>>>> I am not sure I get this idea at all.  First, I would expect that
>>>>> “styles” would be plugins much as converters are for the PatternLayout. 
>>>>> But
>>>>> it isn’t clear to me at all why I would want or require a StyledMessage to
>>>>> do that.  If you want to support “styles” then implement the support in 
>>>>> the
>>>>> appropriate layouts. The message should just contain the information the
>>>>> styles need to render them.
>>>>>
>>>>> Also, is StyledMessage an Interface?  If it is a class is it a
>>>>> ParameterizedMessage, SimpleMessage, etc, or are you planning on having a
>>>>> “Styled” version of each Message type. I am not in favor of that at all.
>>>>>
>>>>> I am also not sure how this handles the issue you mentioned at the
>>>>> start of this thread - that the color codes written to files don’t cause
>>>>> the colors to show up and only render properly on the console.
>>>>>
>>>>> Ralph
>>>>>
>>>>> On Jun 24, 2016, at 8:43 AM, Gary Gregory <[email protected]>
>>>>> wrote:
>>>>>
>>>>> Another question is what should the syntax be for a StyledMessage? The
>>>>> same as for a pattern layout (
>>>>> https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout)?
>>>>> Something else? Could it be simpler and still allow for parameters and
>>>>> escaping?
>>>>>
>>>>> SyledMessageFactory factory = SyledMessageFactory.load( ...styles... );
>>>>> item = "pants";
>>>>> // Using pattern layout kind of format with parameter markers.
>>>>> logger.error("Your {} are on {fire!}{criticalMassStyle},
>>>>> {notifying}{peacfulStyle}{}", item);
>>>>> logger.error("Your %s are on {fire!}{criticalMassStyle},
>>>>> {notifying}{peacfulStyle}%s", item);
>>>>>
>>>>> Gary
>>>>>
>>>>> On Tue, Jun 21, 2016 at 6:39 PM, Remko Popma <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> After thinking about it some more, I agree with you guys that the
>>>>>> string syntax seems like a better idea.
>>>>>>
>>>>>>
>>>>>> On Wednesday, 22 June 2016, Gary Gregory <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>>> On Mon, Jun 20, 2016 at 4:14 PM, Remko Popma <[email protected]>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> What if we keep the same or similar syntax but with Log4j2 imports,
>>>>>>>> and we use it to build a custom Message?
>>>>>>>>
>>>>>>>> So, this java code logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a("
>>>>>>>> World").reset());
>>>>>>>> would result in a JansiMessage containing a "Hello" string
>>>>>>>> associated with a RED object, and a " World" string associated with the
>>>>>>>> CYAN object. At this stage, nothing is rendered yet.
>>>>>>>>
>>>>>>>
>>>>>>> I would prefer to avoid a vendor specific message class and name. I
>>>>>>> think the Maven folks are experiencing growing pains now that they have
>>>>>>> enabled color within Maven messages. I think a StyledMessage would be 
>>>>>>> the
>>>>>>> way to go.
>>>>>>>
>>>>>>> When a StyledMessage goes to a Console appender, JAnsi is used, when
>>>>>>> it does to an HTML appender, HTML is used. Whether you build a
>>>>>>> StyledMessage with a fluent API, a string syntax or both is another 
>>>>>>> matter,
>>>>>>> but the string syntax seems simplest.
>>>>>>>
>>>>>>> Gary
>>>>>>>
>>>>>>>
>>>>>>>> The Console Appender's PatternLayout, when the Jansi option is
>>>>>>>> enabled, could call JansiMessage.generateJansiFormattedMessage() which
>>>>>>>> contains the escape codes for the console.
>>>>>>>>
>>>>>>>> The File Appender's PatternLayout does not have the Jansi option
>>>>>>>> enabled, so the normal Message.getFormattedMessage() is called, 
>>>>>>>> resulting
>>>>>>>> in the plain string "Hello World".
>>>>>>>>
>>>>>>>> One key consideration is that all the objects used to build the
>>>>>>>> message should be in the Log4j API namespace to avoid any dependency on
>>>>>>>> Jansi at the API level. (But things like RED etc can be inner classes 
>>>>>>>> of
>>>>>>>> JansiMessage. Static imports can make this painless to use.)
>>>>>>>>
>>>>>>>>
>>>>>>>> On Tue, Jun 21, 2016 at 3:59 AM, Paul Benedict <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> It's pretty cool. Yes, a generalized syntax is very nice. Do your
>>>>>>>>> best to make the syntax general -- and if for, for whatever reason, an
>>>>>>>>> appender needs something more explicit/specific, those options can 
>>>>>>>>> just be
>>>>>>>>> provided by the appender's custom parsing.
>>>>>>>>>
>>>>>>>>> Cheers,
>>>>>>>>> Paul
>>>>>>>>>
>>>>>>>>> On Mon, Jun 20, 2016 at 1:44 PM, Gary Gregory <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> I think like the idea of having a special syntax for colors, for
>>>>>>>>>> rendering of styles in general actually, because we could have this
>>>>>>>>>> implemented for the Jansi+Console appender, for the HTML appender, 
>>>>>>>>>> and you
>>>>>>>>>> could also imagine an RTF appender.
>>>>>>>>>>
>>>>>>>>>> Gary
>>>>>>>>>>
>>>>>>>>>> On Thu, Jun 16, 2016 at 12:59 PM, Gary Gregory <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> On Thu, Jun 16, 2016 at 12:48 PM, Paul Benedict <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> I imagine parsing the placeholder is going to be expensive
>>>>>>>>>>>> (relatively speaking). It is an extra cost.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> We already support different ways to paramaterize messages [1]:
>>>>>>>>>>> {}, %s (and family), java.text.MessageFormat, and so on. Each has 
>>>>>>>>>>> its
>>>>>>>>>>> different overhead.
>>>>>>>>>>>
>>>>>>>>>>> This could be a variation of the ParameterizedMessage class for
>>>>>>>>>>> example. Or maybe an extension of to one or more other message 
>>>>>>>>>>> types.
>>>>>>>>>>>
>>>>>>>>>>> Gary
>>>>>>>>>>>
>>>>>>>>>>> [1] https://logging.apache.org/log4j/2.x/manual/messages.html
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>> I advise devising a new interface that appenders can implement
>>>>>>>>>>>> to receive the parsed tokens. If the interface is missing, no 
>>>>>>>>>>>> parsing
>>>>>>>>>>>> in-between is necessary. Otherwise, send the tokens to the 
>>>>>>>>>>>> appender as a
>>>>>>>>>>>> callback for it to make the necessary modifications -- such as 
>>>>>>>>>>>> setting the
>>>>>>>>>>>> color.
>>>>>>>>>>>>
>>>>>>>>>>>> Cheers,
>>>>>>>>>>>> Paul
>>>>>>>>>>>>
>>>>>>>>>>>> On Thu, Jun 16, 2016 at 1:53 PM, Gary Gregory <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Jun 16, 2016 11:25 AM, "Paul Benedict" <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >
>>>>>>>>>>>>> > Are you asking me for blue sky thinking, perhaps something
>>>>>>>>>>>>> like this:
>>>>>>>>>>>>> > log.info("Hello, {color:green}, how are you?", "Gary");
>>>>>>>>>>>>> >
>>>>>>>>>>>>> > For this example, I took the {} placeholder and added some
>>>>>>>>>>>>> context.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Ok yes, that's what I was talking about. Also:
>>>>>>>>>>>>>
>>>>>>>>>>>>> log.info("Hello {color:green Gary}, how are you?");
>>>>>>>>>>>>>
>>>>>>>>>>>>> Gary
>>>>>>>>>>>>> >
>>>>>>>>>>>>> > Cheers,
>>>>>>>>>>>>> > Paul
>>>>>>>>>>>>> >
>>>>>>>>>>>>> > On Thu, Jun 16, 2016 at 1:22 PM, Gary Gregory <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >> On Thu, Jun 16, 2016 at 11:04 AM, Paul Benedict <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>> I think color falls into the category of formatting. By
>>>>>>>>>>>>> that, I mean to state that colors shouldn't be hardcoded into 
>>>>>>>>>>>>> messages :-)
>>>>>>>>>>>>> That should belong to the actual formatter... template string or 
>>>>>>>>>>>>> appender
>>>>>>>>>>>>> configuration.
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >> What would that look like? I do not see how do to that
>>>>>>>>>>>>> without creating a lot of custom code.
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >> Gary
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>> Cheers,
>>>>>>>>>>>>> >>> Paul
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>> On Thu, Jun 16, 2016 at 12:58 PM, Gary Gregory <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> On Thu, Jun 16, 2016 at 10:39 AM, Gary Gregory <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>> On Wed, Jun 15, 2016 at 10:50 PM, Gary Gregory <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> Hi All,
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> See color messages in Maven 3.4.0-SNAPSHOT made me
>>>>>>>>>>>>> think of the following.
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> Right now, with Jansi on the CP, I can say:
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> import static org.fusesource.jansi.Ansi.*;
>>>>>>>>>>>>> >>>>>> import static org.fusesource.jansi.Ansi.Color.*;
>>>>>>>>>>>>> >>>>>> ...
>>>>>>>>>>>>> >>>>>> logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a("
>>>>>>>>>>>>> World").reset());
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> and the right thing happens on the console.
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> If I also have a file appender, I get the escape codes
>>>>>>>>>>>>> in the file, which I do not think most people would want.
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> The question is, how can we make it simple for users to
>>>>>>>>>>>>> have their cake and eat it too?
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> With a special Message implementation?
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> Thoughts?
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>> One way would be to have the non-a() methods (plus
>>>>>>>>>>>>> reset()) become no-ops when not using a console appender. But 
>>>>>>>>>>>>> how? We could
>>>>>>>>>>>>> have a subclass of JAnsi's Ansi class that gets used. Anyway, I'm 
>>>>>>>>>>>>> just
>>>>>>>>>>>>> rambling.
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Still rambling, mostly so I have a place to look back for
>>>>>>>>>>>>> these notes:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> - nope, the reset() method would need to be noop'd.
>>>>>>>>>>>>> >>>> - Example of a color message:
>>>>>>>>>>>>> org.apache.logging.log4j.core.appender.ConsoleAppenderJAnsiMessageMain
>>>>>>>>>>>>> >>>> - JAnsi also supports a special syntax, for example:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> "@|red Hello|@ @|cyan World|@"
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> but if use that like:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info("@|red Hello|@ @|cyan World|@");
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> JAnsi rendering does not kick in unsurprisingly.
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Maybe the Console appender could make sure the JAnsi
>>>>>>>>>>>>> renderer is used (optional), so that
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info(ansi().render("@|red Hello|@ @|green
>>>>>>>>>>>>> World|@");
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> can become:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info("@|red Hello|@ @|green World|@");
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> and then we can add a renderJansi option to the console
>>>>>>>>>>>>> appender but... the decorations still end up in a file appender 
>>>>>>>>>>>>> so we are
>>>>>>>>>>>>> still in the same pickle.
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Thinking about a MessageRenderer (String render(String))
>>>>>>>>>>>>> interface with two impl: one that calls ansi().render(String) for 
>>>>>>>>>>>>> console
>>>>>>>>>>>>> appenders (optionally, if renderJansi=true) and another that 
>>>>>>>>>>>>> strips the
>>>>>>>>>>>>> decorations (but this feels heavy).
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> More rambling:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Instead of:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a("
>>>>>>>>>>>>> World").reset());
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> say:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info((Ansi ansi) ->
>>>>>>>>>>>>> ansi.fg(RED).a("Hello").fg(CYAN).a(" World").reset());
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Then we can pass in a custom Ansi subclass that only
>>>>>>>>>>>>> outputs the string bits, no escape codes.
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Gary
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>> Gary
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> Thank you,
>>>>>>>>>>>>> >>>>>> Gary
>>>>>>>>>>>>> >>>>>> --
>>>>>>>>>>>>> >>>>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>>>>> >>>>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>>>> >>>>>> JUnit in Action, Second Edition
>>>>>>>>>>>>> >>>>>> Spring Batch in Action
>>>>>>>>>>>>> >>>>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>>>>> >>>>>> Home: http://garygregory.com/
>>>>>>>>>>>>> >>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>> --
>>>>>>>>>>>>> >>>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>>>>> >>>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>>>> >>>>> JUnit in Action, Second Edition
>>>>>>>>>>>>> >>>>> Spring Batch in Action
>>>>>>>>>>>>> >>>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>>>>> >>>>> Home: http://garygregory.com/
>>>>>>>>>>>>> >>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> --
>>>>>>>>>>>>> >>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>>>>> >>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>>>> >>>> JUnit in Action, Second Edition
>>>>>>>>>>>>> >>>> Spring Batch in Action
>>>>>>>>>>>>> >>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>>>>> >>>> Home: http://garygregory.com/
>>>>>>>>>>>>> >>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >> --
>>>>>>>>>>>>> >> E-Mail: [email protected] | [email protected]
>>>>>>>>>>>>> >> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>>>> >> JUnit in Action, Second Edition
>>>>>>>>>>>>> >> Spring Batch in Action
>>>>>>>>>>>>> >> Blog: http://garygregory.wordpress.com
>>>>>>>>>>>>> >> Home: http://garygregory.com/
>>>>>>>>>>>>> >> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>>> >
>>>>>>>>>>>>> >
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>> <http://www.manning.com/bauer3/>
>>>>>>>>>>> JUnit in Action, Second Edition
>>>>>>>>>>> <http://www.manning.com/tahchiev/>
>>>>>>>>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>>>>>>>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>>> Home: http://garygregory.com/
>>>>>>>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>> <http://www.manning.com/bauer3/>
>>>>>>>>>> JUnit in Action, Second Edition
>>>>>>>>>> <http://www.manning.com/tahchiev/>
>>>>>>>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>>>>>>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>> Home: http://garygregory.com/
>>>>>>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> E-Mail: [email protected] | [email protected]
>>>>>>> Java Persistence with Hibernate, Second Edition
>>>>>>> <http://www.manning.com/bauer3/>
>>>>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>>>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>>>>> Blog: http://garygregory.wordpress.com
>>>>>>> Home: http://garygregory.com/
>>>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> E-Mail: [email protected] | [email protected]
>>>>> Java Persistence with Hibernate, Second Edition
>>>>> <http://www.manning.com/bauer3/>
>>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>>> Blog: http://garygregory.wordpress.com
>>>>> Home: http://garygregory.com/
>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>
>
> --
> E-Mail: [email protected] | [email protected]
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>
>
>


-- 
E-Mail: [email protected] | [email protected]
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

On Sat, Jun 25, 2016 at 4:02 PM, Ralph Goers <[email protected]>
wrote:

> Why wouldn’t you just do:
>
> %m{ansi}
> %m{html}
> %m{styled}
>
> Ralph
>
> On Jun 25, 2016, at 3:09 PM, Gary Gregory <[email protected]> wrote:
>
> Rambling thoughts:
>
> I use the term message as the message string from the log event (probably
> after parameters has been processed.)
>
> - Add to PatternLayout a %ansiMessage, use that instead of %m and the
> layout will rewrite the message as an ANSI message. Use that on a file
> layout and you get ANSI codes in your file.
> - Add to PatternLayout a %htmlMessage, use that instead of %m and the
> layout will rewrite the message as an HTML fragment. The produced HTML
> would not be a whole HTML document, just a fragment that fits in an HTML
> page/
>
> More general:
>
> Add to PatternLayout a %styledMessage, use that instead of %m and:
> - A console appends rewrites the message as an ANSI message.
> - An HTML layout rewrites the message as an HTML fragment.
>
> The message syntax is TDB.
>
> My focus in on the console appender but thinking about HTML as well helps
> consider a more general solution (I hope).
>
> Gary
>
>
>
> On Sat, Jun 25, 2016 at 2:51 PM, Paul Benedict <[email protected]>
> wrote:
>
>> Do you guys have a policy like HTML for ignoring unknown tags/styles when
>> parsing a message? So if a message is, for example, "Hey {%s color:red}",
>> and the formatter doesn't support colors, it completely ignores the
>> "color:red" token? I am implying a backward and forward compatibility.
>>
>> Cheers,
>> Paul
>>
>> On Sat, Jun 25, 2016 at 2:16 PM, Gary Gregory <[email protected]>
>> wrote:
>>
>>> I meant something like (b). I used the word "render" to try to convey a
>>> different concept form "formatting" a message with its parameter. An
>>> appender knows how to render a formatted message on itself.
>>>
>>> The question is how to get no styles on certain appenders and layouts
>>> seem to be one good place to do it if I set up that layout for just the one
>>> appender that needs it.
>>>
>>> Gary
>>> ?
>>>
>>> Every appender accepts a Layout for rendering and they all use one. A
>>> File appender can use a Pattern layout, a JSON layout, etc. So it is
>>> incorrect to say any appender wants no rendering.
>>>
>>> I think what you are really wanting is a way to either a) enhance the
>>> Message.getFormattedMessage() to process the styles in accordance with the
>>> Appender type or b) have the Appender process the styles after
>>> getFormattedMessage() is called. Architecturally, I like the idea of having
>>> the Message handle it but it may be harder to implement.
>>>
>>> Ralph
>>>
>>>
>>> On Jun 24, 2016, at 12:22 PM, Gary Gregory <[email protected]>
>>> wrote:
>>>
>>> Since an HTML layout and a Console JAnsi layout need different
>>> interpretation of the message string, why not allow each appender to do its
>>> own rendering? Also, you want no rendering for other appenders like file,
>>> JMS, and so on.
>>>
>>> Gary
>>> On Jun 24, 2016 11:07 AM, "Ralph Goers" <[email protected]>
>>> wrote:
>>>
>>>> Yes. Of course the converter would need to be aware what the target is,
>>>> which I am not sure is currently available.  In this case I would think you
>>>> would want to just enhance the %m converter to support these new plugins,
>>>> rather than creating a new message converter.
>>>>
>>>> If you didn’t want to have the output formatted differently depending
>>>> on the target I could see having the formatting being done in the Message.
>>>>
>>>> Ralph
>>>>
>>>> On Jun 24, 2016, at 10:37 AM, Gary Gregory <[email protected]>
>>>> wrote:
>>>>
>>>> Thank you for the feedback.
>>>>
>>>> I can see that I could invent a new kind of %m converter that parses
>>>> the message and does the coloring. I could have an ANSI kind of %m, an HTML
>>>> %m, and so on.
>>>>
>>>> Gary
>>>> On Jun 24, 2016 10:00 AM, "Ralph Goers" <[email protected]>
>>>> wrote:
>>>>
>>>>>
>>>>> I am not sure I get this idea at all.  First, I would expect that
>>>>> “styles” would be plugins much as converters are for the PatternLayout. 
>>>>> But
>>>>> it isn’t clear to me at all why I would want or require a StyledMessage to
>>>>> do that.  If you want to support “styles” then implement the support in 
>>>>> the
>>>>> appropriate layouts. The message should just contain the information the
>>>>> styles need to render them.
>>>>>
>>>>> Also, is StyledMessage an Interface?  If it is a class is it a
>>>>> ParameterizedMessage, SimpleMessage, etc, or are you planning on having a
>>>>> “Styled” version of each Message type. I am not in favor of that at all.
>>>>>
>>>>> I am also not sure how this handles the issue you mentioned at the
>>>>> start of this thread - that the color codes written to files don’t cause
>>>>> the colors to show up and only render properly on the console.
>>>>>
>>>>> Ralph
>>>>>
>>>>> On Jun 24, 2016, at 8:43 AM, Gary Gregory <[email protected]>
>>>>> wrote:
>>>>>
>>>>> Another question is what should the syntax be for a StyledMessage? The
>>>>> same as for a pattern layout (
>>>>> https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout)?
>>>>> Something else? Could it be simpler and still allow for parameters and
>>>>> escaping?
>>>>>
>>>>> SyledMessageFactory factory = SyledMessageFactory.load( ...styles... );
>>>>> item = "pants";
>>>>> // Using pattern layout kind of format with parameter markers.
>>>>> logger.error("Your {} are on {fire!}{criticalMassStyle},
>>>>> {notifying}{peacfulStyle}{}", item);
>>>>> logger.error("Your %s are on {fire!}{criticalMassStyle},
>>>>> {notifying}{peacfulStyle}%s", item);
>>>>>
>>>>> Gary
>>>>>
>>>>> On Tue, Jun 21, 2016 at 6:39 PM, Remko Popma <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> After thinking about it some more, I agree with you guys that the
>>>>>> string syntax seems like a better idea.
>>>>>>
>>>>>>
>>>>>> On Wednesday, 22 June 2016, Gary Gregory <[email protected]>
>>>>>> wrote:
>>>>>>
>>>>>>> On Mon, Jun 20, 2016 at 4:14 PM, Remko Popma <[email protected]>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> What if we keep the same or similar syntax but with Log4j2 imports,
>>>>>>>> and we use it to build a custom Message?
>>>>>>>>
>>>>>>>> So, this java code logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a("
>>>>>>>> World").reset());
>>>>>>>> would result in a JansiMessage containing a "Hello" string
>>>>>>>> associated with a RED object, and a " World" string associated with the
>>>>>>>> CYAN object. At this stage, nothing is rendered yet.
>>>>>>>>
>>>>>>>
>>>>>>> I would prefer to avoid a vendor specific message class and name. I
>>>>>>> think the Maven folks are experiencing growing pains now that they have
>>>>>>> enabled color within Maven messages. I think a StyledMessage would be 
>>>>>>> the
>>>>>>> way to go.
>>>>>>>
>>>>>>> When a StyledMessage goes to a Console appender, JAnsi is used, when
>>>>>>> it does to an HTML appender, HTML is used. Whether you build a
>>>>>>> StyledMessage with a fluent API, a string syntax or both is another 
>>>>>>> matter,
>>>>>>> but the string syntax seems simplest.
>>>>>>>
>>>>>>> Gary
>>>>>>>
>>>>>>>
>>>>>>>> The Console Appender's PatternLayout, when the Jansi option is
>>>>>>>> enabled, could call JansiMessage.generateJansiFormattedMessage() which
>>>>>>>> contains the escape codes for the console.
>>>>>>>>
>>>>>>>> The File Appender's PatternLayout does not have the Jansi option
>>>>>>>> enabled, so the normal Message.getFormattedMessage() is called, 
>>>>>>>> resulting
>>>>>>>> in the plain string "Hello World".
>>>>>>>>
>>>>>>>> One key consideration is that all the objects used to build the
>>>>>>>> message should be in the Log4j API namespace to avoid any dependency on
>>>>>>>> Jansi at the API level. (But things like RED etc can be inner classes 
>>>>>>>> of
>>>>>>>> JansiMessage. Static imports can make this painless to use.)
>>>>>>>>
>>>>>>>>
>>>>>>>> On Tue, Jun 21, 2016 at 3:59 AM, Paul Benedict <
>>>>>>>> [email protected]> wrote:
>>>>>>>>
>>>>>>>>> It's pretty cool. Yes, a generalized syntax is very nice. Do your
>>>>>>>>> best to make the syntax general -- and if for, for whatever reason, an
>>>>>>>>> appender needs something more explicit/specific, those options can 
>>>>>>>>> just be
>>>>>>>>> provided by the appender's custom parsing.
>>>>>>>>>
>>>>>>>>> Cheers,
>>>>>>>>> Paul
>>>>>>>>>
>>>>>>>>> On Mon, Jun 20, 2016 at 1:44 PM, Gary Gregory <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> I think like the idea of having a special syntax for colors, for
>>>>>>>>>> rendering of styles in general actually, because we could have this
>>>>>>>>>> implemented for the Jansi+Console appender, for the HTML appender, 
>>>>>>>>>> and you
>>>>>>>>>> could also imagine an RTF appender.
>>>>>>>>>>
>>>>>>>>>> Gary
>>>>>>>>>>
>>>>>>>>>> On Thu, Jun 16, 2016 at 12:59 PM, Gary Gregory <
>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>
>>>>>>>>>>> On Thu, Jun 16, 2016 at 12:48 PM, Paul Benedict <
>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>
>>>>>>>>>>>> I imagine parsing the placeholder is going to be expensive
>>>>>>>>>>>> (relatively speaking). It is an extra cost.
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> We already support different ways to paramaterize messages [1]:
>>>>>>>>>>> {}, %s (and family), java.text.MessageFormat, and so on. Each has 
>>>>>>>>>>> its
>>>>>>>>>>> different overhead.
>>>>>>>>>>>
>>>>>>>>>>> This could be a variation of the ParameterizedMessage class for
>>>>>>>>>>> example. Or maybe an extension of to one or more other message 
>>>>>>>>>>> types.
>>>>>>>>>>>
>>>>>>>>>>> Gary
>>>>>>>>>>>
>>>>>>>>>>> [1] https://logging.apache.org/log4j/2.x/manual/messages.html
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>> I advise devising a new interface that appenders can implement
>>>>>>>>>>>> to receive the parsed tokens. If the interface is missing, no 
>>>>>>>>>>>> parsing
>>>>>>>>>>>> in-between is necessary. Otherwise, send the tokens to the 
>>>>>>>>>>>> appender as a
>>>>>>>>>>>> callback for it to make the necessary modifications -- such as 
>>>>>>>>>>>> setting the
>>>>>>>>>>>> color.
>>>>>>>>>>>>
>>>>>>>>>>>> Cheers,
>>>>>>>>>>>> Paul
>>>>>>>>>>>>
>>>>>>>>>>>> On Thu, Jun 16, 2016 at 1:53 PM, Gary Gregory <
>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>
>>>>>>>>>>>>>
>>>>>>>>>>>>> On Jun 16, 2016 11:25 AM, "Paul Benedict" <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >
>>>>>>>>>>>>> > Are you asking me for blue sky thinking, perhaps something
>>>>>>>>>>>>> like this:
>>>>>>>>>>>>> > log.info("Hello, {color:green}, how are you?", "Gary");
>>>>>>>>>>>>> >
>>>>>>>>>>>>> > For this example, I took the {} placeholder and added some
>>>>>>>>>>>>> context.
>>>>>>>>>>>>>
>>>>>>>>>>>>> Ok yes, that's what I was talking about. Also:
>>>>>>>>>>>>>
>>>>>>>>>>>>> log.info("Hello {color:green Gary}, how are you?");
>>>>>>>>>>>>>
>>>>>>>>>>>>> Gary
>>>>>>>>>>>>> >
>>>>>>>>>>>>> > Cheers,
>>>>>>>>>>>>> > Paul
>>>>>>>>>>>>> >
>>>>>>>>>>>>> > On Thu, Jun 16, 2016 at 1:22 PM, Gary Gregory <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >> On Thu, Jun 16, 2016 at 11:04 AM, Paul Benedict <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>> I think color falls into the category of formatting. By
>>>>>>>>>>>>> that, I mean to state that colors shouldn't be hardcoded into 
>>>>>>>>>>>>> messages :-)
>>>>>>>>>>>>> That should belong to the actual formatter... template string or 
>>>>>>>>>>>>> appender
>>>>>>>>>>>>> configuration.
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >> What would that look like? I do not see how do to that
>>>>>>>>>>>>> without creating a lot of custom code.
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >> Gary
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>> Cheers,
>>>>>>>>>>>>> >>> Paul
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>> On Thu, Jun 16, 2016 at 12:58 PM, Gary Gregory <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> On Thu, Jun 16, 2016 at 10:39 AM, Gary Gregory <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>> On Wed, Jun 15, 2016 at 10:50 PM, Gary Gregory <
>>>>>>>>>>>>> [email protected]> wrote:
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> Hi All,
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> See color messages in Maven 3.4.0-SNAPSHOT made me
>>>>>>>>>>>>> think of the following.
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> Right now, with Jansi on the CP, I can say:
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> import static org.fusesource.jansi.Ansi.*;
>>>>>>>>>>>>> >>>>>> import static org.fusesource.jansi.Ansi.Color.*;
>>>>>>>>>>>>> >>>>>> ...
>>>>>>>>>>>>> >>>>>> logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a("
>>>>>>>>>>>>> World").reset());
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> and the right thing happens on the console.
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> If I also have a file appender, I get the escape codes
>>>>>>>>>>>>> in the file, which I do not think most people would want.
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> The question is, how can we make it simple for users to
>>>>>>>>>>>>> have their cake and eat it too?
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> With a special Message implementation?
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> Thoughts?
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>> One way would be to have the non-a() methods (plus
>>>>>>>>>>>>> reset()) become no-ops when not using a console appender. But 
>>>>>>>>>>>>> how? We could
>>>>>>>>>>>>> have a subclass of JAnsi's Ansi class that gets used. Anyway, I'm 
>>>>>>>>>>>>> just
>>>>>>>>>>>>> rambling.
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Still rambling, mostly so I have a place to look back for
>>>>>>>>>>>>> these notes:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> - nope, the reset() method would need to be noop'd.
>>>>>>>>>>>>> >>>> - Example of a color message:
>>>>>>>>>>>>> org.apache.logging.log4j.core.appender.ConsoleAppenderJAnsiMessageMain
>>>>>>>>>>>>> >>>> - JAnsi also supports a special syntax, for example:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> "@|red Hello|@ @|cyan World|@"
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> but if use that like:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info("@|red Hello|@ @|cyan World|@");
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> JAnsi rendering does not kick in unsurprisingly.
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Maybe the Console appender could make sure the JAnsi
>>>>>>>>>>>>> renderer is used (optional), so that
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info(ansi().render("@|red Hello|@ @|green
>>>>>>>>>>>>> World|@");
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> can become:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info("@|red Hello|@ @|green World|@");
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> and then we can add a renderJansi option to the console
>>>>>>>>>>>>> appender but... the decorations still end up in a file appender 
>>>>>>>>>>>>> so we are
>>>>>>>>>>>>> still in the same pickle.
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Thinking about a MessageRenderer (String render(String))
>>>>>>>>>>>>> interface with two impl: one that calls ansi().render(String) for 
>>>>>>>>>>>>> console
>>>>>>>>>>>>> appenders (optionally, if renderJansi=true) and another that 
>>>>>>>>>>>>> strips the
>>>>>>>>>>>>> decorations (but this feels heavy).
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> More rambling:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Instead of:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info(ansi().fg(RED).a("Hello").fg(CYAN).a("
>>>>>>>>>>>>> World").reset());
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> say:
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> logger.info((Ansi ansi) ->
>>>>>>>>>>>>> ansi.fg(RED).a("Hello").fg(CYAN).a(" World").reset());
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Then we can pass in a custom Ansi subclass that only
>>>>>>>>>>>>> outputs the string bits, no escape codes.
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> Gary
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>> Gary
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>>
>>>>>>>>>>>>> >>>>>> Thank you,
>>>>>>>>>>>>> >>>>>> Gary
>>>>>>>>>>>>> >>>>>> --
>>>>>>>>>>>>> >>>>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>>>>> >>>>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>>>> >>>>>> JUnit in Action, Second Edition
>>>>>>>>>>>>> >>>>>> Spring Batch in Action
>>>>>>>>>>>>> >>>>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>>>>> >>>>>> Home: http://garygregory.com/
>>>>>>>>>>>>> >>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>>
>>>>>>>>>>>>> >>>>> --
>>>>>>>>>>>>> >>>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>>>>> >>>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>>>> >>>>> JUnit in Action, Second Edition
>>>>>>>>>>>>> >>>>> Spring Batch in Action
>>>>>>>>>>>>> >>>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>>>>> >>>>> Home: http://garygregory.com/
>>>>>>>>>>>>> >>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>>
>>>>>>>>>>>>> >>>> --
>>>>>>>>>>>>> >>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>>>>> >>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>>>> >>>> JUnit in Action, Second Edition
>>>>>>>>>>>>> >>>> Spring Batch in Action
>>>>>>>>>>>>> >>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>>>>> >>>> Home: http://garygregory.com/
>>>>>>>>>>>>> >>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>>
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >>
>>>>>>>>>>>>> >> --
>>>>>>>>>>>>> >> E-Mail: [email protected] | [email protected]
>>>>>>>>>>>>> >> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>>>> >> JUnit in Action, Second Edition
>>>>>>>>>>>>> >> Spring Batch in Action
>>>>>>>>>>>>> >> Blog: http://garygregory.wordpress.com
>>>>>>>>>>>>> >> Home: http://garygregory.com/
>>>>>>>>>>>>> >> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>>> >
>>>>>>>>>>>>> >
>>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> --
>>>>>>>>>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>>> <http://www.manning.com/bauer3/>
>>>>>>>>>>> JUnit in Action, Second Edition
>>>>>>>>>>> <http://www.manning.com/tahchiev/>
>>>>>>>>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>>>>>>>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>>> Home: http://garygregory.com/
>>>>>>>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> E-Mail: [email protected] | [email protected]
>>>>>>>>>> Java Persistence with Hibernate, Second Edition
>>>>>>>>>> <http://www.manning.com/bauer3/>
>>>>>>>>>> JUnit in Action, Second Edition
>>>>>>>>>> <http://www.manning.com/tahchiev/>
>>>>>>>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>>>>>>>> Blog: http://garygregory.wordpress.com
>>>>>>>>>> Home: http://garygregory.com/
>>>>>>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>>> E-Mail: [email protected] | [email protected]
>>>>>>> Java Persistence with Hibernate, Second Edition
>>>>>>> <http://www.manning.com/bauer3/>
>>>>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>>>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>>>>> Blog: http://garygregory.wordpress.com
>>>>>>> Home: http://garygregory.com/
>>>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> E-Mail: [email protected] | [email protected]
>>>>> Java Persistence with Hibernate, Second Edition
>>>>> <http://www.manning.com/bauer3/>
>>>>> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
>>>>> Spring Batch in Action <http://www.manning.com/templier/>
>>>>> Blog: http://garygregory.wordpress.com
>>>>> Home: http://garygregory.com/
>>>>> Tweet! http://twitter.com/GaryGregory
>>>>>
>>>>>
>>>>>
>>>>
>>>
>>
>
>
> --
> E-Mail: [email protected] | [email protected]
> Java Persistence with Hibernate, Second Edition
> <http://www.manning.com/bauer3/>
> JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
> Spring Batch in Action <http://www.manning.com/templier/>
> Blog: http://garygregory.wordpress.com
> Home: http://garygregory.com/
> Tweet! http://twitter.com/GaryGregory
>
>
>


-- 
E-Mail: [email protected] | [email protected]
Java Persistence with Hibernate, Second Edition
<http://www.manning.com/bauer3/>
JUnit in Action, Second Edition <http://www.manning.com/tahchiev/>
Spring Batch in Action <http://www.manning.com/templier/>
Blog: http://garygregory.wordpress.com
Home: http://garygregory.com/
Tweet! http://twitter.com/GaryGregory

Reply via email to