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

MessageBodyReader & Writer in META-INF/service issues... #39

Closed
pnsantos opened this issue Jan 7, 2014 · 15 comments
Closed

MessageBodyReader & Writer in META-INF/service issues... #39

pnsantos opened this issue Jan 7, 2014 · 15 comments
Milestone

Comments

@pnsantos
Copy link

pnsantos commented Jan 7, 2014

Hi, I've recently ran into a problem trying to use ackson-jaxrs-json-provider 2.3.0 with Jersey 2.4.1. The problem has to do with the automatic scanning that Jersey does of META-INF/services which can't be disabled otherwise CDI stops functioning.

The problem is that if I want to create a custom ContextResolver (to configure some global Jackson options) that context resolver, and consequently the corresponding object mapper is completly ignored unless I remove the META-INF/services folder.

The issue came up a while ago in Jersey's list (see this post). I'm far from an expert but is it absolutely necessary to include these? can (as per the sugestion in the mentioned post) these two files (MessageBodyReader and MessageBodyWriter) be included in a seperate jar?

@cowtowncoder
Copy link
Member

Assumption is that users like the simplicity of simply dropping provider jar, without explicit registration. This is why the default jar contains SPI metadata.

One possible way to offer choice here would be to use Maven qualifiers and essentially build 2 variants of jars; ones with SPI registration, and others without it. I don't know how to do it, but think it can be done.

@pnsantos
Copy link
Author

pnsantos commented Jan 8, 2014

Nice idea, google did that with guava because of how CDI works in JavaEE 6 and Java EE 7 server (link)

I think all you need to do is create two build artifacts one with the usual scheme:

<major version>.<minor version>.<incremental version>

and another with the qualifier

<major version>.<minor version>.<incremental version>-<qualifier>

(where the latter is built without the META-INF/services) and then publish them.

@japod
Copy link

japod commented Jan 8, 2014

I have a patch ready for JSON provider, going to write a simple test and will submit a pull request.
Tatu, will that be fine with you? What about the classifier? no-metainf-services, i.e. jackson-jaxrs-json-provider-2.3.2-SNAPSHOT-no-metainf-services.jar ? Some other idea?

@cowtowncoder
Copy link
Member

@japod Yeah I think classifier is the way to go. My only concern is that I wouldn't want to double number of sub-modules if possible (since we have 3 data formats supported, and will most likely get more over time). But as long as release process is automated, I am open to any solutions.
I hope that the fact that this is only about inclusion (or not) of meta-inf, it's easier than cases where different compilation would be needed (like for debug info).

And just to make sure: I do not want to have a single artifact without SPI information without full discussion on mailing list. Problem there would be that a simple upgrade (2.3 -> 2.4) would basically change registration and then users would wonder why their deployments broke.

@rdifalco
Copy link

rdifalco commented Feb 7, 2014

My suggestion is simple. Move the provider classes over to jackson-jaxrs-base. Then have jaxrs-providers depend on that and have the META-INF.services entries. For someone like me I will just depend on base and register the provider I want myself.

This issue is HUGE and will make many of our lives easier who are using Jersey 2.x

@cowtowncoder
Copy link
Member

I don't think that would work, if I understand the idea correctly -- the
key to modularity is that XML provider's dependencies are not forced on
JSON provider. So pushing functionality to base is not something I would
want to do.

But if necessary, we can just double up on sub-modules, and create set of
additional sub-modules which only contain META-INF entries, and depend on
concrete implementations. So instead of using qualifiers, we'd just create
new artifacts

The main open question would then be that of naming: would the existing
artifact ids refer to implementation-only (backwards incompatible), and new
ids to registration; or to registration. That is: whether to have

  1. jackson-jaxrs-json-provider-impl (code) and jackson-jaxrs-json-provider
    (registration)

or

  1. jackson-jaxrs-json-provider (impl) and
    jackson-jaxrs-json-provider-metainf (registration)

For backwards compatibility first choice would work better via Maven but
could confuse anyone who directly downloads providers.

-+ Tatu +-

