-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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
refactor ObjectMapperFactory and other util classes that deal with Jackson #4052
Comments
@pjfanning I think what you propose is a good idea and I'm interested in trying to push this through. I'm not 100% familiar with the swagger-core code-base but debugging a recent issue on my end led me to the Jackson object mapper exposed in ObjectMapperFactory My use-case is pretty simple - I have a Kotlin/Jersey integration leveraging JAX-RS annotations and I'm trying to generate the OpenAPI JSON spec via the swagger-gradle plugin. In order for the integration to work, the Kotlin field parameter annotations need to site target the constructor parameters. However, the JAX-RS annotation detection logic in DefaultParameterExtension currently won't detect constructor-level annotations. Under the hood, I did look over your draft PR and the only thing that I'm confused about is how to potentially integrate with this logic. For instance, the swagger-jaxrs2 module provides a SwaggerLoader in which you can pass a Let me know your thoughts. Thanks! |
There's also a suggestion here to leverage ObjectMapper#findAndRegisterModules but I've never used that and might result in inconsistent behavior |
Unfortunately, I have no say on what gets merged to swagger-core. Without some indication from someone who can merge that there is hope that my work will not go to waste, I'm reluctant to spend much more time on this, |
@pjfanning Understood @frantuma Any thoughts on the above discussion or anyone else we can potentially discuss solutions with? |
Thanks for your contributions in this area!
At the moment (also because of historical reasons) we have basically three mapper instances used in code: A. outputJsonMapper: this mapper is originally a copy of Customizing the output seems to be the most popular "mapper customization" scenario and it's handled by the processor The mapper used by C. Json.mapper() In all the rest of the code, One solution might be something like what @pjfanning proposes (being able to update the An alternative approach would be to have the mapper used by JAX-RS being separate, similarly to what done for the This is not so trivial (but would be really really nice to have!), also because of the current status with e.g. For @bbguitar77 particuar issue with current version of swagger core, providing an @pjfanning @bbguitar77 please let me know your thoughts about this. |
@frantuma the swagger build uses jackson 2.12 already - if you compile with that version, are you really hoping that users can override the transitive dependency and use an older version of jackson? I am part of the Jackson team and that wouldn't be something that we'd recommend. Generally, with the existing PR draft, I focused on swagger-core but if swagger-integration has its own classes, similar changes can be made there - I guess I'd prefer to get the swagger-core changes agreed and then move onto swagger-integration. |
@pjfanning I have actually seen several cases where keeping the explicit Jackson version defined in their project was a requirement for the users, there are probably tickets in this repo about that as well. Not sure what you mean with Also can you clarify which scenarios are you trageting with the proposed changes, if any? Or would this mainy be done to "modernize" Jackson usage? |
https://github.com/swagger-api/swagger-core/blob/master/modules/swagger-integration/src/main/java/io/swagger/v3/oas/integration/GenericOpenApiContext.java -- swagger-integration appears to be the name of this 'module' - this is one of the links you provided @frantuma
This class seems to delegate to the class that I've already modified in the PR. |
the main aim is to allow of this enhancement is to allow users to update the jackson object mapper used by swagger - swagger does a bit of its own configuration already - so we need to ensure this is not lost - so we don't want users just replacing the jackson object mapper and leaving out config that swagger needs but at the same time it is useful to allow users to add extra config (extra jackson modules, etc). |
I searched through swagger issues - there are a lot - but I found none where people were complaining about jackson version being too new - the issues that mention jackson versions typically are about upgrading. Jackson MapperBuilder used in my PR was introduced in Jackson 2.10.0 that was released on Sep 26, 2019 - that's a fair while ago. If Log4Shell issue teaches us anything is that trying to support open source users who insist on not upgrading their dependencies is bad for everyone. If swagger wants to support multiple jackson versions, then the jackson code should be shifted off into its own module with a standardised API and different variants of that module can be published for different jackson versions -- this adds a fair amount of complexity |
my comment
So we agree here I guess. As I mentioned in comment above there are potentially different mappers involved, and it would be nice to allow customization specific to each one. Not entirely sure about your proposal (on top of changes to factory), but we can proceed in steps |
These changes would only probably be used by a small number of users. I'd prefer not to complicate things by adding jackson customisation in different places. If use cases pop up later, it should be easy to support them. For instance, if IntegrationObjectMapperFactory needs separate customisation, the API could be something like:
|
I might need to go back to the drawing board on the PR. The Jackson 3 Mapper.Builder is due to return fresh mapper instances on each build call but the Jackson 2 version of the code returns the same mapper so my code acts up if a different thread modifies its mapper instance. In the swagger unit tests, there are just 2 tests that do this but I had to disable them in my PR to get the other tests to pass. I'm starting a conversation with Jackson team about whether the Jackson 2 Mapper.Builder can be made to work more like the Jackson 3 version. |
@frantuma Sorry for the late reply, but your suggestion on providing my own Anyway, regarding the other comments, I don't have too much input other than having a centralized Jackson |
I'm going to close this |
Jackson plays an important role in Swagger-Core. Jackson code is evolving towards an eventual Jackson 3.0 release and the existing ObjectMapperFactory probably needs a little refactoring with this in mind.
Jackson 2 already has the Mapper.Builder concept added to it and aim is to deprecate and remove anything on ObjectMapper that allows it to be modified. That is, you configure a Mapper.Builder and this config can be changed but once you create an ObjectMapper from it, that ObjectMapper is supposed to be immutable.
It would also be nice to allow users to add extra features to the Jackson mapper to suit their needs.
My proposal would be:
The text was updated successfully, but these errors were encountered: