无法使用本地Tomcat服务器上的Java REST-API连接到pgsql数据库。堆栈包含ExceptionInInitializerError和IllegalStateException [英] Unable to connect to pgsql database with Java REST-API on local Tomcat server. Stack contains ExceptionInInitializerError and IllegalStateException

查看:135
本文介绍了无法使用本地Tomcat服务器上的Java REST-API连接到pgsql数据库。堆栈包含ExceptionInInitializerError和IllegalStateException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发REST-API,目前正在尝试解决问题。问题是当我进入chrome的网页时,REST-API无法连接到pgsql数据库。为了显示此问题,我将发布堆栈的简化版本并提供一些解释,以描述所涉及的Java类和XML的起源和功能。然后,我将显示一些有关XML文件和Java类的代码。我会很高兴收到您的第一篇文章。


更新:在文章结尾,我将透露我在寻找答案方面的主要进展。

UPDATE: at the end of the post I'll disclose my major progress towards finding the answer.

到目前为止,我正在使用以下内容工具:

Up till now I'm using the following tools:


  • Eclipse EE(目前为氧气II)

  • Apache Tomcat 8.5.14

  • Maven

  • Chrome

  • PG-admin 4

  • Eclipse EE (Oxygen II at the moment)
  • Apache Tomcat 8.5.14
  • Maven
  • Chrome
  • PG-admin 4

堆栈从这一行开始,这可能意味着Jersey遇到了一些困难。

the stack begins with this line, which probably means Jersey runs into some difficulties.

WARNING: The following warnings have been detected: WARNING: Unknown HK2 failure detected:

我的堆栈继续运行下面显示的java.lang.ExceptionInInitializerError源自我的数据库连接代理。

My stack continues with java.lang.ExceptionInInitializerError shown below, originating from my database connection broker.

MultiException stack 1 of 2
java.lang.ExceptionInInitializerError
at nl.hu.v1wac.PostgresDAO.webservices.WorldResource.<init (WorldResource.java:25) 
Caused by: java.lang.RuntimeException: javax.naming.NameNotFoundException: Name [jdbc/PostgresDS] is not bound in this Context. Unable to find [jdbc].
at nl.hu.v1wac.PostgresDAO.jdbc.BaseDAO.<init>(BaseDAO.java:38)
at nl.hu.v1wac.PostgresDAO.jdbc.CountryDAO.<init>(CountryDAO.java:13)
at nl.hu.v1wac.PostgresDAO.model.WorldService.<init>(WorldService.java:9)
at nl.hu.v1wac.PostgresDAO.model.ServiceProvider.<clinit>(ServiceProvider.java:4)
... 61 more

多堆栈中的第二个异常是IllegalStateException,该异常源于我的WorldResource类,其中包含用于将JSON消息解析到我的前端的统一资源标识符和JSON解释器。

the second exception in the multistack is the IllegalStateException, originating from my WorldResource class, containing the Unified Resource Identifiers and JSON interpreter for parsing json messages to my front-end.

MultiException stack 2 of 2
java.lang.IllegalStateException: Unable to perform operation: create on nl.hu.v1wac.PostgresDAO.webservices.WorldResource
Caused by: java.lang.RuntimeException: javax.naming.NameNotFoundException: 
at org.jvnet.hk2.internal.ClazzCreator.create(ClazzCreator.java:393)
at org.glassfish.jersey.servlet.WebComponent.service(WebComponent.java:427)
    at org.glassfish.jersey.servlet.ServletContainer.service(ServletContainer.java:388)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)

