No #NotBlank validator for type String - spring-boot

I keep getting validator error for quite simple configuration class
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;
import javax.validation.constraints.NotBlank;
#Component
#Data
#Validated
#ConfigurationProperties(prefix = "test")
public class TestProperties {
#NotBlank
String uri;
}
Error is self explaining:
javax.validation.UnexpectedTypeException: HV000030: No validator could be found for constraint 'javax.validation.constraints.NotBlank' validating type 'java.lang.String'. Check configuration for 'uri'
But according to spring boot documentation this should work.

I had the same issue and solved it.
As Yogi stated in his answer, there are two implementations:
import javax.validation.constraints.NotBlank;
and
import org.hibernate.validator.constraints.NotBlank;
Switching from the javax implementation to the hibernate one solved the issue.
Since I didn't use Spring boot, I had to add to my pom.xml:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.2.4.Final</version>
</dependency>

According to Spring-Boot documentation and maven central repo the:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
has the validator included. If you have not spring-boot-starter-web included to your dependencies you can just add the validator:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>

I saw a similar question outside this forum and discovered that the error comes up whenever you try to put #NotBlank annotation on any non-string type field. In my case, the javax.validation.UnexpectedTypeException came up when I annotated a field of type Byte with #NotBlank. So I imported javax.validation.constraints.NotNull, changed the annotation on the Byte field to #NotNull and the error disappeared.
I previously tried replacing import javax.validation.constraints.NotBlank; with import org.hibernate.validator.constraints.NotBlank; to kill the error, but I got a deprecation warning. Programmers are discouraged from using deprecated program elements, so I advise that you use #NotNull annotation instead.
To understand the differences between #NotBlank and #NotNull, see this StackOverflow thread. That way, you get to decide if #NotNull fits your use case.

In my case, it worked okay when running as a standalone application, but gave this same error when running as a WAR; in order to make it work, it was necessary to explicitly import the hibernate-validator as a dependency in order to make it work when running as a WAR:
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>7.0.2.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator-annotation-processor</artifactId>
</dependency>

You can use below options,which works with Spring JPA:
org.hibernate.validator.constraints.NotBlank
javax.validation.constraints.NotNull

I have always used #NotNull.
I think the corresponding POM code is
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

Related

Exclude entire class if no starter present

Is there a way to exclude a class if there is no Spring Boot starter-X in pom. For example, if someone forgets to import a dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>-->
and I have a component that creates a dependency object on that starter. Is there a way to exclude the entire class and complain that there is no such file/class. I would like to compile the rest of the application without this class? Something like
#EnabledIf(value = "${is-present}")

Can not run Junit in eclipse

I am trying to run spring boot crud example with following code
#SpringBootTest
#RunWith(MockitoJUnitRunner.class)
public class CreateUserServiceTest {
#Mock
private UserRepository userRepository;
#InjectMocks
private CreateUserService createUserService;
#Test
public void whenSaveUser_shouldReturnUser() {
User user = new User();
user.setName("Test Name");
when(userRepository.save(ArgumentMatchers.any(User.class))).thenReturn(user);
User created = createUserService.createNewUser(user);
assertThat(created.getName()).isSameAs(user.getName());
verify(userRepository).save(user);
}
}
But after run it gives bellow error.
"NO test found with test runner 'junit5'"
anyone please help me.
Please check the error message from this file.
Edit: I found the root cause.
JUnit 5 uses annotations from a different package than JUnit 4. When you start a test, Eclipse automatically creates a launch configuration for JUnit 5, but if your annotations are not in the new package, Eclipse would not find the tests and will display the error message.
New annotations:
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.Test;
// ... other imports from org.junit.jupiter.api
Old annotations:
import org.junit.Test;
// ... imports without "jupiter" in their name
You need to add the following dependencies in a Maven project in order to use JUnit 5:
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
<scope>test</scope>
</dependency>
Workaround: Use JUnit 4.
You need to select JUnit 4 in your launch configuration. Otherwise this error is shown.
From the main menu select Run -> Run configurations, then select your JUnit test configuration from the navigation bar on the left hand side.

import of amqp from org.springframework get error

I'm working on existing Scala project which using the spring framework and I need to import org.springframework.amqp but when I tried to build the project I get:
Error:(15, 28) object amqp is not a member of package
org.springframework import org.springframework.amqp
It is really strange since I can see it in the formal website and I can see it in lot of examples in the web.
Any idea what is the problem?
A Maven dependency was missing. This is what I was need to add:
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-amqp</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>

spring boot guide missing autoconfigure

I am just going through the Spring Boot guide Tutorial:
https://spring.io/guides/gs/spring-boot/
In the Step while adding the Unittests seems broken.
The class misses some Imports:
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.test.context.junit4.SpringRunner;
Of course I can search and add the maven packages manually, but I want to know if this package should be enough? If though, what could be wrong in my code?
The guide says, this is enough:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
Thanks for any infos!
OK... bottom line it was a stupid typo...
in pom.xml
in <parent> tag
I used the <version>1.2.3 ....
It works with <version>1.5.3 ....
Sry for the inconvienece.

