Spring Boot with Web dependency pulls jackson library dependencies and supports the Json format out of the box. But when I try to fetch the data in the xml format by placing the Accept header to application/xml, I get 406. The issue is resolved by adding the jackson-dataformat-xml dependency.
My question are,
Why does jackson-data-format-xml be added and why is this not supported out of the box.
Isn't JAXB not part of standard JDK and take care of marshalling and unmarshalling out of the box instead on relying on other jar files?
Spring is opinionated in many ways, and only supporting JSON out of the box is one example of that. Not all developers will want XML support and so it is left as an optional dependency.
JAXB was pulled from the normal JDK distribution in Java 9 in order to help make the core JDK less bloated. Again, the idea is to let developers opt in to the technologies they need instead of giving them everything by default.
Here's a little history of JAXB and the various Java versions: https://www.jesperdj.com/2018/09/30/jaxb-on-java-9-10-11-and-beyond/
Related
I'm writing a lib for projects using different versions of Spring. The lib itself is based on Spring too ( more precisely, Spring Cloud Sleuth). For now, I use different versions for different projects( version1 for projects using Spring boot 2.0.x, version2 for projects using Spring boot 2.3.x, etc). Apparently, the maintenance took a lot of time and made some confusion. Is there a runtime mechanism like #Conditional but for dependencies?
First, check the Spring Cloud compatibility matrix. As you can see, different Spring Cloud versions support different Boot versions.
I would do the same for your library and maintain different versions of it.
Your can have optional dependencies on Sleuth and set things up using #Conditional annotations (e.g.: #ConditionalOnClass) but I would not recommend that.
Sleuth 2.2.x (Hoxton) uses Brave's API (btw 2.x is not supported anymore, you should upgrade). Sleuth 3.0.x (2020.0.x aka Ilford) and 3.1.x (2021.0.x aka Jubilee) have their own API and they abstract the tracer libraries away. You can use these interfaces/classes to detect the version and configure them differently but when you compile your library you can have classpath issues because you have 2.2.x, 3.0.x, and 3.1.x on your classpath.
Another thing you can do is modularize your library and put all of those things that does not depend on Spring into a "core" module then create smaller adapter/autoconfiguration/starter modules for every version of Spring Cloud you want to support.
I have a RESTful web service application in java deployed on google app-engine which uses jersey 1.18.6.
I want to use postmark java client to send transactional emails from it.
When I integrated it, i was seeing the following exception:
javax.ws.rs.core.Response$Status$Family.familyOf(I)Ljavax/ws/rs/core/Response$Status$Family
From what I could find, I think this error was because of there were two different (and probably incompatible) version of jersey being used ,1.18.6 for jersey-server, jersey-guice and jersey-bundle and 2.25.1 for jersey-client (by postmark).
Then I tried to make the jersey version 1.18,6 throughout, so in the my main project pom, while including the dependency for postmark, I excluded the jersey-client (by added exclusions header) and separately added jersey-client dependency in my main project .
But then I got the following error:
java.lang.NoClassDefFoundError: javax/ws/rs/core/MultivaluedHashMap
This is I think the class MultivaluedHashMap is present only in jax-rs 2.x versions (which is compatible with jersey 2.x versions)
So my questions are:
Is there a version of postmark java client library which uses jersey 1.x instead of jersey 2.x?
If no then what options do I have other than migrating my main project from jersey 1.x to jersey 2.x. I don't want to do that since we will have to migrate not just the jersey dependencies but I think some other things like guice, shiro etc. which would be time consuming. Also it doesn't really seem optimal to modify multiple existing dependencies just to include one additional module.
There isn't. The very first commit of the project's pom.xml already used Jersey 2.25.1
as Mureinik mentioned above, when we worked on the library, our plan at Postmark was to use newer library versions, since they are better options in long run.
On our Github page Rupert made good suggestions, from which I find separate ClassLoader a good choice. I will play a bit with the library code in next couple of days on compatibility, however we are always in favour of using newer libraries for our codebase.
please check out my latest comment on Github issues page for possible solution for using older Jersey version https://github.com/wildbit/postmark-java/issues/11
It should be pretty easy to port the library to Jersey 1.x by porting only the HttpClient class on your side.
We have some xml that uses capitol letters for all fields. Spring boot automatically uses jackson which does not work well with this. I have the xml "jaxb"d into java objects that tell it to use the capitol letters. However spring always seems to use Jackson.
Anyway to force it to use Jaxb?
You can find here a list of commonly used in spring-boot properties for your application.properties file. You probably need:
spring.jackson.property-naming-strategy=UPPER_CAMEL_CASE
Here are the available naming strategies for Jackson.
If you insist on Jaxb I believe it will be used by spring boot unless you include jackson-dataformat-xml in your classpath (may have to exclude it).
I am trying to make sure I am using spring-boot and Jackson in a safe way. There is a deserialization bug in some versions of Jackson (source: https://github.com/FasterXML/jackson-databind/issues/1599).
By default Spring Security does not perform deserialization using Jackson, so this is an explicit choice of the user (source: https://pivotal.io/security/cve-2017-4995).
If Jackson is used to perform deserialization, versions 2.7, 2.8, 2.8.9 and 2.7.9.1, as well as 2.9.0.pr3 are patched (source: see cowtowncoder commented on Apr 13, https://github.com/FasterXML/jackson-databind/issues/1599) and not vulnerable to the bug.
Is it safe, then to perform deserialization using the version of Jackson that is part of spring, spring-boot, or Spring Security?
Every version of SpringBoot uses a vulnerable version of the Jackson API, since there really is no version that is not at least partially suceptable to attack. It can happen if you allow untrusted and third party data to be de-serialized into generic collections(Map<>, List<>. etc). Even if you are adding generics to these structures in you code, those generics are compile time only, and cannot enforce typing in the JVM runtime.
If you are accessing an external restful api, then you will have to implement your own typing. If you are using RestTemplate, this will have to be manually set on the object mapper it uses.
FYI: SpringBoot also uses a vulnerable version of logback. Just update to the latest version by explicitly including it in your build.
I do not wish to use Spring annotations or xml or any declarative, non-compile-time-safe code or anything that relies on reflection. However, I'm guessing Spring does have traditional libraries (like Apache Commons libraries) that you can call from your code rather than your annotated code getting called by the framework.
What Spring projects are libraries? I'm assuming some of them are.
The core of Spring is the Spring Framework. Which is uses reflection, annotations etc without remorse. Using spring as a library completely misses the point. You could use, say JdbcTemplates with the correct dependency but why?
If you do use Spring as a Library bare in mind you are only getting tiny bits of functionality, most of which is just bootstrap code you avoid writing. Spring is designed to be used within it's framework and built upon. Some do use libraries such as Apache Commons. Using Spring Framework as a library however does just complicate your own project and people would probably ask - "why".