I'm trying to serialise a class that belongs to project B from project A using jackson.
Since this class has some funny method names I needed to use MixIn annotation to make it serialisable from project A.
That worked well, but later I was asked to make this change directly into project B, since we want many other projects to be able to serialise/deserialise this class.
I ended up putting annotation directly into the class, so my class became
public class Dog {
public Dog(#JsonProperty("breed") String colour) {
this.colour = colour;
}
#JsonProperty("breed")
private String colour;
}
This is just an example and it shows what the class looks like. The point here is, when I serialise/deserialise the class inside project B the annotations are picked up and everything works as expected, whilst when I serialise/deserialise inside project A (that has project B as a dependency) the annotations are ignored. Does anybody know why this is happening?
The first thing to do is to upgrade jars.
New Maven dependencies are:
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.7.2</version>
<type>jar</type>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.7.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.2</version>
<type>jar</type>
</dependency>
You can make annotation work with usings different version but it it too much overhead and do not brings any advantages.
see:
org.codehaus.jackson versus com.fasterxml.jackson.core
http://wiki.fasterxml.com/JacksonUpgradeFrom19To20
The problem was in the jackson version.
Project B was using org.codehaus.jackson annotation, whilst project A was using com.fasterxml.jackson
fasterxml.jackson ignores codehaus annotation.
Related
I read a few threads here about static methods, and I think I understand the problems misuse/excessive use of static methods can cause. But I didn't really get to the bottom of why it is hard to mock static methods in JUnit5.
I know in JUnit4 we can do it using PowerMockito but how to do in Junit5?
An easy explanation/link would be great.
My UseCase:
I've created a service class in which I'm calling static method of other class. But that value is returning as Null.
So, I need some reference by which I can MOck that static method so that I can continue writing test case for same.
JUnit5 dependencies in pom.xml
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter-api -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.8.2</version>
<scope>test</scope>
</dependency>
The below object mapper configuration is not working when I add jjwt security to spring boot application.
#Configuration
public class CustomObjectMapper extends ObjectMapper {
/**
* Default serial version id generated.
*/
private static final long serialVersionUID = 1L;
public CustomObjectMapper() {
this.setSerializationInclusion(Include.NON_EMPTY);
this.registerModule(new ThreeTenModule());
this.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
}
}
Security dependencies added here
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.7.0</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-jwt</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security.oauth</groupId>
<artifactId>spring-security-oauth2</artifactId>
</dependency>
where as the below Jackson annotations are working on class/field levels.
#JsonInclude(Include.NON_EMPTY)
Why the bean configured custom object mapper not been used for serialization & deserialization? Any other libraries configured object mapper overriding my custom mapper?
After a long investigation, i have noticed #EnableWebMvc annotated configuration bean available in one dependent library. And got to know from here that #EnableWebMvc disables Spring Boot's MVC auto-configuration, thus giving complete control to provide customer MVC configuration. HTTP Message Convertors will also be included in Spring MVC component which in turn disables my custom jackson object mapper configuration.
PS: As jjwt imports jackson databind dependency by default, it fell in my suspect list. Feel good that i could RCA. Thanks.
Here is the maven dependency I have
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
what I'm trying to achieve is, change the spring core from 4.3.14.RELEASE to 4.3.4.RELEASE. Yes, by default spring boot starter, is using spring core 4.3.14 which can be extended to 5.0.7.RELEASE for that I tried excluding spring-core and including with 4.3.4.RELEASE
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.10.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
</exclusion>
</exclusions>
<scope>import</scope>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.4.RELEASE</version>
</dependency>
</dependencies>
When i tried to build it throws the following expection
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'org.springframework.security.config.annotation.web.configuration.WebSecurityConfiguration': Unsatisfied dependency expressed through method 'setFilterChainProxySecurityConfigurer' parameter 1; nested exception is org.springframework.beans.factory.BeanExpressionException: Expression parsing failed; nested exception is java.lang.NoSuchMethodError: org.springframework.core.convert.support.DefaultConversionService.getSharedInstance()Lorg/springframework/core/convert/ConversionService;
Manually adding each and every dependency is not possible because the application is using a hell lot of dependencies and compatibility with other dependencies would be another tough job.
So is there any workaround for this?
NOTE:- tried to work with spring framework-bom and spring IO and yet didn't find any solution maybe I missing something. Examples of those are welcomed.
You shouldn't really do this. Spring Framework > Spring Boot > Spring Cloud > Data Flow all manage these dependencies for a reason. You should let spring handle the dependnecies and upgrade your implementations as needed.
https://spring.io/blog/2016/04/13/overriding-dependency-versions-with-spring-boot
Answers this in more detail.
It is a reasonable thing to want to do this, but it should be done
with caution, because newer versions of transitive dependencies can
easily break features that rely on the older version in Spring
Boot. When you do this, and apply one of the fixes below, you are
divorcing yourself from the dependency management of Spring Boot and
saying “hey, I know what I am doing, trust me.” Unfortunately,
sometimes you need to do this in order to take advantage of new
features in third party libraries. If you don’t need the new version
of Reactor (or whatever other external transitive dependency you
need), then don’t do this, just stick to the happy path and let Spring
Boot manage the dependencies.
I have annotated a class as follows:
#ManagedResource(objectName="com.myproject.bean.jmx:name=JMXSolrIndexerBean",
description="Index Solr Operations")
public class JMXSolrIndexerBean {
....
}
My pom has the following dependencies
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-jmx</artifactId>
<version>4.1.6.RELEASE</version>
</dependency>
I can't find my MBean in the JConsole... are there any configuration steps I am missing?
Two things:
You don't need the spring-integrtation-jmx dependency to make that work, the actuator starter is enough
Your class needs to be a spring bean if you want Spring Boot to auto-detect JMX annotation on them. So adding #Component on your JMXSolrIndexerBean is all that's needed as long as it is located in a package that is processed by component scan
In other words, that class of yours is just a pojo that spring know nothings about. #ManagedResource is not a stereotype that turns that class in a Spring Bean.
I started a project in which I use both Mongo, Elasticsearch and spring boot.
With either technologies by itself, the project works just fine. However with both together, they conflict. I saw this particular article that seemed to be similar to my issue.
https://jira.spring.io/browse/DATAES-57
So I tried it out and it the problem is still there.
I put these on the Main class
#EnableAutoConfiguration(exclude = MongoRepositoriesAutoConfiguration.class)
#EnableMongoRepositories(basePackages = "com.searchizi.mongo.repository")
#EnableElasticsearchRepositories(basePackages = "com.searchizi.elasticsearch.repository")
#ComponentScan
public class Application implements CommandLineRunner { … }
A shortened form the the exception trace is this
The class SearchiziUser is in the com.searchizi.mongo.model package. It is not on the Elasticsearch scan path.
Caused by: java.lang.IllegalArgumentException: Unable to identify index name. SearchiziUser is not a Document. Make sure the document class is annotated with #Document(indexName="foo")
at org.springframework.util.Assert.isTrue(Assert.java:65)
at org.springframework.data.elasticsearch.core.ElasticsearchTemplate.getPersistentEntityFor(ElasticsearchTemplate.java:869)
at org.springframework.data.elasticsearch.core.ElasticsearchTemplate.createIndexIfNotCreated(ElasticsearchTemplate.java:684)
at org.springframework.data.elasticsearch.core.ElasticsearchTemplate.createIndex(ElasticsearchTemplate.java:135)
at org.springframework.data.elasticsearch.repository.support.AbstractElasticsearchRepository.createIndex(AbstractElasticsearchRepository.java:80)
at org.springframework.data.elasticsearch.repository.support.AbstractElasticsearchRepository.<init>(AbstractElasticsearchRepository.java:72)
at org.springframework.data.elasticsearch.repository.support.SimpleElasticsearchRepository.<init>(SimpleElasticsearchRepository.java:36)
The scanning for each repository type should be separated but apparently it is not. Any idea what to do?
This is clearly a bug in Spring Data Elasticsearch as it seems to scan for domain types in packages it actually shouldn't. I filed DATAES-?? for you. Also, I filed a ticket so that Spring Data Elasticsearch supports the new multi-store configuration improvements so that you shouldn't have to explicitly configure separate packages.
On a side note, excluding the auto-configuration is not necessary if you set up #EnableMongoRepositories as it will automatically disable Spring Boot's auto-configuration.
I faced this exception and I resolved by change version of elasticsearch and mongodb lib versions
<!-- Spring data mongodb -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.7.0.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.10.0.RELEASE</version>
</dependency>
<!-- mongodb java driver -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
</dependency>
<!-- ELASTICSEARCH -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-elasticsearch</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>