I can't add mapstruct in my Spring project - spring

I try to add mapstruct mapper in my Spring project.
I have a User entity. I need to show a list of users in the admin panel. For this, I did DTO UserForAdmin, mapper UserMapper and rest controller AdminRestController. When I try to get UserMapper I get errors.
I try two ways:
Mappers.getMapper(UserMapper.class)
I get error
java.lang.ClassNotFoundException: Cannot find implementation for
ru.project.mapper.UserMapper
Autowired
I get error
Error starting ApplicationContext. To display the conditions report
re-run your application with 'debug' enabled. 2019-07-17 15:47:07.886
ERROR 13652 --- [ restartedMain]
o.s.b.d.LoggingFailureAnalysisReporter :
*************************** APPLICATION FAILED TO START
Description:
Field userMapper in ru.project.controller.rest.AdminRestController
required a bean of type 'ru.project.mapper.UserMapper' that could not
be found.
The injection point has the following annotations:
- #org.springframework.beans.factory.annotation.Autowired(required=true)
Action:
Consider defining a bean of type 'ru.project.mapper.UserMapper' in
your configuration.
Here my source code.
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.6.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>ru.project</groupId>
<artifactId>project</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project</name>
<description>The project is project of resourse for investors.</description>
<properties>
<java.version>12</java.version>
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.thymeleaf.extras</groupId>
<artifactId>thymeleaf-extras-springsecurity5</artifactId>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>2.3.5</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</path>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
My interface UserMapper:
package ru.project.mapper;
import java.util.List;
import org.mapstruct.Mapper;
import ru.project.domain.User;
import ru.project.dto.UserForAdmin;
#Mapper
//#Mapper(componentModel = "spring")
public interface UserMapper {
UserForAdmin UserToUserForAdmin(User user);
List<UserForAdmin> UserListToUserForAdminList(List<User> user);
}
My RestController:
package ru.project.controller.rest;
import java.util.List;
import org.mapstruct.factory.Mappers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import ru.project.dto.UserForAdmin;
import ru.project.mapper.UserMapper;
import ru.project.service.UserService;
#RestController
public class AdminRestController {
#Autowired
private UserService userService;
//#Autowired
//private UserMapper userMapper;
#GetMapping("/admin/users")
public List<UserForAdmin> findAllUsers(){
UserMapper userMapper = Mappers.getMapper(UserMapper.class);
return userMapper.UserListToUserForAdminList(userService.findAll());
}
}
I would like to use Awtowired.

You need to use #Mapper(componentModel="spring")
package ru.project.mapper;
import java.util.List;
import org.mapstruct.Mapper;
import ru.project.domain.User;
import ru.project.dto.UserForAdmin;
#Mapper(componentModel = "spring")
public interface UserMapper {
UserForAdmin UserToUserForAdmin(User user);
List<UserForAdmin> UserListToUserForAdminList(List<User> user);
}
and use below in AdminRestController
#Autowired
private UserMapper userMapper;
And i am assuming that User and UserForAdmin have same field names
After this run mvn clean compile and sources will be generated

An alternative answer to using annotation #Mapper(componentModel = "spring") would be to add the component model as compiler arguments in the plugin. The annotation works but the annoying thing may be having to add it to every mapper you create. A compiler argument you add once and works for all mappers in the project. Below is an example of a plugin definition with the componentModel compiler argument.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</path>
<path>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</path>
</annotationProcessorPaths>
<compilerArgs>
<arg>-Amapstruct.defaultComponentModel=spring</arg>
</compilerArgs>
</configuration>
</plugin>
I have tried this with versions 1.3.0.Final as well as 1.3.1.Final and sping boot 2.1.7/8/9

Use #Mapper(componentModel = "spring") - enable di.
Run mvn package command -it creates the implementation class.
#Autowired the mapper interface and use.
(method name start letter in java should be lower case)