下面将显示

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">
  <display-name>MavenJersey</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
    <welcome-file>default.html</welcome-file>
    <welcome-file>default.htm</welcome-file>
    <welcome-file>default.jsp</welcome-file>
  </welcome-file-list>
  <servlet>
    <servlet-name>Jersey REST Service</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
      <param-name>jersey.config.server.provider.packages</param-name>
      <param-value>nl.hu.v1wac.PostgresDAO.webservices</param-value>
    </init-param>
    <init-param>
      <param-name>jersey.config.server.provider.classnames</param-name>
      <param-value>org.glassfish.jersey.server.filter.RolesAllowedDynamicFeature</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>Jersey REST Service</servlet-name>
    <url-pattern>/restservices/*</url-pattern>
  </servlet-mapping>
</web-app>

在下面的错误中显示我的BaseDAO。此类是我的数据访问对象的连接代理。

Below Ill show my BaseDAO. This class is a connection broker for my Data Access Objects.

import java.sql.Connection;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.net.URI;
import org.apache.tomcat.dbcp.dbcp2.BasicDataSource;

public class BaseDAO {
    private static final String URL = "jdbc:postgresql://";
    private static final String JDBC_DRIVER = "org.postgresql.Driver";
    private static final String CONTEXT = "java:comp/env/jdbc/PostgresDS";
    private DataSource connectionPool;
    public BaseDAO() {
    try {
        final String DATABASE_URL_PROP = System.getenv("DATABASE_URL");
        if (DATABASE_URL_PROP != null) {
            URI dbUri = new URI(DATABASE_URL_PROP);
            String dbUrl = URL + dbUri.getHost() + dbUri.getPath();
            BasicDataSource pool = new BasicDataSource();

            if (dbUri.getUserInfo() != null) {
                pool.setUsername(dbUri.getUserInfo().split(":")[0]);
                pool.setPassword(dbUri.getUserInfo().split(":")[1]);
                }
                pool.setDriverClassName(JDBC_DRIVER);
                pool.setUrl(dbUrl);
                pool.setInitialSize(1);

                connectionPool = pool;

        } else{
            InitialContext ic = new InitialContext();
            connectionPool = (DataSource) ic.lookup(CONTEXT);
        }
    } catch (Exception e) {

      throw new RuntimeException(e);
    }
    }
  protected final Connection getConnection() {
      try {
          return connectionPool.getConnection();
      } catch (Exception ex) {
          throw new RuntimeException(ex);
      }
  }
}

最后,我总结一下我的WorldResource类的这篇文章。请注意,大多数代码都被排除在外。

Finally, I'll conclude this post with my WorldResource class. please note that most code is excluded.

public class WorldResource{
    private WorldService service = ServiceProvider.getWorldService();    
@GET
@RolesAllowed({"admin"})
@Path("/getAll")
@Produces(MediaType.APPLICATION_JSON)
public String getCountries() {
        JsonArrayBuilder jab;
        jab = Json.createArrayBuilder();
        for (Country c : service.getAllCountries()) {
            jab.add(makeCountryObj(c));
        }
        return jab.build().toString();
}

编辑:@ Alok Sinha发布后, context.xml丢失了,我添加了我已经存在的context.xml,以提供一些额外的见识。

After @Alok Sinha posted that the context.xml is missing, I added my already existing context.xml to give some extra insight.

<?xml version="1.0" encoding="UTF-8"?> 
<Context> <Resource name="jdbc/PostgresDS" 

url="jdbc:postgresql://localhost:5432/mydb" driverClassName="org.postgresql.Driver" 
auth="Container" 
type="javax.sql.DataSource" 
username="javaduser" 
password="javadude" 
/> 
<ResourceLink name="jdbc/PostgresDS" global="jdbc/PostgresDS" type="javax.sql.DataSource" 
/>
</Context>

更新::在向我的web.xml添加资源引用后,建议通过 Apache手册,我当时

UPDATE: after adding a resource references to my web.xml, recommended by this manual of Apache, I was able to get some new insight in my connection problems.

  <resource-ref>
    <description>PostgreSQL Datasource example</description>
    <res-ref-name>jdbc/PostgresDS</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

如下面的堆栈所示,似乎添加资源引用有助于将我的应用程序指向右侧方向。但是,名称和网址似乎为空。

As shown in the stack below, it seems that adding a resource ref helps pointing my Application into the right direction. however, the name and url seem to be empty.

Cannot create JDBC driver of class '' for connect URL 'null'
java.sql.SQLException: No suitable driver
at java.sql.DriverManager.getDriver(Unknown Source)
at nl.hu.v1wac.PostgresDAO.jdbc.BaseDAO.getConnection(BaseDAO.java:47)
at nl.hu.v1wac.PostgresDAO.webservices.WorldResource.getCountries(WorldResource.java:34)

UPDATE2:
我尝试了另一种方法。我从最初的Maven项目开始,然后从那里开始构建我的应用程序。我摆脱了IllegalstateException。我已经按照 Alok Sinha 所述实施了您的context.xml。因此,没有Resourcelink。我还取消了BaseDAO的衣服,使其只有一个InitialContext和一个数据源。现在,我可以将应用程序部署为war文件,而无需进行基础设置。如果我尝试使用BaseDAO部署它,由于tomcat日志中出现以下错误,我将无法运行:

UPDATE2: I've tried another approach. I began with an initial maven project, and build my application up from there. I got rid of the IllegalstateException. I've implemented your context.xml exactly as Alok Sinha described. So, no Resourcelink. I've also undressed the BaseDAO to a point where it only has an Initialcontext and a Datasource. Now I can deploy the application as a war file without the basedao. If I try to deploy it with BaseDAO, I can't run due to the following error in my tomcat log:

org.apache.catalina.deploy.NamingResourcesImpl.cleanUp Failed to retrieve
JNDI naming context for container [StandardEngine[Catalina].StandardHost[localhost].StandardContext[/holidayboardapp]] so no cleanup was performed for that container 
  javax.naming.NameNotFoundException: Name [comp/env] is not bound in this Context. Unable to find [comp].`


推荐答案

您尚未将数据源绑定到tomcat的JNDI中。您将需要在context.xml中进行输入,如下所示-

It appears that you have not bound your datasource in tomcat's JNDI. You would need to make an entry in context.xml , like the below -

<Resource name="jdbc/PostgresDS" auth="Container" type="javax.sql.DataSource"
           maxActive="100" maxIdle="30" maxWait="10000"
           username="javauser" password="javadude" driverClassName="org.postgresql.Driver"
           url="jdbc:postgresql:localhost..."/>

这篇关于无法使用本地Tomcat服务器上的Java REST-API连接到pgsql数据库。堆栈包含ExceptionInInitializerError和IllegalStateException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