【问题标题】:Connect a web-app on tomcat container to mysql container via hibernate通过休眠将tomcat容器上的Web应用程序连接到mysql容器
【发布时间】:2017-07-05 08:55:37
【问题描述】:

我正在尝试将我的 web 应用程序从 windows(使用 xampp 用于 apache+mysql)移植到 ubuntu(使用 docker 容器,所以我有两个容器:一个带有 tomcat,另一个带有 mysql.. 它们已链接)。

与此question 相关,我无法访问我的 sql 容器。它来自this image

Tomcat 容器是从官方的 tomcat:8.0 镜像创建的。

这两个容器通过创建的桥接 docker 网络链接。

这是一个提供登录+注册服务并检查用户在数据库中的存在的网络应用程序。

我必须告诉你,在 Windows 上一切正常。

这是我的 hibernate.cfg 文件:

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>

<!-- queste configurazioni sono per il testing in locale  -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:49162/AT_DB</property>

<property name="hibernate.connection.username">root</property>
<property name="connection.password">lxit</property>

<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>

<property name="show_sql">false</property>
<!--<property name="hibernate.hbm2ddl.auto">create-drop</property>  se al posto di update metto create, mi cancella il db e lo rifa -->
<property name="hbm2ddl.auto">update</property>
        <!-- Entity -->

<mapping class="com.ATBoscoCastellano.Entity.ClientUser" />
<mapping class="com.ATBoscoCastellano.Entity.GenericUser" />
<mapping class="com.ATBoscoCastellano.SessionManagement.SessionToken" />
<mapping class="com.ATBoscoCastellano.Entity.Post" />
<!-- <mapping class="it.boscus.StarFoods.entity.ExampleEmbeddableIDClass2" /> -->


    </session-factory>
</hibernate-configuration>

在我插入我的凭据后,我点击“登录”;然后有一个名为“UserSessionServlet”的servlet,它检查数据库中是否存在具有该凭据的用户;单击登录时出现错误,因为 UserSessionServlet 返回 http 500 错误。

[编辑] 在 tomcat 容器上,我看到日志告诉我:

16-Feb-2017 09:43:41.498 SEVERE [http-nio-8080-exec-19] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [com.ATBoscoCastellano.servlets.UserSessionServlet] in context with path [/AtApplicazione1] threw exception [Servlet execution threw an 
exception] with root cause
 java.lang.NoClassDefFoundError: Could not initialize class com.ATBoscoCastellano.Util.HibernateUtil.HibernateUtil
    at com.ATBoscoCastellano.Entity.GenericUser.checkIfUserExistsByEmail(GenericUser.java:198)
    at com.ATBoscoCastellano.Entity.ClientUser.validateCredentials(ClientUser.java:259)
    at com.ATBoscoCastellano.servlets.UserSessionServlet.doPost(UserSessionServlet.java:78)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:509)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1104)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:684)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1520)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1476)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)

但所有这些类都存在于 opt/tomcat/webapps/AtApplicazione1/WEB-INF/classes/com/AtBoscoCastellano/some/paths 下。

我不得不说我没有从官方镜像 (tomcat:8.0) 修改我的 tomcat 容器,所以我不知道它是否配置为休眠。

我的战争结构如下:三个文件夹(META-INF、WEB-INF、模板)和一个文件(.DS_Store)。因为我的例外是 :java.lang.NoClassDefFoundError: Could not initialize class com.ATBoscoCastellano.Util.HibernateUtil.HibernateUtil ,在战争中,这个类在 WEB-INF/classes/com/ATBoscoCastellano/Util/HibernateUtil/ ... 下有 HibernateUtil .class 和 .java。

当我在我的 tomcat 容器上 cmd java/javac -version 时,它的输出是:

root@a26ff8018f3f:/opt/tomcat# java -version
java version "1.8.0_111"
Java(TM) SE Runtime Environment (build 1.8.0_111-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.111-b14, mixed mode)

root@a26ff8018f3f:/opt/tomcat# javac -version
javac "1.8.0_111"

[重新编辑]:在我的第一个请求中,catalina 日志说java.net.ConnectException: Connection refused;然后,从第二个请求开始,它总是对我说同样的错误。

[编辑] 现在我正在使用一个新的 mysql 容器,名为 mysql-phpmyadmin 来自 this 图像。我已将 tomcat 容器链接到这个(新)容器;如果我在 hibernate.cfg.xml 中指向localhost:PORT_MYSQL/AT_DB --> 在 tomcat 日志中拒绝连接。如果我指向mysql-phpmyadmin:PORT/AT_DB,tomcat 日志会说:

17-Feb-2017 08:31:25.649 SEVERE [http-apr-8080-exec-2] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [com.ATBoscoCastellano.servlets.UserSessionServlet] in context with path [/AtApplicazione1] threw exception [Servlet execution threw an e
xception] with root cause
 java.sql.SQLException: null,  message from server: "Host '172.17.0.9' is not allowed to connect to this MySQL server"
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:959)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:898)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:887)
    at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1038)
    at com.mysql.jdbc.ConnectionImpl.coreConnect(ConnectionImpl.java:2254)
    at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2285)
    at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2084)
    at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:795)
    at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:44)

我不得不说,在 mysql 容器的配置文件中,有 bind_address 0.0.0.0

