I'm trying to write a simple unit test. This test function will call my service, which grabs info from the database, pushes it to a list and returns it. I've looked high and low in the debug logs to find what could be causing, but it seems nothing on the web is helping me out. I'm not too familiar with Spring Boot, but it seems surprising that all this effort and I am unable to get a simple unit test to pass.
Error Logs
http://text-share.com/view/fb0369c3
Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]: Invocation of init method failed;
Example Test
package com.algoq.algoq;
import com.algoq.algoq.models.Subscriber;
import com.algoq.algoq.respositories.SubscriberRepository;
import com.algoq.algoq.services.AlgorithmService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.ArrayList;
import static org.assertj.core.api.Assertions.assertThat;
#RunWith(SpringRunner.class)
#TestConfiguration
#SpringBootTest(classes = {
AlgoQApplication.class,
})
public class ExampleTest extends AlgoQApplicationTests {
#Autowired
private AlgorithmService aService;
#MockBean
private SubscriberRepository employeeRepository;
#Bean
public AlgorithmService aService() {
return new AlgorithmService();
}
#Test
public void subscriberListNull() throws Exception {
ArrayList<Subscriber> subs = aService.getSubscribers();
assertThat(subs).isEmpty();
}
}
Service
package com.algoq.algoq.services;
import com.algoq.algoq.models.Subscriber;
import com.algoq.algoq.respositories.SubscriberRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
#Service
public class AlgorithmService {
#Autowired
private SubscriberRepository subRep;
/**
* Gets a list of subscribers to return to the API
* #return
*/
public ArrayList<Subscriber> getSubscribers() {
ArrayList<Subscriber> subscribers = new ArrayList<>();
subRep.findAll()
.forEach(subscribers::add);
return subscribers;
}
/**
* Adds a new subscriber to the database
* #param sub
* #return
*/
public void addSubscriber(Subscriber sub) {
subRep.save(sub);
}
/**
* Finds a single user id
* #param email
* #return
*/
public List<Subscriber> getSubscriber(String email) {
return subRep.findByEmailAddress(email);
}
}
Application
package com.algoq.algoq;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
#SpringBootApplication
//#EnableScheduling
public class AlgoQApplication {
public static void main(String[] args) {
SpringApplication.run(AlgoQApplication.class, args);
}
}
POM
<?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>
<groupId>com.algoQ</groupId>
<artifactId>algo-q</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>algo-q</name>
<description>An algorithm a day keeps the brain up to date</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>com.itextpdf</groupId>
<artifactId>itextpdf</artifactId>
<version>5.5.12</version>
</dependency>
<dependency>
<groupId>com.itextpdf.tool</groupId>
<artifactId>xmlworker</artifactId>
<version>5.5.12</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.python</groupId>
<artifactId>jython-standalone</artifactId>
<version>2.5.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>1.5.2.RELEASE</version>
</dependency>
<!--<dependency>-->
<!--<groupId>com.h2database</groupId>-->
<!--<artifactId>h2</artifactId>-->
<!--<version>1.4.194</version>-->
<!--</dependency>-->
<dependency>
<groupId>org.pygments</groupId>
<artifactId>pygments</artifactId>
<version>1.5</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
The real cause of the exception is
java.lang.ClassNotFoundException: javax.xml.bind.JAXBException
So I believe you need to add JAXBE library to your classpath (it was removed from JDK in java9 and I guess you are using java9)
Try to add this to your pom file
<!-- https://mvnrepository.com/artifact/javax.xml.bind/jaxb-api -->
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
JDK
/Library/Java/JavaVirtualMachines/jdk-9.0.1.jdk/Contents/Home/bin/java
pom.xml
1.8
Are you using java 8 or 9 ?
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'entityManagerFactory' defined in class path
resource
[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaAutoConfiguration.class]:
Invocation of init method failed; nested exception is
java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException
Issue with java.lang.NoClassDefFoundError: javax/xml/bind/JAXBException ,
Run the application with Java 8 environement or Include the JAXB library for Java 9, JAXB API are not included in JAVA SE 9. Refer Deprecated, for removal: This API element is subject to removal in a future version.. Use --add-modules ( --add-modules java.xml.bind ) to add module in classpath. Jave has only deprecated and does not add javax.xml.bind module on classpath by default.
Otherwise include as dependency through maven.
<dependency>
<groupId>javax.xml.bind</groupId>
<artifactId>jaxb-api</artifactId>
<version>2.3.0</version>
</dependency>
Related
I'm not able to solve the problem with the version of Jaybird's libs package: jaybird-jdk17:3.0.10 where the antlr4-runtime:4.7 is conflicting with the hibernate-core6.1.5Final lib where there is another antlr4:4.10 .1
https://uploaddeimagens.com.br/imagens/vSObP0s
I've tried to change several other Jaybird dependencies but without success, I tried to change the hibernate libs and without success.
Entity
package com.aula.restiapi.entidade;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
#Entity
#NoArgsConstructor
#AllArgsConstructor
#Data
#Table(name = "tb_users")
public class Usuario {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private Double salary;
}
repository
package com.aula.restiapi.repository;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.aula.restiapi.entidade.Usuario;
#Repository
public interface UsuarioRepository extends JpaRepository<Usuario, Long>{
#Query("SELECT obj FROM User obj WHERE obj.salary >= :minSalary AND
obj.salary <= :maxSalary")
Page<Usuario> searchBySalary(Double minSalary, Double maxSalary, Pageable pageable);
}
controller
package com.aula.restiapi.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import com.aula.restiapi.entidade.Usuario;
import com.aula.restiapi.repository.UsuarioRepository;
#RestController
#RequestMapping(value = "/users")
public class UserController {
#Autowired
private UsuarioRepository repository;
#GetMapping
public ResponseEntity<List<Usuario>> findAll() {
List<Usuario> result = repository.findAll();
return ResponseEntity.ok(result);
}
#GetMapping(value = "/page")
public ResponseEntity<Page<Usuario>> findAll(Pageable pageable) {
Page<Usuario> result = repository.findAll(pageable);
return ResponseEntity.ok(result);
}
#GetMapping(value = "/search-salary")
public ResponseEntity<Page<Usuario>> searchBySalary(#RequestParam(defaultValue = "0") Double minSalary, #RequestParam(defaultValue = "1000000000000") Double maxSalary, Pageable pageable) {
Page<Usuario> result = repository.searchBySalary(minSalary, maxSalary, pageable);
return ResponseEntity.ok(result);
}
}
application.properties
spring.datasource.url:jdbc:firebirdsql:localhost/3050:C:/DB/BD_ARTISTS.FDB?
sql_dialect=3&charSet=utf-8
spring.datasource.username:SYSDBA
spring.datasource.password:masterkey
spring.datasource.driver-class-name=org.firebirdsql.jdbc.FBDriver
spring.jpa.database-platform=org.hibernate.community.dialect.FirebirdDialect
spring.jpa.show-sql: true
spring.jpa.properties.hibernate.format_sql=true
#logging.level.org.springframework=DEBUG
app.path.arquivos=/Users/Paulo/Pictures/SavedPictures
spring.servlet.multipart.max-file-size=30MB
spring.servlet.multipart.max-request-size=30MB
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>3.0.0</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.aula</groupId>
<artifactId>restiapi</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>restiapi</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-rest</artifactId>
</dependency>
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird-jdk17</artifactId>
<version>3.0.10</version>
</dependency>
<dependency>
<groupId>org.hibernate.orm</groupId>
<artifactId>hibernate-community-dialects</artifactId>
</dependency>
<dependency>
<groupId>net.java.dev.jna</groupId>
<artifactId>jna</artifactId>
<version>5.5.0</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</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</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
You need to switch to using Jaybird 4.0.8. The problem is that Jaybird 4.0.7 and earlier used a grammar generated with ANTLR 4.7.2 (or earlier). Hibernate 6 upgraded to ANTLR 4.10 (or higher), and there was an incompatible change in ANTLR 4.10, which means the grammar of Jaybird cannot be loaded when ANTLR 4.10 or higher is on the classpath, and vice versa, grammars from libraries using ANTLR 4.10 or higher (like Hibernate) cannot be loaded if ANTLR 4.7.x is on the classpath.
Jaybird 4.0.8 fixed that by removing the reliance on ANTLR 4.7.2 by replacing it with a dependency-less parser.
As an aside, normally you should let Spring Boot handle the dependency version of Jaybird, but Spring Boot 3.0.0 currently defines version 4.0.7.java11.
In any case, remove your current Jaybird dependency (as you're depending on the deprecated artifactId jaybird-jdk17, which is for Java 1.7, not Java 17!) and add:
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird</artifactId>
<version>4.0.8.java11</version>
</dependency>
I do recommend you check the Jaybird 4 release notes if there are any relevant or breaking changes for you.
If you upgrade to Spring Boot 3.0.1 or higher, you can use:
<dependency>
<groupId>org.firebirdsql.jdbc</groupId>
<artifactId>jaybird</artifactId>
</dependency>
and let Spring Boot manage the dependency version.
As an aside, I notice that you have a dependency on net.java.dev.jna:jna listed. If you added that because of Jaybird, then you should remove it. Jaybird only needs JNA when you use native or embedded connections, but your code uses a pure-java JDBC URL for Firebird, so there is no need to add JNA.
I have a spring boot app. It works when fine when I click "run" button in SpringToolSuit4.
But when I run as "maven install", I got the error message:
<error message="Failed to load ApplicationContext" type="java.lang.IllegalStateException">java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is java.lang.IllegalArgumentException: Could not resolve placeholder 'envVersionNum' in value "${envVersionNum}"
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'envVersionNum' in value "${envVersionNum}"
</error>
The content of my application properties:
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.show-sql=true
spring.thymeleaf.cache=false
version=${envVersionNum}
If I change it to
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
spring.jpa.show-sql=true
spring.thymeleaf.cache=false
version=1.1.1
It works fine. But I want to get the envVersionNum from user, which is stored in .bash_profile (export envVersionNum= 1.1.1).
the content of 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.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.jrp</groupId>
<artifactId>project-management</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>project-management</name>
<description>project management application</description>
<properties>
<java.version>1.8</java.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-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>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</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>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
The code of homeController:
package com.jrp.pma.controllers;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jrp.pma.dao.EmployeeRepository;
import com.jrp.pma.dao.ProjectRepository;
import com.jrp.pma.dto.ChartData;
import com.jrp.pma.dto.EmployeeProject;
import com.jrp.pma.entities.Project;
#Controller
public class HomeController {
#Value("${version}")
private String ver;
#Autowired
ProjectRepository proRepo;
#Autowired
EmployeeRepository empRepo;
#GetMapping("/")
public String displayHome(Model model) throws JsonProcessingException {
model.addAttribute("versionNumber", ver);
Map<String, Object> map = new HashMap<>();
// we are querying the database for projects
List<Project> projects = proRepo.findAll();
model.addAttribute("projectsList", projects);
List<ChartData> projectData = proRepo.getProjectStatus();
// Lets convert projectData object into a json structure for use in javascript
ObjectMapper objectMapper = new ObjectMapper();
String jsonString = objectMapper.writeValueAsString(projectData);
//[["NOTSTARTED", 1], ["INPROGRESS", 2], ["COMPLETED", 1]]
model.addAttribute("projectStatusCnt", jsonString);
// we are querying the database for employees
List<EmployeeProject> employeesProjectCnt = empRepo.employeeProjects();
model.addAttribute("employeesListProjectsCnt", employeesProjectCnt);
return "main/home";
}
}
Any suggestions gratefully accepted.
If you're setting any env variable in export command then it it visible only through the command line only.
If you're using Eclipse or any other IDE then it won't get the values from the export command because the scope of the export is inside the terminal.
Try by running your jar after exporting the variables in command line it will work.
I am trying to create a web application with spring boot web that needs geoserver to deserve GeoJSON layers.
I succed to launch geoserver in the same tomcat that my spring-boot application. But there is a problem when GeoServer is trying to access postgresql/postgis database. Geoserver said:
Error occurred getting featuresUnable to obtain connection: Cannot create PoolableConnectionFactory
Due to:
java.lang.ClassCastException: class org.postgis.PGbox2d
at java.lang.Class.asSubclass(Class.java:3404) ~[na:1.8.0_151]
at org.postgresql.jdbc.PgConnection.initObjectTypes(PgConnection.java:645) ~[postgresql-42.1.1.jar:42.1.1]
at org.postgresql.jdbc.PgConnection.<init>(PgConnection.java:296) ~[postgresql-42.1.1.jar:42.1.1]
at org.postgresql.Driver.makeConnection(Driver.java:450) ~[postgresql-42.1.1.jar:42.1.1]
at org.postgresql.Driver.connect(Driver.java:252) ~[postgresql-42.1.1.jar:42.1.1]
...
I can access to data stored in postgresql/postgis via spring application.
Here there is my pom.xml
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.9.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.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-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>net.postgis</groupId>
<artifactId>postgis-jdbc</artifactId>
<version>2.2.0</version>
<exclusions>
<exclusion>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-spatial</artifactId>
<version>5.2.12.Final</version>
</dependency>
<dependency>
<groupId>com.bedatadriven</groupId>
<artifactId>jackson-datatype-jts</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>9.0.2</version>
</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-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
There is also Application:
package fr.app;
import fr.app.dao.GreffeRepository;
import fr.app.util.TomcatDeployer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.context.annotation.Bean;
import java.util.logging.Logger;
#SpringBootApplication
public class GroLocApplication
{
private static final Logger LOGGER = Logger.getLogger(GroLocApplication.class.getName());
public static void main(String... args)
{
SpringApplication.run(GroLocApplication.class, args);
}
#Bean
public EmbeddedServletContainerFactory servletContainerFactory()
{
return new TomcatDeployer();
}
}
The TomcatDeployer, that deploy war in war folder in resources:
package fr.app.util;
import org.apache.catalina.Context;
import org.apache.catalina.loader.WebappLoader;
import org.apache.catalina.startup.Tomcat;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import javax.servlet.ServletException;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.StandardCopyOption;
import java.util.logging.Logger;
final public class TomcatDeployer extends TomcatEmbeddedServletContainerFactory
{
private static final Logger LOGGER = Logger.getLogger(TomcatDeployer.class.getName());
private static final String WAR_TO_DEPLOY = "war/geoserver.war";
private String copyResourceToTmp() throws IllegalStateException
{
try (InputStream resourceStream = getClass().getClassLoader().getResourceAsStream(WAR_TO_DEPLOY))
{
File tmpWar = File.createTempFile("geoserver", ".war");
Files.copy(resourceStream, tmpWar.toPath(), StandardCopyOption.REPLACE_EXISTING);
return tmpWar.getAbsolutePath();
}
catch (IOException e)
{
throw new IllegalStateException("Cannot copy geoserver.war resource", e);
}
}
#Override
protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat)
throws IllegalStateException
{
if (!new File(tomcat.getServer().getCatalinaBase(), "webapps").mkdirs())
{
throw new IllegalStateException("Cannot create a webapps directory on tomcat");
}
try
{
final String pathToWar = copyResourceToTmp();
LOGGER.info(pathToWar);
final Context context = tomcat.addWebapp("/geoserver", pathToWar);
final WebappLoader loader = new WebappLoader(Thread.currentThread().getContextClassLoader());
context.setLoader(loader);
}
catch (ServletException e)
{
throw new IllegalStateException("Failed to add geoserver", e);
}
return super.getTomcatEmbeddedServletContainer(tomcat);
}
}
Greffe entity:
package fr.app.entity;
import com.bedatadriven.jackson.datatype.jts.serialization.GeometryDeserializer;
import com.bedatadriven.jackson.datatype.jts.serialization.GeometrySerializer;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.vividsolutions.jts.geom.Geometry;
import javax.persistence.Entity;
import javax.persistence.Id;
#Entity
public class Greffe
{
#Id
private String id;
#JsonSerialize(using = GeometrySerializer.class)
#JsonDeserialize(using = GeometryDeserializer.class)
private Geometry coord;
// getters...
}
And dao is a classic CrudRepository<Greffe,String> extends.
So is it possible to really embed GeoServer in the same tomcat that the spring-boot application's tomcat? (it's possible because I did so, but is it really a good idea?)
And if so, how can I avoid this kind of trouble?!
Thanks by advance :)
I would not embed GeoServer in the same Tomcat your application is using. Yes, it is possible, yes; but not a really good idea.
Reasoning: During Tomcat startup, GeoServer and your application is not running (yet) - but if your application needs GeoServer during startup it must fail.
Solution: Put GeoServer in a serparat Tomcat that starts up before your application is starting.
And to your trouble (and the ClassCastException):
Make sure to use a postgres and postgis driver version matching each other and the database version you are using.
The error you get seems related to https://github.com/brettwooldridge/HikariCP/issues/1476 - maybe the information there can help you.
I personally never heard of com.bedatadriven.jackson.datatype.jts - make sure the depending JTS version of that library matches the versions used in your GeoServer.
And as you are using HibernateSpatial: make sure to configure HibernateSpatial correct. I did not see a configuration.
Maybe using hibernate-spatial for postgis is a solution:
<groupId>org.hibernatespatial</groupId>
<artifactId>hibernate-spatial-postgis</artifactId>
I am trying to configure the spring boot with jersey but it seems jersey annotations are not working with spring boot.
can you please help me out.
I have tried #RestController instead of #Component and #RequestMapping instead of #Path in service class.
pom.xml
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>org.hotel</groupId>
<artifactId>reservations</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>reservations</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.RELEASE</version>
<relativePath/>
<!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>1.4.2.RELEASE</version>
</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-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-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>
Spring Boot Application Xml
package org.hotel;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ReservationApplication {
public static void main(String []args){
SpringApplication.run(ReservationApplication.class, args);
}
}
service class with jersey annotations
package org.hotel.webservices;
import org.springframework.stereotype.Component;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
#Component
#Path("/rooms")
public class AddRoomService {
#GET
public String addRoomService(){
return "success";
}
}
Nice tutorial online about this:
Spring Boot Jersey Example July 14, 2017 by Lokesh Gupta. This seems to be the part you're missing.
Jersey Configuration
1: Now we have a JAX-RS resource and we want to access it from spring boot application which include Jersey dependency. Let’s register this resource as Jersey resource.
package com.howtodoinjava.jerseydemo;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
#Component
public class JerseyConfig extends ResourceConfig
{
public JerseyConfig()
{
register(UserResource.class);
}
}
Look at the #Component annotation. It enables this class to be registered while spring boot auto scans the java classes in source folder.
2: ResourceConfig provides advanced capabilities to simplify registration of JAX-RS components.
3: Extend spring boot application with SpringBootServletInitializer.
package com.howtodoinjava.jerseydemo;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
#SpringBootApplication
public class JerseydemoApplication extends SpringBootServletInitializer
{
public static void main(String[] args)
{
new JerseydemoApplication().configure(new SpringApplicationBuilder (JerseydemoApplication.class)).run(args);
}
}
Just to add to the answer from Nicholas agreed its an excellent tutorial but if you wish to restructure the project (for example create multiple packages for your resources, models etc) you must ensure that the JerseyConfig class and JerseydemoApplication class are in the same package, otherwise the registration wont work. This is not explicitly mentioned in the tutorial.
I found this while working in intellij ultimate edition and following same tutorial provided by Nicholas above
Basically, what I want in the end, is that an object in some piece of code is wired up with my Spring Component, although that object is not created / managed by Spring.
The object in question is:
package demo;
import org.springframework.beans.factory.annotation.Autowire;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
#Configurable(autowire= Autowire.BY_TYPE)
public class NotSoSpring {
SpringComponent springComponent;
public NotSoSpring() {
springComponent.test();
}
#Autowired
public void setSpringComponent(SpringComponent springComponent) {
this.springComponent = springComponent;
}
public void test() {
springComponent.test();
}
}
And the component is as simple as that:
package demo;
import org.springframework.stereotype.Component;
#Component
public class SpringComponent {
public void test() {
System.out.println("Hello. Wow, this works!");
}
}
The Spring configuration is done by the following piece of code:
package demo;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.EnableLoadTimeWeaving;
import org.springframework.context.annotation.aspectj.EnableSpringConfigured;
#SpringBootApplication
#EnableSpringConfigured
#EnableLoadTimeWeaving(aspectjWeaving = EnableLoadTimeWeaving.AspectJWeaving.ENABLED)
#EnableAspectJAutoProxy
#ComponentScan(basePackages = "demo")
public class DemoApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
#Override
public void run(String... strings) throws Exception {
NotSoSpring spring = new NotSoSpring();
spring.test();
}
}
And here's the project's configuration:
<?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>
<groupId>org.test</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.2.5.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
</dependency>
<dependency>
<groupId>javax.el</groupId>
<artifactId>javax.el-api</artifactId>
<version>3.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
That's all the files, and here's the JVM command line option I used:
-javaagent:c:/.m2/repository/org/springframework/spring-instrument/4.1.5.RELEASE/spring-instrument-4.1.5.RELEASE.jar
So this results in
Exception in thread "main" java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:675)
at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:690)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:321)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946)
at demo.DemoApplication.main(DemoApplication.java:19)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:140)
Caused by: java.lang.NullPointerException
at demo.NotSoSpring.<init>(NotSoSpring.java:13)
at demo.DemoApplication.run(DemoApplication.java:24)
at org.springframework.boot.SpringApplication.runCommandLineRunners(SpringApplication.java:672)
... 10 more
I looked through other SO questions, the Spring Documentation and a lot of blogs, but unfortunately they usually refer to Spring 3 and to XML based configurations.
Might be related to this question which has no solution either.