I converted the file appender tests in question to use a JUnit rule to delete files after a test is run. This doesn't happen until after the @Test method is executed (so no checking for files and such in an @After method). This was to get rid of all the duplicate calls to file.delete() in several tests that would put it in an @After or @AfterClass method. If the files aren't supposed to be deleted after every test method and instead should be deleted only after the full test (which is somewhat odd), then change @Rule to @ClassRule and make the field static.
On 1 April 2014 07:23, Gary Gregory <[email protected]> wrote: > I should also point out that the tests themselves might be at issue. I > just fixed a couple of bugs (locally only) in the socket server tests that > held never closed server sockets as part of my change set for LOG4J2-583. > So more problems would not be a surprise. > > Gary > > On Tue, Apr 1, 2014 at 8:21 AM, Gary Gregory <[email protected]>wrote: > >> On Tue, Apr 1, 2014 at 1:51 AM, Ralph Goers <[email protected]> wrote: >> >>> Is this a flaw in the recent changes Matt made? >>> >> >> My guess is yes. >> >> >>> Do they need to be reverted? Or are the tests themselves flawed? I also >>> haven't had the time to investigate. >>> >> >> Well, this is the tricky part. Matt has suggested that these failures >> might reveal a problem in the file appender holding on to its file too >> long. Why only on Windows, how knows :( It seems like the kind of problem >> that would be generic... >> >> Gary >> >> >> >> >>> >>> Ralph >>> >>> On Mar 31, 2014, at 10:32 PM, Remko Popma <[email protected]> wrote: >>> >>> I haven't tried to build since a week ago, sorry, totally swamped at >>> work. >>> >>> But I agree this should not stay this way. >>> >>> Sent from my iPhone >>> >>> On 2014/04/01, at 14:17, Gary Gregory <[email protected]> wrote: >>> >>> Sadly it looks like it. I have not heard from other Windows users >>> though. IMO this is not acceptable. This could also be a bug in the test or >>> the file appender. >>> >>> Gary >>> >>> >>> -------- Original message -------- >>> From: Remko Popma >>> Date:04/01/2014 00:41 (GMT-05:00) >>> To: Log4J Developers List >>> Subject: Re: unit test failures? >>> >>> Does everyone who wants to build on windows now need to exclude certain >>> tests in order for the build to succeed? >>> >>> Remko >>> >>> Sent from my iPhone >>> >>> On 2014/04/01, at 12:50, Gary Gregory <[email protected]> wrote: >>> >>> I've tweaked the POM to allow for Maven to skip specific tests like so: >>> >>> mvn test -Dlog4j.skip.test1=**/ConfigurationTest.java >>> -Dlog4j.skip.test2=**/FileOutputTest.java >>> >>> Gary >>> >>> >>> On Mon, Mar 31, 2014 at 9:38 PM, Gary Gregory <[email protected]>wrote: >>> >>>> If I change the method to: >>>> >>>> private void clean() { >>>> for (final File file : files) { >>>> if (file.exists()) { >>>> if (!file.delete()) { >>>> StatusLogger.getLogger().error( >>>> "TODO [FileAppender problem?] Could not >>>> delete file " + file + ", last modifed " >>>> + >>>> DateFormat.getInstance().format(new Date(file.lastModified()))); >>>> } else { >>>> file.deleteOnExit(); >>>> } >>>> } >>>> } >>>> >>>> I get 3 failures (instead of 9): >>>> >>>> ConfigurationTest >>>> org.apache.logging.log4j.core.config.ConfigurationTest >>>> [0] >>>> testLogToFile[0](org.apache.logging.log4j.core.config.ConfigurationTest) >>>> java.lang.AssertionError: >>>> Expected: is <1> >>>> but: was <2> >>>> >>>> at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) >>>> >>>> at org.junit.Assert.assertThat(Assert.java:865) >>>> >>>> at org.junit.Assert.assertThat(Assert.java:832) >>>> >>>> at >>>> org.apache.logging.log4j.core.config.ConfigurationTest.testLogToFile(ConfigurationTest.java:138) >>>> >>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>>> >>>> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) >>>> >>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) >>>> >>>> at java.lang.reflect.Method.invoke(Unknown Source) >>>> >>>> at >>>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) >>>> >>>> at >>>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) >>>> >>>> at >>>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) >>>> >>>> at >>>> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) >>>> >>>> at >>>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) >>>> >>>> at >>>> org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48) >>>> >>>> at >>>> org.apache.logging.log4j.junit.InitialLoggerContext$1.evaluate(InitialLoggerContext.java:52) >>>> >>>> at org.junit.rules.RunRules.evaluate(RunRules.java:20) >>>> >>>> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) >>>> >>>> at >>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) >>>> >>>> at >>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) >>>> >>>> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) >>>> >>>> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) >>>> >>>> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) >>>> >>>> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) >>>> >>>> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) >>>> >>>> at org.junit.runners.ParentRunner.run(ParentRunner.java:309) >>>> >>>> at org.junit.runners.Suite.runChild(Suite.java:127) >>>> >>>> at org.junit.runners.Suite.runChild(Suite.java:26) >>>> >>>> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) >>>> >>>> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) >>>> >>>> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) >>>> >>>> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) >>>> >>>> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) >>>> >>>> at org.junit.runners.ParentRunner.run(ParentRunner.java:309) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) >>>> >>>> >>>> >>>> [1] >>>> testLogToFile[1](org.apache.logging.log4j.core.config.ConfigurationTest) >>>> java.lang.AssertionError: >>>> Expected: is <1> >>>> but: was <3> >>>> >>>> at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) >>>> >>>> at org.junit.Assert.assertThat(Assert.java:865) >>>> >>>> at org.junit.Assert.assertThat(Assert.java:832) >>>> >>>> at >>>> org.apache.logging.log4j.core.config.ConfigurationTest.testLogToFile(ConfigurationTest.java:138) >>>> >>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>>> >>>> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) >>>> >>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) >>>> >>>> at java.lang.reflect.Method.invoke(Unknown Source) >>>> >>>> at >>>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) >>>> >>>> at >>>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) >>>> >>>> at >>>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) >>>> >>>> at >>>> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) >>>> >>>> at >>>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) >>>> >>>> at >>>> org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48) >>>> >>>> at >>>> org.apache.logging.log4j.junit.InitialLoggerContext$1.evaluate(InitialLoggerContext.java:52) >>>> >>>> at org.junit.rules.RunRules.evaluate(RunRules.java:20) >>>> >>>> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) >>>> >>>> at >>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) >>>> >>>> at >>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) >>>> >>>> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) >>>> >>>> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) >>>> >>>> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) >>>> >>>> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) >>>> >>>> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) >>>> >>>> at org.junit.runners.ParentRunner.run(ParentRunner.java:309) >>>> >>>> at org.junit.runners.Suite.runChild(Suite.java:127) >>>> >>>> at org.junit.runners.Suite.runChild(Suite.java:26) >>>> >>>> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) >>>> >>>> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) >>>> >>>> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) >>>> >>>> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) >>>> >>>> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) >>>> >>>> at org.junit.runners.ParentRunner.run(ParentRunner.java:309) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) >>>> >>>> >>>> >>>> [2] >>>> testLogToFile[2](org.apache.logging.log4j.core.config.ConfigurationTest) >>>> java.lang.AssertionError: >>>> Expected: is <1> >>>> but: was <4> >>>> >>>> at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20) >>>> >>>> at org.junit.Assert.assertThat(Assert.java:865) >>>> >>>> at org.junit.Assert.assertThat(Assert.java:832) >>>> >>>> at >>>> org.apache.logging.log4j.core.config.ConfigurationTest.testLogToFile(ConfigurationTest.java:138) >>>> >>>> at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) >>>> >>>> at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) >>>> >>>> at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) >>>> >>>> at java.lang.reflect.Method.invoke(Unknown Source) >>>> >>>> at >>>> org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47) >>>> >>>> at >>>> org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) >>>> >>>> at >>>> org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44) >>>> >>>> at >>>> org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) >>>> >>>> at >>>> org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) >>>> >>>> at >>>> org.junit.rules.ExternalResource$1.evaluate(ExternalResource.java:48) >>>> >>>> at >>>> org.apache.logging.log4j.junit.InitialLoggerContext$1.evaluate(InitialLoggerContext.java:52) >>>> >>>> at org.junit.rules.RunRules.evaluate(RunRules.java:20) >>>> >>>> at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271) >>>> >>>> at >>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70) >>>> >>>> at >>>> org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50) >>>> >>>> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) >>>> >>>> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) >>>> >>>> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) >>>> >>>> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) >>>> >>>> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) >>>> >>>> at org.junit.runners.ParentRunner.run(ParentRunner.java:309) >>>> >>>> at org.junit.runners.Suite.runChild(Suite.java:127) >>>> >>>> at org.junit.runners.Suite.runChild(Suite.java:26) >>>> >>>> at org.junit.runners.ParentRunner$3.run(ParentRunner.java:238) >>>> >>>> at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63) >>>> >>>> at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236) >>>> >>>> at org.junit.runners.ParentRunner.access$000(ParentRunner.java:53) >>>> >>>> at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229) >>>> >>>> at org.junit.runners.ParentRunner.run(ParentRunner.java:309) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) >>>> >>>> at >>>> org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) >>>> >>>> >>>> Gary >>>> >>>> >>>> >>>> >>>> On Mon, Mar 31, 2014 at 4:10 PM, Matt Sicker <[email protected]> wrote: >>>> >>>>> In >>>>> log4j-core/src/test/java/org/apache/logging/log4j/junit/CleanFiles.java on >>>>> line 48, could you try deleting the "assertTrue" part? >>>>> >>>>> I get occasional test failures myself from the same test in my >>>>> TeamCity instance, but it seems to be a different issue with the log file >>>>> *not* being deleted! It's actually possible that this modified test has >>>>> exposed a potential bug with the FileAppender code. It seems to be holding >>>>> on to the file longer than it should. >>>>> >>>>> >>>>> On 31 March 2014 13:54, Ralph Goers <[email protected]>wrote: >>>>> >>>>>> I’d guess it is Windows specific. I haven’t looked at what Matt did >>>>>> to this yet. >>>>>> >>>>>> Ralph >>>>>> >>>>>> >>>>>> >>>>>> On Mar 31, 2014, at 11:08 AM, Gary Gregory <[email protected]> >>>>>> wrote: >>>>>> >>>>>> I just tested a clean trunk and I get the following failures: >>>>>> >>>>>> Failed tests: >>>>>> ConfigurationTest.testLogToFile[0] Could not delete >>>>>> target\test.log, last modifed 3/31/14 1:50 PM >>>>>> ConfigurationTest.testConfiguredAppenders[0] Could not delete >>>>>> target\test.log, last modifed 3/31/14 1:51 PM >>>>>> ConfigurationTest.testLogger[0] Could not delete target\test.log, >>>>>> last modifed 3/31/14 1:51 PM >>>>>> ConfigurationTest.testLogToFile[1] Could not delete >>>>>> target\test.log, last modifed 3/31/14 1:51 PM >>>>>> ConfigurationTest.testConfiguredAppenders[1] Could not delete >>>>>> target\test.log, last modifed 3/31/14 1:51 PM >>>>>> ConfigurationTest.testLogger[1] Could not delete target\test.log, >>>>>> last modifed 3/31/14 1:51 PM >>>>>> ConfigurationTest.testLogToFile[2] Could not delete >>>>>> target\test.log, last modifed 3/31/14 1:51 PM >>>>>> ConfigurationTest.testConfiguredAppenders[2] Could not delete >>>>>> target\test.log, last modifed 3/31/14 1:51 PM >>>>>> ConfigurationTest.testLogger[2] Could not delete target\test.log, >>>>>> last modifed 3/31/14 1:51 PM >>>>>> FileOutputTest.testConfig:59 Couldn't delete file target\status.log >>>>>> >>>>>> Tests run: 542, Failures: 10, Errors: 0, Skipped: 15 >>>>>> >>>>>> I tested with: >>>>>> >>>>>> Apache Maven 3.0.5 (r01de14724cdef164cd33c7c8c2fe155faf9602da; >>>>>> 2013-02-19 08:51:28-0500) >>>>>> Maven home: C:\Java\apache-maven-3.0.5\bin\.. >>>>>> Java version: 1.6.0_45, vendor: Sun Microsystems Inc. >>>>>> Java home: C:\Program Files\Java\jdk1.6.0_45\jre >>>>>> Default locale: en_US, platform encoding: Cp1252 >>>>>> OS name: "windows 7", version: "6.1", arch: "amd64", family: "windows" >>>>>> >>>>>> and: >>>>>> >>>>>> Apache Maven 3.0.5 (r01de14724cdef164cd33c7c8c2fe155faf9602da; >>>>>> 2013-02-19 08:51:28-0500) >>>>>> Maven home: C:\Java\apache-maven-3.0.5\bin\.. >>>>>> Java version: 1.8.0_20-ea, vendor: Oracle Corporation >>>>>> Java home: C:\Program Files\Java\*jdk1.8.0_20*\jre >>>>>> Default locale: en_US, platform encoding: Cp1252 >>>>>> OS name: "windows 7", version: "6.1", arch: "amd64", family: "dos" >>>>>> >>>>>> Matt? Bueller? Anybody? >>>>>> >>>>>> Gary >>>>>> >>>>>> >>>>>> On Mon, Mar 31, 2014 at 2:48 AM, Ralph Goers < >>>>>> [email protected]> wrote: >>>>>> >>>>>>> Trunk is building for me. >>>>>>> >>>>>>> Ralph >>>>>>> >>>>>>> On Mar 30, 2014, at 7:43 PM, Gary Gregory <[email protected]> >>>>>>> wrote: >>>>>>> >>>>>>> Hi All: >>>>>>> >>>>>>> I have a large change set (can't break it up into smaller bits) on >>>>>>> my machine and it does not seem related to the following failures I see: >>>>>>> >>>>>>> Results : >>>>>>> >>>>>>> Failed tests: >>>>>>> XmlFileAppenderTest.testFlushAtEndOfBatch:70 line1 incorrect: [ >>>>>>> <Event logger="com.foo.Bar" timestamp="1396233402662" level="INFO" >>>>>>> thread="main" >>>>>>> fcqn="org.apache.logging.log4j.spi.AbstractLoggerProvider">], >>>>>>> does not contain: [<log4j:Even >>>>>>> t ] >>>>>>> ConfigurationTest.testLogToFile[0] null >>>>>>> ConfigurationTest.testConfiguredAppenders[0] null >>>>>>> ConfigurationTest.testLogger[0] null >>>>>>> ConfigurationTest.testLogToFile[1] null >>>>>>> ConfigurationTest.testConfiguredAppenders[1] null >>>>>>> ConfigurationTest.testLogger[1] null >>>>>>> ConfigurationTest.testLogToFile[2] null >>>>>>> ConfigurationTest.testConfiguredAppenders[2] null >>>>>>> ConfigurationTest.testLogger[2] null >>>>>>> FileOutputTest.testConfig:59 Couldn't delete file >>>>>>> >>>>>>> Tests in error: >>>>>>> >>>>>>> JpaH2AppenderTest>AbstractJpaAppenderTest.testBaseJpaEntityAppender:107 >>>>>>> » >>>>>>> AppenderLogging >>>>>>> >>>>>>> JpaH2AppenderTest>AbstractJpaAppenderTest.testPerformanceOfAppenderWith10000EventsUsingBasicEntity:224 >>>>>>> » AppenderLogging >>>>>>> >>>>>>> JpaH2AppenderTest>AbstractJpaAppenderTest.testBasicJpaEntityAppender:169 >>>>>>> » >>>>>>> AppenderLogging >>>>>>> >>>>>>> JpaHyperSqlAppenderTest>AbstractJpaAppenderTest.testBaseJpaEntityAppender:107 >>>>>>> » AppenderLogging >>>>>>> >>>>>>> JpaHyperSqlAppenderTest>AbstractJpaAppenderTest.testPerformanceOfAppenderWith10000EventsUsingBasicEntity:224 >>>>>>> » AppenderLogging >>>>>>> >>>>>>> JpaHyperSqlAppenderTest>AbstractJpaAppenderTest.testBasicJpaEntityAppender:169 >>>>>>> » AppenderLogging >>>>>>> >>>>>>> Tests run: 569, Failures: 11, Errors: 6, Skipped: 21 >>>>>>> >>>>>>> Can folks comment on whether they can do a clean build? >>>>>>> >>>>>>> Thank you! >>>>>>> >>>>>>> Gary >>>>>>> >>>>>>> -- >>>>>>> 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 >>>>>> >>>>>> >>>>>> >>>>> >>>>> >>>>> -- >>>>> Matt Sicker <[email protected]> >>>>> >>>> >>>> >>>> >>>> -- >>>> 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 > -- Matt Sicker <[email protected]>