【问题讨论】:

  • 你能从com.ATBoscoCastellano.Util.HibernateUtil.HibernateUtil 的静态块中检查未捕获的异常吗?它可能导致 NoClassDefFoundError
  • @GauravJ 这里 [textuploader.com/d1zpy] 这里是 HibernateUtil.java 的主体。我不知道为什么在 Tomcat+Mysql 容器上它不起作用,在 WIndows 上,使用 Xampp,一切正常。
  • 我无法访问该链接。您的静态初始化程序可能在这种新组合中失败。
  • 请@GauravJ,现在试试。 scribd.com/document/339505288/File

标签: mysql hibernate tomcat jdbc docker


【解决方案1】:

我想我知道您为什么会收到此异常。您正在运行 2 个容器,

  1. 数据库的mysql容器
  2. Tomcat 容器

当然,你的异常是由于静态变量初始化异常,

public static final SessionFactory sessionFactory = buildSessionFactory();

另外,你的属性文件也没有什么问题,

  1. connection.url 应该是 hibernate.connection.url
  2. 您提到您的 mysql 主机名是 localhost,但它正在另一个容器中运行。如果您将 mysql 容器命名为“mysql”,则应将其更改为“mysql”

java.net.ConnectException: Connection refused (Connection refused)
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)
at java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:188)
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:392)
at java.net.Socket.connect(Socket.java:589)
at com.mysql.jdbc.StandardSocketFactory.connect(StandardSocketFactory.java:214)
at com.mysql.jdbc.MysqlIO.<init>(MysqlIO.java:298)

清楚地表明您的任一

  1. Mysql 没有运行。通过从 squirrel 等 sql 客户端建立连接进行检查。
  2. Tomcat 容器无法连接到 mysql 容器。通过执行检查快速 ping

    docker exec tomcat ping mysql  
    

我花了一些时间来部署这个应用程序。我已经解决了你在这个问题中提出的问题。主要问题是无法从 tomcat 容器访问 mysql。此外,指定的端口也不正确。以下是hibernate.cfg.xml,

<!DOCTYPE hibernate-configuration PUBLIC
    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
    <session-factory>

<!-- queste configurazioni sono per il testing in locale  -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://mysql:3306/AT_DB</property>

<property name="hibernate.connection.username">root</property>
<property name="connection.password">lxit</property>

 ....rest of configuration....      

    </session-factory>
</hibernate-configuration>

有以下几个问题,

17-Feb-2017 16:07:53.156 INFO [http-nio-8080-exec-1] org.hibernate.dialect.Dialect.<init> HHH000400: Using dialect: org.hibernate.dialect.MySQLDialect
17-Feb-2017 16:07:53.776 INFO [http-nio-8080-exec-1] org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processGetTableResults HHH000262: Table not found: ClientUser
17-Feb-2017 16:07:53.777 INFO [http-nio-8080-exec-1] org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processGetTableResults HHH000262: Table not found: ClientUser
17-Feb-2017 16:07:53.818 INFO [http-nio-8080-exec-1] org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processGetTableResults HHH000262: Table not found: Post
17-Feb-2017 16:07:53.819 INFO [http-nio-8080-exec-1] org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processGetTableResults HHH000262: Table not found: Post
17-Feb-2017 16:07:53.828 INFO [http-nio-8080-exec-1] org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processGetTableResults HHH000262: Table not found: SessionToken
17-Feb-2017 16:07:53.828 INFO [http-nio-8080-exec-1] org.hibernate.tool.schema.extract.internal.InformationExtractorJdbcDatabaseMetaDataImpl.processGetTableResults HHH000262: Table not found: SessionToken
17-Feb-2017 16:07:53.830 WARN [http-nio-8080-exec-1] org.hibernate.tool.schema.internal.ExceptionHandlerLoggedImpl.handleException GenerationTarget encountered exception accepting command : Unable to execut

但这些是由于 unix 的大小写敏感性,而在 Windows 的情况下可能不存在。其余的异常很容易解决。我运行了以下 docker 命令,

 sudo docker run -ti --rm -p 8888:8080 -p 8009:8009 -v $(pwd):/usr/local/tomcat/webapps/ --name tomcat tomcat:9-jre8 bash

 sudo docker run -d --name mysql -p 49162:3306 -p 49161:80 -p 49160:22 lxitgto/mysql-phpmyadmin:v1

和其余的网络命令。

【讨论】:

  • 对于第一点,1) 那么,为什么在 Windows 上使用(仅)connection.url?对于第二个,2):我的sql容器正确命名为“mysql”但两个容器没有链接,而是属于同一个网络;我有 cmd "docker network create --driver=bridge mynet" 然后将两个容器附加到 mynet。
  • 你能不能先把连接url从localhost改成mysql?
  • 我在 WEB-INF/classes/ 路径中编辑了 hibernate.cfg.xml 文件;仍然有同样的错误,但我还没有重新启动我的 tomcat 容器......我有吗?还是无动于衷?
  • 你应该重启你的容器
  • 我在重启后附加日志;第一个块与第一个请求有关(单击登录按钮);以下块与以下请求有关。这是链接:scribd.com/document/339510950/Logs
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-01
  • 2017-08-20
  • 2016-07-14
  • 2020-03-01
  • 2021-12-03
相关资源
最近更新 更多