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

Reply via email to