There is one simple solution.
at your mapper class, use #Mapper(componentModel = "spring")
and the run mvn clean install command from terminal.
or in case of STS/ Eclipse, go to Project> Run As> maven clean
and then run Project> Run As> maven install
and your mapper Impl will be generated!
NOTE: Regarding to plugins
if you're using both of following dependencies then no need to use plugin in pom.xml file
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
and properties will be like;
<properties>
<java.version>11</java.version>
<org.mapstruct.version>1.3.1.Final</org.mapstruct.version>
</properties>

I solved it by adding scanBasePackages
#SpringBootApplication(scanBasePackages = {
"com.yourpackagepath.mapper"
})

Cannot find implementation for ru.project.mapper.UserMapper that means UserMapper must be implements by some class.
such as public Class UserMapperImple implements UserMapper {XXXXXXX}
then the Mappers.getMapper("UserMapper") will get UserMapperImple.
Consider defining a bean of type 'ru.project.mapper.UserMapper' in your configuration. that means #Mapper do not work; i advise you to check the spring-config.xml. may the ApplicationContext not scan this package.
hope to help you :)

Related

Repository bean cannot be found (No idea why)

I'm trying to run my application and I'm receiving this error:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of constructor in com.danielturato.product.services.ProductServiceImpl required
a bean of type 'com.danielturato.product.persistence.ProductRepository' that could not be
found.
Action:
Consider defining a bean of type 'com.danielturato.product.persistence.ProductRepository' in
your configuration.
I have no idea why this is occurring. I've tried to look at past solutions where its said to use the #EnableMongoRepository to point to the correct package however I have tried this and it doesn't work. I've also tried adding the #Repository annotation above my repository (even though its not needed) and it doesn't work still. Here is my code for my repository, application & where the repository is failing to be injected.
Application:
#SpringBootApplication
#ComponentScan("com.danielturato")
public class ProductServiceApplication {
private static final Logger LOG = LoggerFactory.getLogger(ProductServiceApplication.class);
public static void main(String[] args) {
SpringApplication.run(ProductServiceApplication.class, args);
}
}
Repository:
public interface ProductRepository extends ReactiveCrudRepository<ProductEntity, String> {
Mono<ProductEntity> findByProductId(int productId);
}
ProductServiceImpl:
#RestController
public class ProductServiceImpl implements ProductService {
private static final Logger LOG = LoggerFactory.getLogger(ProductServiceImpl.class);
private final ServiceUtil serviceUtil;
private final ProductRepository repository;
private final ProductMapper mapper;
#Autowired
public ProductServiceImpl(ProductRepository repository, ProductMapper mapper, ServiceUtil serviceUtil) {
this.repository = repository;
this.mapper = mapper;
this.serviceUtil = serviceUtil;
}
Pom file:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.danielturato</groupId>
<artifactId>product-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>product-service</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.0.Beta1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>io.projectreactor</groupId>
<artifactId>reactor-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.danielturato</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.danielturato</groupId>
<artifactId>util</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.3.1.RELEASE</version>
</dependency>
<dependency>
<groupId>de.flapdoodle.embed</groupId>
<artifactId>de.flapdoodle.embed.mongo</artifactId>
<version>2.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-kafka</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-stream-rabbit</artifactId>
<version>3.0.6.RELEASE</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<annotationProcessorPaths>
<path>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.3.0.Beta2</version>
</path>
</annotationProcessorPaths>
</configuration>
</plugin>
</plugins>
</build>
</project>
If anyone can suggest for me anything to try or would like me to put more info here please let me know.
The stack trace you have included in your question does point to the ProductRepository not being available for autowiring and as a previous comment has pointed out this is because you are missing the #Repository annotation from your repository.
Another reason is if your repository cannot find a matching entity. This might be for example if the Id is the wrong type or is missing the #Id annotation, if the entity doesn't have either #Entity/#Document or if it is missing an all args constructor. Plus in your case you have added a findByProductId() method so your entity will need a productId field too.
I would also remove the #ComponentScan annoatation from your application class as this is included by default in #SpringBootApplication unless you are intentionally pointing it at a different class path.
If this still fails as you have mentioned in your comments is it failing for the same reason or is there a different error now related to ProductMapper or ServiceUtil?

spring boot #repository bean from Maven dependency not found

I'm working on multiple Spring Boot projects using spring-data-mongoDB (w/o JPA). One that contains the common (udc-common) components, repositories and services and others (eg udc-gateway) that use these components. the udc-common library is declared as a maven dependency in the other projects.
(you'll find enclosed the maven detailed configurations at the end of this post)
Environment structure
udc_common project
udc_common.models
udc_common.repositories
udc_common.services
udc_common.interfaces
udc_gateway project
udc_gateway.controllers
udc_gateway ....
gatewayApplication.java
gateway pom.xml
<dependency>
<groupId>org.open_si</groupId>
<artifactId>udc-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
in the udc-gateway project I have a rest controller thats refers to a udc-comm SampleService. When running it I face an error
Parameter 0 of constructor in org.open_si.udc_common.services.SampleService required a bean of type 'org.open_si.udc_common.repositories.SampleRepository' that could not be found.
the coding organization is :
the controller (SamplesController) belongs to the gateway project
the service (SampleService) and its repository (SampleRepository) belong to the common project being declared as maven dependency in the gateway project
Obviously the SampleService injection does work but its SampleRepository dependency doesn't. As the common package is an external one I've set the #componentscan accordingly in the gateway app main class
tryed
#ComponentScan("org.open_si.udc_common")
and
#ComponentScan({
"org.open_si.udc_common.repositories",
"org.open_si.udc_common.services"
})
the SamplesController (gateway project) code excerpt related for the SampleService is
#RestController
#RequestMapping("/samples")
public class SamplesController {
#Autowired
private SampleService service;
......
the SampleService (common project) is
#Service
#EnableMongoRepositories
public class SampleService {
#Autowired
private SampleRepository sr;
void insert(BaseSampleEntity sample) {
this.sr.insert(sample);
}
public void delete(BaseSampleEntity sample) {
this.sr.delete(sample);
}
.....
or also tryed
#Service
#EnableMongoRepositories
public class SampleService {
private final SampleRepository sr;
public SampleService(SampleRepository repository) {
sr = repository;
}
void insert(BaseSampleEntity sample) {
this.sr.insert(sample);
}
public void delete(BaseSampleEntity sample) {
this.sr.delete(sample);
}
and the SampleRepository (common project) is
// #Repository (JPA only)
public interface SampleRepository extends MongoRepository<BaseSampleEntity, String> {
List<BaseSampleEntity> findByNodeUuid(String Uuid, Sort sort, Pageable pageable);
List<BaseSampleEntity> findByFieldUuid(String Uuid, Sort sort, Pageable pageable);
so the raised exception
Parameter 0 of constructor in org.open_si.udc_common.services.SampleService required a bean of type 'org.open_si.udc_common.repositories.SampleRepository' that could not be found.
leads me thinking that something is wrong in the spring boot IOC process. Any idea ?
thanks in advance for your help.
udc-common pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.open_si</groupId>
<artifactId>udc-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>UDC common</name>
<packaging>jar</packaging>
<description>Common resources for Universal Data Collector</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>RELEASE</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<!-- <source>1.8</source>-->
<!-- <target>1.8</target>-->
<release>11</release>
</configuration>
</plugin>
</plugins>
</build>
</project>
udc-gateway pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.7.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.open_si</groupId>
<artifactId>gateway</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>Gateway</name>
<description>Gateway for UDC project</description>
<properties>
<java.version>11</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.open_si</groupId>
<artifactId>udc-common</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-oauth2-client</artifactId>-->
<!-- </dependency>-->
<!-- <dependency>-->
<!-- <groupId>org.springframework.boot</groupId>-->
<!-- <artifactId>spring-boot-starter-oauth2-resource-server</artifactId>-->
<!-- </dependency>-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.amqp</groupId>
<artifactId>spring-rabbit-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Try adding below annotation in the spring boot main application class (ie. class annotated with SpringBootApplication - GateWayApplication.java)
#EnableMongoRepositories(basePackages = "org.open_si.udc_common")
#ComponentScan("org.open_si.udc_common.services")
#EntityScan(basePackages ="org.open_si.udc_common.models")
Also, as you mentioned you don't need to annotate repository class with #Repository as this is already managed by spring data
UPDATE:
#SpringBootApplication itself has ComponentScan annoation embedded to it, so it automatically scans all the classes under all the subdirectories.
Hope you have the directory structure somewhat similar to
com.example
--controllers
-- SamplesController
--service
-- SampleService
SampleApplication (this is the class that contains #SpringBootApplication & #EnableMongoRepositories)
Mb you need to add the Spring Data dependency to Maven
As suggested by Kumar V adding
#ComponentScan("org.open_si.udc_common.services")
#EnableMongoRepositories(basePackages = {"org.open_si.udc_common.repositories"})
In the gateway.application.java did the trick.
Unfortunately due to the org.open_si.udc_common.services import, I faced a new issue :
when sending a request against the SamplesController I get an HTTP 404 error.
When removing the ComponentScan of udc-common-services (and the reference to the SampleService in the controller) everythink is ok.
Springs does make some stuff under the wood that I don't understand.

What should be the datasource configuration for cosmosdb in springboot project to use JdbcTemplate

I have provided the azure.cosmosdb.uri, azure.cosmosdb.key and azure.cosmosdb.database definition in my application.properties file.
When I am using DocumentDbRepository, I am able to perform CRUD operations to my cosmos db.
I want to use JDBC template for my project to write customize queries using JDBCTemplate.queryForString() methods. I autowired the JDBCTemplate class in my DAO class:
But still I am getting the below error:
APPLICATION FAILED TO START
Description:
Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
Reason: Failed to determine a suitable driver class
Action:
Consider the following:
If you want an embedded database (H2, HSQL or Derby), please put it on the classpath.
If you have database settings to be loaded from a particular profile you may need to activate it (no profiles are currently active).
DAO class code-
package com.walmart.Ods;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
import java.util.Map;
public class TechDAO{
public void select(String id)
{
String queryString = "SELECT * FROM [DATABASE_NAME] g WHERE g.id = ? ";
#Autowired
private JdbcTemplate jdbcTemplate;
List<Map<String, Object>> result =
getJdbcTemplate().queryForList(queryString, new Object[]{id});
}
}
application.properties file -
azure.cosmosdb.uri=***
azure.cosmosdb.key=***
azure.cosmosdb.database=***
pom.xml file -
https://maven.apache.org/xsd/maven-4.0.0.xsd">
4.0.0
org.springframework.boot
spring-boot-starter-parent
2.1.8.RELEASE
com.walmart
Ods
0.0.1-SNAPSHOT
Ods
Demo project for Spring Boot
<properties>
<java.version>1.8</java.version>
<azure.version>2.1.7</azure.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-cosmosdb-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-spring-boot-bom</artifactId>
<version>${azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

Status 200, but JSP in Spring only displaying un-rendered code

Although my index.jsp opens in a browser with a Status 200 it only displays the JSP code.
I've read through what seem to be all related issues/solutions on this site, but none of the solutions have worked. e.g. adding jstl, jasper, etc. jars into my pom.xml and build path; mapping variations like "/", "/*", etc. No errors in the Spring log- just that JSPs aren't rendering or being "seen" as JSPs. My newest theories are that something is over-writing or conflicting, or that Spring needs something to "see" JSPs under the WEB-INF folder, but it's not easy to debug. Seems a stupid thing that a JSP doesn't render, so any insight would be helpful.
AppConfig
package mil.dfas.springmvc.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
/**
* #author David Higgins
*/
#Configuration
#EnableWebMvc
#ComponentScan(basePackages = {"mil.dfas.springmvc.controller"})
public class AppConfig {
#Bean
public InternalResourceViewResolver resolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setViewClass(JstlView.class);
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
}
LMSInitializer
package mil.dfas.springmvc.config;
import java.util.EnumSet;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import mil.dfas.filters.LoginFilter;
import mil.dfas.filters.TimeoutFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
/**
* The Spring MVC DispatcherServlet needs to be declared and mapped for all request processing.
* In a Servlet 3.0+ environment, AbstractAnnotationConfigDispatcherServletInitializer class is used to register and initialize the DispatcherServlet programmatically.
*
* #author $Author: David Higgins $
* #version $Revision: 1.0 $ $Date: 2019/05/12 $
*/
public class LMSInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
private static final Logger LOGGER = LoggerFactory.getLogger(LMSInitializer.class);
#Override
public void onStartup(ServletContext servletContext) throws ServletException {
FilterRegistration timeoutFilter = servletContext.addFilter("timeoutFilter", new TimeoutFilter());
timeoutFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "*.do");
super.onStartup(servletContext);
}
#Override
protected Filter[] getServletFilters() {
LOGGER.info("LMSInitializer: Configuring Servlet Filters" );
LoginFilter loginFilter = new LoginFilter();
return new Filter[] {new LoginFilter()};
}
#Override
protected Class <?> [] getRootConfigClasses() {
return null;
}
#Override
protected Class <?> [] getServletConfigClasses() {
return new Class[] {AppConfig.class};
}
#Override
protected String[] getServletMappings() {
return new String[] {"/"};
}
}
LMSController
package mil.dfas.springmvc.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
/**
* #author David Higgins
*/
#Controller
public class LMSSpringController {
#RequestMapping(value = "/index", method = RequestMethod.POST)
public ModelAndView forward(Model model) {
System.out.println("LMS Controller");
model.addAttribute("msg","Forward Handled");
return new ModelAndView("index");
}
}
WEB-INF/views/index.jsp
No error messages. JSPs just don't displays as JSPs.
The problem must be something with the pom.xml. It must be a conflict with dependencies. I've added jasper, jstl, and others, but no change. Status 200 and no log errors, but no jsp rendering.
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.7.RELEASE</version> <!-- 2.1.5.RELEASE ? -->
<relativePath />
</parent>
<groupId>mil.dfas.springmvc</groupId>
<artifactId>EmployeeDevelopment</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<failOnMissingWebXml>false</failOnMissingWebXml>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<!-- Spring-boot-starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<scope>provided</scope>
</dependency>
<!-- I think maybe including servlet dependencies is forcing servlet version
to 4.0 since no versions are included, so Spring Boot parent will provide
the defaults and maybe force latest version (?) A lot of this servlet stuff
should already be included in Tomcat bin (on build path) -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<!-- <scope>provided</scope> -->
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
</dependency>
<dependency>
<groupId>com.keypoint</groupId>
<artifactId>png-encoder</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.apache.ant</groupId>
<artifactId>ant</artifactId>
<version>1.8.2</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.12.0</version>
</dependency>
<dependency>
<groupId>org.jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.14</version>
</dependency>
<dependency>
<groupId>jfree</groupId>
<artifactId>jcommon</artifactId>
<version>1.0.16</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>xalan</groupId>
<artifactId>xalan</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>com.lowagie</groupId>
<artifactId>itext</artifactId>
<version>2.1.7</version>
</dependency>
<!-- As Oracle JDBC drivers are not in public Maven repositories (legal
reasons) downloading the jar was the best available option. -->
<dependency>
<groupId>com.oracle.jdbc</groupId>
<artifactId>ojdbc8</artifactId>
<version>12.2.0.1</version>
<scope>system</scope>
<systemPath>${basedir}/src/lib/ojdbc8.jar</systemPath>
</dependency>
<!-- Added 5/17/19 DJM, may want to get directly from Maven repo -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mailapi</artifactId>
<version>1.4.3</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
</dependencies>
<build>
<sourceDirectory>src/main/java</sourceDirectory>
<plugins>
<plugin>
<!-- <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source>
<target>1.8</target> </configuration> -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Package as an executable jar/war -->
</plugins>
</build>
</project>

spring eclipselink static weaving was not enabled or did not occur

Project uses:
spring boot 2.1.1
oracle 12 database
eclipselink 2.6.5
maven 3.6.0
in this project we are using a provided jar with the entities and we created the configuration withouth persistence.xml. The project is created as a war to be deployed in weblogic 12c server but we are testing with springboot inbuilt tomcat server. And ocasionaly on a test server with Weblogic.
When we launch the application in either container we get a lot of EL warnings like the following one:
[EL Warning]: metadata: 2019-02-28 17:10:14.684--ServerSession(1764986459)--Reverting the lazy setting on the OneToOne or ManyToOne attribute [readonlyUserInformation] for the entity class [class com.adquira.mkp.persistence.entities.auditory.AuditoryEvent] since weaving was not enabled or did not occur.
after searching and looking everywhere how to solve this the only similar question we found was this question about static weaving not working in springboot
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.adus</groupId>
<artifactId>adus-backend</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>adus-backend</name>
<description>Adus back-end development</description>
<properties>
<java.version>1.8</java.version>
<springfox-swagger.version>2.9.2</springfox-swagger.version>
<eclipselink.version>2.6.5</eclipselink.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<exclusions>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
</exclusion>
<exclusion>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.adquira.orm</groupId>
<artifactId>adquira-orm</artifactId>
<version>1.0.20</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.2</version>
</dependency>
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${springfox-swagger.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>${eclipselink.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.core</artifactId>
<version>${eclipselink.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>eclipselink</artifactId>
<version>${eclipselink.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The class for configuration
package com.adus.adusbackend;
import java.util.Properties;
import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaDialect;
import org.springframework.orm.jpa.vendor.EclipseLinkJpaVendorAdapter;
#Configuration
#EnableJpaRepositories(basePackages = { "com.adus.adusbackend.repository.user","com.adus.adusbackend.repository.market"})
public class DatasourceConfiguration {
#Bean(destroyMethod = "close")
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
#Bean
EclipseLinkJpaVendorAdapter jpaVendorAdapter() {
EclipseLinkJpaVendorAdapter jpaVendorAdapter = new EclipseLinkJpaVendorAdapter();
jpaVendorAdapter.setDatabasePlatform("org.eclipse.persistence.platform.database.oracle.Oracle12Platform");
jpaVendorAdapter.setGenerateDdl(Boolean.FALSE);
jpaVendorAdapter.setShowSql(Boolean.TRUE);
return jpaVendorAdapter;
}
#Bean
LocalContainerEntityManagerFactoryBean entityManagerFactory(DataSource dataSource) {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource);
entityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter());
entityManagerFactoryBean.setJpaDialect(new EclipseLinkJpaDialect());
// Instead of persistence.xml
entityManagerFactoryBean.setPersistenceUnitName("des");
entityManagerFactoryBean.setPackagesToScan("com.adquira.mkp.persistence.entities");
Properties jpaProperties = new Properties();
jpaProperties.put(PersistenceUnitProperties.WEAVING, detectWeavingMode());
jpaProperties.put(PersistenceUnitProperties.DDL_GENERATION, "none");
entityManagerFactoryBean.setJpaProperties(jpaProperties);
entityManagerFactoryBean.afterPropertiesSet();
return entityManagerFactoryBean;
}
#Bean
JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory);
return transactionManager;
}
private String detectWeavingMode() {
return InstrumentationLoadTimeWeaver.isInstrumentationAvailable() ? "true" : "static";
}
}
You have two challenges.
Firstly: to have static weaving to happen at all and entities enhanced you need a properly configured maven plugin to do that. You need to add weaver plugin to your plugin section. Example from Eclipselink Wiki-page:
<plugins>
...
<plugin>
<groupId>de.empulse.eclipselink</groupId>
<artifactId>staticweave-maven-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>process-classes</phase>
<goals>
<goal>weave</goal>
</goals>
<configuration>
<persistenceXMLLocation>
META-INF/persistence.xml</persistenceXMLLocation>
<logLevel>FINE</logLevel>
</configuration>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.eclipse.persistence</groupId>
<artifactId>org.eclipse.persistence.jpa</artifactId>
<version>${eclipselink.version}</version>
</dependency>
</dependencies>
</plugin>
...
</plugins>
Secondly: you need to make plugin aware the classes in external jar. There were quite few articles about that and I am not sure if it is even possible (easily). The wiki page mentions only about sources to weave which can be in a jar but does not directly say if it is possible also for compiled classes.
For this reason I have always made my entity library jars readily enhanced when compiled from source. But anyway there are some related posts like this.

Resources