Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EqualsVerifier fails with NPE in OSGi/Equinox environment #154

Closed
nickstolwijk opened this issue Sep 21, 2016 · 7 comments
Closed

EqualsVerifier fails with NPE in OSGi/Equinox environment #154

nickstolwijk opened this issue Sep 21, 2016 · 7 comments

Comments

@nickstolwijk
Copy link

What steps will reproduce the problem?

We are trying to use EqualsVerifier in our project. We are building an Eclipse RCP application and have our build automated by Maven with the Tycho plugins. When I run my test in Eclipse as JUnit test all passes. When I run my test with the Tycho-Surefire-Plugin all goes down.

What is the code that triggers this problem?

A simple Verifier call, but in a OSGi/Equinox build.

Please try to provide an example of a complete class (equals method, hashCode method, relevant fields) and a call to EqualsVerifier.

What error message or stack trace does EqualsVerifier give?

java.lang.AssertionError: NullPointerException:
For more information, go to: http://www.jqno.nl/equalsverifier/errormessages
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor.getClassLoaderFor(AnnotationAccessor.java:135)
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor.visitType(AnnotationAccessor.java:114)
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor.visit(AnnotationAccessor.java:107)
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor.process(AnnotationAccessor.java:102)
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor.typeHas(AnnotationAccessor.java:66)
at nl.jqno.equalsverifier.internal.annotations.SupportedAnnotations$2.validate(SupportedAnnotations.java:96)
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor$MyAnnotationVisitor.visitEnd(AnnotationAccessor.java:212)
at nl.jqno.equalsverifier.internal.lib.asm.ClassReader.a(Unknown Source)
at nl.jqno.equalsverifier.internal.lib.asm.ClassReader.accept(Unknown Source)
at nl.jqno.equalsverifier.internal.lib.asm.ClassReader.accept(Unknown Source)
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor.visitType(AnnotationAccessor.java:121)
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor.visit(AnnotationAccessor.java:107)
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor.process(AnnotationAccessor.java:102)
at nl.jqno.equalsverifier.internal.annotations.AnnotationAccessor.fieldHas(AnnotationAccessor.java:86)
at nl.jqno.equalsverifier.internal.ClassAccessor.fieldHasAnnotation(ClassAccessor.java:138)
at nl.jqno.equalsverifier.internal.annotations.NonnullAnnotationChecker.fieldIsNonnull(NonnullAnnotationChecker.java:40)
at nl.jqno.equalsverifier.NullChecker$NullPointerExceptionFieldCheck.execute(NullChecker.java:55)
at nl.jqno.equalsverifier.FieldInspector.check(FieldInspector.java:40)
at nl.jqno.equalsverifier.NullChecker.check(NullChecker.java:45)
at nl.jqno.equalsverifier.EqualsVerifier.verifyWithoutExamples(EqualsVerifier.java:405)
at nl.jqno.equalsverifier.EqualsVerifier.performVerification(EqualsVerifier.java:391)
at nl.jqno.equalsverifier.EqualsVerifier.verify(EqualsVerifier.java:364)
at nl.loxia.beheer.domein.infraatlas.views.ViewClassesTest.testEquals(ViewClassesTest.java:72)

What did you expect?

No failing tests, because the tests are green if you use the Eclipse JUnit runner interface.

Which version of EqualsVerifier are you using?

2.1.5

Please provide any additional information below.

@jqno
Copy link
Owner

jqno commented Sep 23, 2016

Hi,

It looks like the error occurs while EqualsVerifier is trying to see if your class has annotations defined on it (like @nonnull or @immutable). You'll probably be able to work around the issue by adding .suppress(Warning.ANNOTATION).

Unfortunately, I have zero experience with OGSi and Equinox. If you can give me a small GitHub repo I can clone that reproduces the issue, then I'm willing to look into it in more depth.

@nickstolwijk
Copy link
Author

I have created the smallest project I could think of and shared it here: https://github.com/nickstolwijk/equalsverifier.osgi-issue

First, you need to install the testtools, which bundles junit and equalsverifier as a bundle due to no good MANIFEST.MF in both those bundles.

Then you can run the main pom to show the problem. If you remove the annotation from the Bar field of Foo then everything runs fine.

@ssoloff
Copy link

ssoloff commented Sep 23, 2016

Sorry for breaking in here with a drive-by comment, but I ran into a similar issue while trying to use EV with a slightly different OSGi toolchain (Bnd/Bndtools with Felix). I thought I'd share what I did to get it to work in the event EV, as currently written, is not compatible with OSGi.

As you observed, EV is not distributed as an OSGi bundle. However, I don't think simply generating a proper bundle manifest for EV is sufficient, as EV (and/or possibly Objenesis) seems to heavily rely on a flat classpath (e.g. Class.forName() is used in several locations). Obviously, when running within an OSGi container, the active bundle class loader will not have the same classpath visibility as when running without an OSGi container. You might be able to get around such limited visibility using a bundle header, such as DynamicImport-Package: *, but that approach always smells bad to me.

The majority of my OSGi background comes from using PDE/Tycho, and thus I was used to running my unit tests in the manner you've described (i.e. the tests are hosted in a bundle fragment and run within an OSGi container). When I made the switch to Bnd/Bndtools, I was pleasantly surprised that Bnd makes a distinction between running unit tests without an OSGi container (i.e. just as you would in any non-OSGi project) and integration tests within an OSGi container. Therefore, in a Bnd OSGi project, using EV in a unit test is as simple as it is in a vanilla Java project.

The last time I looked (about a year ago), Tycho did not support running tests without an OSGi container (i.e. all tests are effectively integration tests). However, there was recently a discussion on the Tycho users mailing list about how to modify a Tycho project to achieve such a distinction between unit tests and integration tests. That thread may help you modify your project if you choose to go that route.

@jqno
Copy link
Owner

jqno commented Sep 23, 2016

@ssoloff I find this very informative, thanks for sharing this!

@nickstolwijk Thanks for taking the time to set up the project, I'll take a look at it as soon as I have some time (probably in the coming week).

@nickstolwijk
Copy link
Author

@ssoloff I will have a look at that discussion. Especially the blog: http://mukis.de/pages/simple-junit-tests-with-tycho-and-surefire/ looks promising!

@jqno
Copy link
Owner

jqno commented Oct 1, 2016

I just released version 2.1.6, which fixes this issue.

@jqno jqno closed this as completed Oct 1, 2016
@nickstolwijk
Copy link
Author

Thanks! It works like a charm.

On 1 Oct 2016 14:49, "Jan Ouwens" notifications@github.com wrote:

I just released version 2.1.6, which fixes this issue.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
#154 (comment),
or mute the thread
https://github.com/notifications/unsubscribe-auth/ABfWonmWjKS_fW2t-DgsflDwBUNT65SGks5qvlbggaJpZM4KCwMT
.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants