Re: [EqualsVerifier] EqualsVerifier and JodaTime LocalDate - AbstractMethodError problem

389 views
Skip to first unread message

Jan Ouwens

unread,
May 16, 2013, 5:29:13 AM5/16/13
to equalsv...@googlegroups.com
Hi Stanley,

Thanks for your message! I'm happy to hear you find EqualsVerifier useful :).

This is an interesting issue. As you pointed out, I've had some issues with JodaTime in the past, and while I'm familiar with Lombok (I know the guys who created it), I've never actually tested it in combination with EqualsVerifier. I have no idea what happens when you mix the three together :).

Unfortunately I'm a bit busy at the moment, I'll try to find some time to look into this over the weekend. In the mean time, could you run EV with the .debug() method and post the stacktrace that it prints to the console? That should give me some more detailed information.


Thanks!
Jan




On 16 May 2013 03:25, Stanley Kurdziel <aka...@gmail.com> wrote:
Hello,

I've used EqualsVerifier successfully in the past, very useful =)

Today, I ran into an issue with EqualsVerifier verifying an Object with a Joda time LocalDate field:
java.lang.AbstractMethodError: org.joda.time.Chronology.year()Lorg/joda/time/DateTimeField;

I created a very simple test to demonstrate.  In a previous post it was suggested that perhaps it was an internal String usage by the Joda time library.  If that is the case, is there a recommended work-around?

Thanks!
-Stan

Test Code: uses Lombok for the Equals and HashCode implementation, but I also tried manually implementing and got the same error.

public class JodaTimeEqualsVerifierTest
{
    @Test public void test() {
        // passes
        EqualsVerifier.forClass(ObjectContainingString.class).verify();
        // Causes AbstractMethodError
        EqualsVerifier.forClass(ObjectContainingLocalDate.class).verify();
    }
}

@AllArgsConstructor @EqualsAndHashCode
final class ObjectContainingString {
    private final String time;
}

@AllArgsConstructor @EqualsAndHashCode
final class ObjectContainingLocalDate {
    private final LocalDate time;
}

Complete project posted to github for easy reference: https://github.com/sek/learning_lombok

Full Stack Trace:
java.lang.AssertionError: java.lang.AbstractMethodError: org.joda.time.Chronology.year()Lorg/joda/time/DateTimeField;
at nl.jqno.equalsverifier.util.Assert.fail(Assert.java:80)
at nl.jqno.equalsverifier.EqualsVerifier.handleError(EqualsVerifier.java:355)
at nl.jqno.equalsverifier.EqualsVerifier.verify(EqualsVerifier.java:343)
at com.example.learning_lombok.EqualsTest.testJodaTimeField(EqualsTest.java:15)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
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.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.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)

--
You received this message because you are subscribed to the Google Groups "equalsverifier" group.
To unsubscribe from this group and stop receiving emails from it, send an email to equalsverifie...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Stanley Kurdziel

unread,
May 16, 2013, 5:16:40 PM5/16/13
to equalsv...@googlegroups.com
.debug() stack trace below.

I don't think Lombok is an issue here - it just makes the test concise.  If I use the Eclipse "generate hashCode() and equals()" function, I get the same error.

I grabbed Joda time source and line 526 of LocalDate is:
  return getChronology().year().get(getLocalMillis());

Set a breakpoint there and apparently getChronology() is null at this point.
Possibly there's an issue with how EV is instantiating the object?

Thanks for your help,
-Stan

java.lang.AbstractMethodError: org.joda.time.Chronology.year()Lorg/joda/time/DateTimeField;
at org.joda.time.LocalDate.getValue(LocalDate.java:526)
at org.joda.time.base.AbstractPartial.equals(AbstractPartial.java:266)
at org.joda.time.LocalDate.equals(LocalDate.java:641)
at com.example.learning_lombok.ObjectContainingLocalDate.equals(JodaTimeEqualsVerifierTest.java:26)
at nl.jqno.equalsverifier.ExamplesChecker.checkNotEqual(ExamplesChecker.java:103)
at nl.jqno.equalsverifier.ExamplesChecker.checkDouble(ExamplesChecker.java:96)
at nl.jqno.equalsverifier.ExamplesChecker.check(ExamplesChecker.java:71)
at nl.jqno.equalsverifier.EqualsVerifier.verifyWithExamples(EqualsVerifier.java:393)
at nl.jqno.equalsverifier.EqualsVerifier.performVerification(EqualsVerifier.java:364)
at nl.jqno.equalsverifier.EqualsVerifier.verify(EqualsVerifier.java:334)
at com.example.learning_lombok.JodaTimeEqualsVerifierTest.test(JodaTimeEqualsVerifierTest.java:17)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
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.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.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)


Jan Ouwens

unread,
May 20, 2013, 7:12:52 AM5/20/13
to equalsv...@googlegroups.com
Hi Stanley,

Thanks for the information, and for the wait :).

I've looked at your issue, and you're right; EqualsVerifier can't instantiate LocalDate (and LocalTime) objects automatically. You'll have to add a withPrefabValues call, like this:

        EqualsVerifier.forClass(ObjectContainingLocalDate.class)
                .withPrefabValues(LocalDate.class, new LocalDate(2013, 5, 20), new LocalDate(2013, 5, 21))
                .verify();

Sadly, I can't fix this automatically without adding an explicit dependency on JodaTime to EqualsVerifier, which I can't do, because I don't want to drag in JodaTime dependencies to projects that don't use it (or worse, that already use a different version).

For a future version of EqualsVerifier, I will look into making the error messages around JodaTime objects a little more helpful, though.


Thanks for reporting this!

Jan


Stanley Kurdziel

unread,
May 20, 2013, 5:51:30 PM5/20/13
to equalsv...@googlegroups.com
Thanks, the withPrefabValues works for me =)

And FWIW, I agree that it doesn't make sense to add Joda time dependency to the EV library

Thanks,
-Stan
Reply all
Reply to author
Forward
0 new messages