[英]geoserver embedded in spring boot and hibernate/jpa conflict
I am trying to create a web application with spring boot web that needs geoserver to deserve GeoJSON layers.我正在尝试使用 spring boot web 创建一个 web 应用程序,它需要 geoserver 来获得 GeoJSON 层。
I succed to launch geoserver in the same tomcat that my spring-boot application.我成功地在与我的 spring-boot 应用程序相同的 tomcat 中启动了 geoserver。 But there is a problem when GeoServer is trying to access postgresql/postgis database.
但是当 GeoServer 尝试访问 postgresql/postgis 数据库时出现问题。 Geoserver said:
Geoserver 说:
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.我可以通过 spring 应用程序访问存储在 postgresql/postgis 中的数据。
Here there is my pom.xml这是我的 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: TomcatDeployer,在资源的war文件夹中部署war:
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. dao 是一个经典的
CrudRepository<Greffe,String>
扩展。
So is it possible to really embed GeoServer in the same tomcat that the spring-boot application's tomcat?那么是否有可能真正将 GeoServer 嵌入与 spring-boot 应用程序的 tomcat 相同的 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.我不会将 GeoServer 嵌入您的应用程序正在使用的同一个 Tomcat 中。 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.
推理:在 Tomcat 启动期间,GeoServer 和您的应用程序尚未运行(尚未)-但是如果您的应用程序在启动期间需要 GeoServer,它一定会失败。 Solution: Put GeoServer in a serparat Tomcat that starts up before your application is starting.
解决方案:将 GeoServer 放在一个 serparat Tomcat 中,它会在您的应用程序启动之前启动。
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.并给您带来麻烦(和 ClassCastException):确保使用相互匹配的 postgres 和 postgis 驱动程序版本以及您正在使用的数据库版本。 The error you get seems related to https://github.com/brettwooldridge/HikariCP/issues/1476 - maybe the information there can help you.
您得到的错误似乎与https://github.com/brettwooldridge/HikariCP/issues/1476有关 - 也许那里的信息可以帮助您。
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.我个人从未听说过 com.bedatadriven.jackson.datatype.jts - 确保该库的依赖 JTS 版本与您的 GeoServer 中使用的版本相匹配。
And as you are using HibernateSpatial: make sure to configure HibernateSpatial correct.当您使用 HibernateSpatial 时:确保正确配置 HibernateSpatial。 I did not see a configuration.
我没有看到配置。 Maybe using hibernate-spatial for postgis is a solution:
也许对 postgis 使用 hibernate-spatial 是一个解决方案:
<groupId>org.hibernatespatial</groupId>
<artifactId>hibernate-spatial-postgis</artifactId>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.