hibernate-orm-modules

如前所述,hibernate-orm-modules将Hibernate的最新版本集成到Wildfly 10中。

在Linux和OSX上,测试此模块运行正常,但在Windows上,我们通常会遇到以下测试失败

:hibernate-orm-modules:test

org.hibernate.wildfly.integrationtest.HibernateModulesOnWildflyTest > classMethod FAILED
    org.jboss.arquillian.container.spi.client.container.LifecycleException

1 test completed, 1 failed
:hibernate-orm-modules:test FAILED

找出罪魁祸首

查看测试报告,几乎没有关于正在发生什么的线索

org.jboss.arquillian.container.spi.client.container.LifecycleException: The server is already running! Managed containers do not support connecting to running server instances due to the possible harmful effect of connecting to the wrong server. Please stop server before running or change to another type of container.
To disable this check and allow Arquillian to connect to a running server, set allowConnectingToRunningServer to true in the container configuration
        at org.jboss.as.arquillian.container.managed.ManagedDeployableContainer.failDueToRunning(ManagedDeployableContainer.java:321)
        at org.jboss.as.arquillian.container.managed.ManagedDeployableContainer.startInternal(ManagedDeployableContainer.java:81)
        at org.jboss.as.arquillian.container.CommonDeployableContainer.start(CommonDeployableContainer.java:115)

错误信息表明应用程序服务器已经运行,因此可以有两种解释这种行为的可能

  • 要么设置逻辑有缺陷,服务器启动了两次,但这不可能,因为Linux和OSX上的测试运行正常。

  • 应用程序服务器需要的一个端口被其他进程窃取了,而Arquillian假设我们已经启动了一个服务器实例。

在这种情况下,进行一次好的调试会话可以找出真正的罪魁祸首,在我们的情况下,我可以在org.jboss.as.arquillian.container.managed.ManagedDeployableContainer中识别出问题

private boolean isServerRunning() {
    Socket socket = null;
    try {
        socket = new Socket(
                getContainerConfiguration().getManagementAddress(),
                getContainerConfiguration().getManagementPort());
    } catch (Exception ignored) { // nothing is running on defined ports
        return false;
    } finally {
        if (socket != null) {
            try {
                socket.close();
            } catch (Exception e) {
                throw new RuntimeException("Could not close isServerStarted socket", e);
            }
        }
    }
    return true;
}

Wildfly Arquillian容器试图连接到由org.jboss.as.arquillian.container.CommonContainerConfiguration提供的地址和端口,默认情况下,它使用以下地址和端口信息

managementAddress = "127.0.0.1";
managementPort = 9990 + Integer.decode(System.getProperty("jboss.socket.binding.port-offset", "0"));

如果没有提供jboss.socket.binding.port-offset属性,则默认端口为9990。

让我们看看谁已经在使用这个端口

for /f "tokens=5" %a in ('netstat -ano ^| findstr 9990') do tasklist /fi "pid eq %a"

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
NvNetworkService.exe          2976 Services                   0      4,724 K

NvNetworkService.exe进程是Nvidia使用的网络服务,它用于更新Nvidia驱动程序。

因此,我们有两种选择

  • 要么禁用NvNetworkService.exe进程,然后我们就不会收到任何视频卡驱动程序的更新。

  • 我们使用jboss.socket.binding.port-offset属性,然后Wildfly将使用一个不同的端口,希望它没有被使用。

解决端口抢占问题

由于我不想在我的电脑上运行过时的软件并冒着安全风险,我将选择第二个选项。在搜索了可用端口列表后,我将使用端口10127,这似乎没有被任何软件供应商分配。也就是说,偏移值应该是137。

为了提供jboss.socket.binding.port-offset系统属性,我们需要进行两个更改

  1. 需要将arquillian.xml修改如下

    <group qualifier="Grid" default="true">
        <container qualifier="container.active-1" mode="suite" default="true">
            <configuration>
                <property name="jbossHome">
                    ${buildDir}/wildfly-${wildflyVersion}
                </property>
                <property name="javaVmArguments">
                    -Djava.net.preferIPv4Stack=true
                    -Djgroups.bind_addr=127.0.0.1
                    -Djboss.socket.binding.port-offset=137
                </property>
            </configuration>
        </container>
    </group>
  2. gradle构建脚本也需要提供jboss.socket.binding.port-offset系统属性

    test {
        systemProperties['jboss.socket.binding.port-offset'] = 137
    }

这就完成了。现在,Windows上也能正常运行测试。


返回顶部