On Fri, Feb 7, 2014 at 1:25 PM, Robert DiFalco notifications@github.comwrote:

My suggestion is simple. Move the provider classes over to
jackson-jaxrs-base. Then have jaxrs-providers depend on that and have the
META-INF.services entries. For someone like me I will just depend on base
and register the provider I want myself.

This issue is HUGE and will make many of our lives easier who are using
Jersey 2.x

Reply to this email directly or view it on GitHubhttps://github.com//issues/39#issuecomment-34505277
.

@rdifalco
Copy link

rdifalco commented Feb 7, 2014

Maybe I don't understand but I think this solution prevents anyone from being impacted. JacksonJsonProvider and JacksonJaxbJsonProvider classes are simply moved over to base. But they are inert and do not impact anyone using the base jar. But the provider jar includes the META-INF.services file so people who have come to expect the auto-registration behavior are ALSO not impacted and continue to have the behavior they had before. But again, I could be missing something.

The provider jar already depends on the jaxrs-base jar so that dependency is not changed.

But really, any way it is solved is great for me as long as it is solved. Thanks!

@cowtowncoder
Copy link
Member

On Fri, Feb 7, 2014 at 2:38 PM, Robert DiFalco notifications@github.comwrote:

Maybe I don't understand but I think this solution prevents anyone from
being impacted. JacksonJsonProvider and JacksonJaxbJsonProvider classes are
simply moved over to base. But they are inert and do not impact anyone
using the base jar. But the provider jar includes the services so people
who have come to expect the auto-registration behavior are ALSO not
impacted and continue to have the behavior they had before. But again, I
could be missing something.

There are 3 different providers: beyond JSON provider, XML- and Smile-
providers exist. And soon I'll add fourth one for CBOR. They are all share
the base package (that is, base contains things that all of them need).

I agree in that if we only had JSON provider, this would be doable.

-+ Tatu +-

@rdifalco
Copy link

rdifalco commented Feb 7, 2014

Oh yeah, that was myopic of me! Sorry.

@cowtowncoder
Copy link
Member

On Fri, Feb 7, 2014 at 2:53 PM, Robert DiFalco notifications@github.comwrote:

Oh yeah, that was myopic of me! Sorry.

No prob. Other providers are not that widely used yet, formerly they
existed as separate projects.

But I think we can make this work with a variation, and that should resolve
issues with 2.4, which should not take nearly as long as 2.3 to be
completed.

-+ Tatu +-

@martinstein
Copy link

+1 just a quick note that I'm also very much looking forward to a resolution of this: the documentation on the Jersey pages mentions the approach

public class MyObjectMapperProvider implements ContextResolver<ObjectMapper> {
...
}

and as @pnsantos mentioned, that doesn't work. So I'm guessing everybody who uses Jackson 2.x with Jersey is affected and will stumble over this sooner or later.

@cowtowncoder
Copy link
Member

There hasn't been any progress here, alas, much due to plenty of other Jackson work, but I am still looking forward to potential contributions for 2.5, if anyone has time & interest.

@cowtowncoder
Copy link
Member

As per PR just merged, second set of jars with classifier of no-metainf-services will be built, deployed.
Will be included in 2.6.0 (not yet included in rc1 that went out few days ago, but will be in rc2 and final).

@jhaber
Copy link
Contributor

jhaber commented Jul 2, 2015

If possible I would strongly, strongly recommend not using a qualifier but instead modifying the version number, something to the effect of 2.6.0-no-metainf-services. The issue with using a qualifier is that it changes the maven coordinates, meaning that you could get both jackson-jaxrs-json-provider:2.6.0 and jackson-jaxrs-json-provider:2.6.0:no-metainf-services in your dependency tree. By modifying the version instead of using a qualifier, they will still have the same maven coordinates so you can only end up with one in your dependency tree. This allows users to easily pick which one they want to use and not have to worry about adding exclusions all over the place to prevent the undesirable one from sneaking in as well.

@cowtowncoder
Copy link
Member

@jhaber Do you know of a way to automatically release concurrent versions, similar to how qualifier approach works?

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

6 participants