That's pretty complex :-) I am not saying it's a bad idea -- just very complicated. Additionally, I am not sure there is any greater benefit than coding directly the JAnsi tokens in the message. You aren't escaping (no pun) the use of tokens -- just trading one set for another.
Cheers, Paul On Sat, Jun 25, 2016 at 5:33 PM, Gary Gregory <[email protected]> wrote: > Note that JAnsi includes the class org.fusesource.jansi.AnsiRenderer which > converts strings like "@|bold,red Warning!|@" into ANSI equivalents where > @| and |@ are special markers but this is not what I want. I want to have > _style_ name a la CSS so I can say "@|warning Your pants are on fire|@" and > define "warning" as whatever in the Log4j config. > > Gary > > On Sat, 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 >