Unable to get Swagger UI working with Spring boot

I am trying to get Swagger UI working with Spring Boot 1.2.1. I followed the instructions at https://github.com/martypitt/swagger-springmvc and I added #EnableSwagger on my spring config.
I currently get back JSON when I go to http://localhost:8080/api-docs but no nice HTML.
I am using Maven and added the dependency on swagger-ui:
<dependency>
<groupId>org.ajar</groupId>
<artifactId>swagger-spring-mvc-ui</artifactId>
<version>0.4</version>
</dependency>
This is my complete list of dependencies:
<dependencies>
<dependency>
<groupId>com.mangofactory</groupId>
<artifactId>swagger-springmvc</artifactId>
<version>0.9.4</version>
</dependency>
<dependency>
<groupId>org.ajar</groupId>
<artifactId>swagger-spring-mvc-ui</artifactId>
<version>0.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
I also tried http://localhost:8080/docs/index.html as URL, but that just gives the "Whitelabel Error Page"
Update:
I created a test project on Github to show the problem: https://github.com/wimdeblauwe/springboot-swagger-test
Your problem lies in your SwaggerConfiguration file. You need to take out #EnableWebMvc, because this causes the default Spring Boot view resolver to be overwritten by the default 'SpringWebMvc' one which serves static content differently.
By default, Spring Boot will serve static content from any of the following directories:
/META-INF/resources/
/resources/
/static/
/public/
including webjars.
I had the same problem and I found this in the documentation: http://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-developing-web-applications.html#boot-features-spring-mvc-auto-configuration
If you want to take complete control of Spring MVC, you can add your own #Configuration annotated with #EnableWebMvc. If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own #Bean of type WebMvcConfigurerAdapter, but without #EnableWebMvc.
I hope this helps.
I have swagger-ui v0.4 (with spring v4.14 & swagger-springmvc v0.9.4) working fine, although I had some similar problems at first. It seems like this class does the trick.
#Configuration
#EnableSwagger
public class SwaggerConfig extends WebMvcConfigurerAdapter {
#Autowired
private SpringSwaggerConfig springSwaggerConfig;
#Bean
public SwaggerSpringMvcPlugin customImplementation() {
return new SwaggerSpringMvcPlugin(springSwaggerConfig).apiInfo(
apiInfo());
}
private ApiInfo apiInfo() {
return new ApiInfo(/* strings */);
}
#Override
public void configureDefaultServletHandling(
DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}
I believe the relevant thing is the overridden configureDefaultServletHandling. And on my main WebApplicationInitializer, I have:
#Import(SwaggerConfig.class)
Finally, I fixed the issue with the UI's location box showing "http://localhost:8080${pageContext.request.contextPath}/api-docs" by including this in my dependencies:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<!--<version>8.0.15</version>-->
<scope>provided</scope>
</dependency>
That provides something related to JSP processing. It is included in the dependencies of spring-boot, but it isn't normally provided.
Hope that helps.
If you are experiencing this issue with version springfox swagger-ui 3.x or greater..
try the below url.. It worked for me..
http://localhost:8080/swagger-ui/
For complete swagger documentations steps, refer:
http://muralitechblog.com/swagger-rest-api-dcoumentation-for-spring-boot/
I have the same issue but this link works for me: http://localhost:8080/sdoc.jsp
It pre-populates the swagger ui resource url box with :
http://localhost:8080${pageContext.request.contextPath}/api-docs
and when I hand edit it removing ${pageContext.request.contextPath} and hit Explore it shows me my api doc and I can even try my endpoints successfully. So definitely an issue but probably not picking up ${pageContext.request/contextPath}.
Looking at the source the javascript has:
url: window.location.origin + "${pageContext.request.contextPath}/api-docs"
on a static swagger ui html I have this piece is coded as:
discoveryUrl:"./resource-list.json"
I hope this is a bit helpful
As indicated by Tamas above, the problem lies in using #EnableWebMvc, which goes around the default setup and skips some things Swagger needs. Switching that to #EnableSwagger2 for me was enough to fix the issues in my project, which showed similar symptoms.
I have faced same issues in my project. resolved issue with below steps.
Added below dependencies in pom.xml
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>3.0.0</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
Added swagger2 ui configuration as below in the project level
#Configuration
#EnableSwagger2
#EnableAutoConfiguration
public class SpringFoxConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
Then able to get the swagger ui documentation http://localhost:8080/swagger-ui/
swagger api docs http://localhost:8080/v2/api-docs
I have done separate config for Swagger and my problem was that without #EnableAutoConfiguration it was not working properly.
#Configuration
#EnableSwagger2
#EnableAutoConfiguration
public class SwaggerConfig {
#Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2)
.select()
.apis(RequestHandlerSelectors.any())
.paths(PathSelectors.any())
.build();
}
}
I would suggest you to use #EnableSwagger2 tag and follow the steps and code from here: https://github.com/sanketsw/SpringBoot_REST_API
Also i am using following dependency which works perfectly fine:
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.2.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.2.2</version>
<scope>compile</scope>
</dependency>

Resources