Gradle: MessageIOException: не удалось написать сообщение [EndOfStream] на 127.0.0.1 (брандмауэр)?

Я написал простой тестовый проект, который на некоторое время открывает порт 9123 и завершает работу:

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.Date;

import org.apache.mina.core.service.IoAcceptor;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.apache.mina.filter.codec.textline.TextLineCodecFactory;
import org.apache.mina.filter.logging.LoggingFilter;
import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
public class TimeServer
{
    private static final int PORT = 9123;
    public static void main( String[] args ) throws IOException
    {
        IoAcceptor acceptor = new NioSocketAcceptor();
        acceptor.getFilterChain().addLast( "logger", new LoggingFilter() );
        acceptor.getFilterChain().addLast( "codec", new ProtocolCodecFilter( new TextLineCodecFactory( Charset.forName( "UTF-8" ))));
        acceptor.setHandler( new TimeServerHandler() );
        acceptor.getSessionConfig().setReadBufferSize( 2048 );
        acceptor.getSessionConfig().setIdleTime( IdleStatus.BOTH_IDLE, 10 );
        acceptor.bind( new InetSocketAddress(PORT) );
    }

    private static class TimeServerHandler extends IoHandlerAdapter {
        @Override
        public void exceptionCaught(IoSession session, Throwable cause ) throws Exception
        {
            cause.printStackTrace();
        }
        @Override
        public void messageReceived( IoSession session, Object message ) throws Exception
        {
            String str = message.toString();
            if( str.trim().equalsIgnoreCase("quit") ) {
                session.close();
                return;
            }
            Date date = new Date();
            session.write( date.toString() );
            System.out.println("Message written...");
        }
        @Override
        public void sessionIdle( IoSession session, IdleStatus status ) throws Exception
        {
            System.out.println( "IDLE " + session.getIdleCount( status ));
        }
    }
}

...

import java.io.IOException;

public class TimeServerTest {


   @Test
   public void runningTimeServerForTime() throws IOException, InterruptedException {

      int period = 15000;

      System.out.println("Running time server for " + period + "ms");

      TimeServer.main(new String[] {});

      Thread.sleep(period);

      System.out.println("Done, exiting");

      System.exit(0);

   }
}

Этот тест работает нормально под IntelliJ и при выключенном брандмауэре Windows.

Когда брандмауэр Windows включен, он не работает с исключением

>gradle test
:compileJava
Note: PATH\TimeServer.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:processResources UP-TO-DATE
:classes
:compileTestJava
:processTestResources UP-TO-DATE
:testClasses
:test
Unexpected exception thrown.
org.gradle.messaging.remote.internal.MessageIOException: Could not write message [EndOfStream] to '/127.0.0.1:58895'.
        at org.gradle.messaging.remote.internal.inet.SocketConnection.dispatch(SocketConnection.java:111)
        at org.gradle.messaging.remote.internal.hub.MessageHub$ConnectionDispatch.run(MessageHub.java:284)
        at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
        at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at java.lang.Thread.run(Thread.java:745)
Caused by: java.io.IOException: An existing connection was forcibly closed by the remote host
        at sun.nio.ch.SocketDispatcher.write0(Native Method)
        at sun.nio.ch.SocketDispatcher.write(SocketDispatcher.java:51)
        at sun.nio.ch.IOUtil.writeFromNativeBuffer(IOUtil.java:93)
        at sun.nio.ch.IOUtil.write(IOUtil.java:51)
        at sun.nio.ch.SocketChannelImpl.write(SocketChannelImpl.java:471)
        at org.gradle.messaging.remote.internal.inet.SocketConnection$SocketOutputStream.flush(SocketConnection.java:236)
        at org.gradle.messaging.remote.internal.inet.SocketConnection.dispatch(SocketConnection.java:109)
        ... 6 more

BUILD SUCCESSFUL

Что происходит?

Почему указанный порт 58895 сильно отличается от открытого порта 9123?

Как запустить этот тест без отключения брандмауэра?

Какую программу добавить в белый список брандмауэра Windows, чтобы этот тест работал нормально?


person Dims    schedule 09.12.2016    source источник
comment
Из трассировки стека нет видимой ссылки на ваш тест. Если вы не начнете свой TimeServer. Тоже не получится?   -  person SubOptimal    schedule 16.12.2016
comment
Мобильный хост Windows 10 включен?   -  person Jose Antonio Dominguez Garcia    schedule 11.12.2020


Ответы (1)


Это может быть связано с тем, как gradle обрабатывает вызовы System.exit(), см. GRADLE-2759.

Как правило, вызов System.exit() в тестах — не лучшая идея, так как это может испортить тестовую среду (что, если все запускается с одной и той же JVM? Вы бы внезапно отключили ее). Вы должны добавить способ изящного выключения вашего сервера.

Обратите внимание, что сетевая ошибка, похоже, не имеет ничего общего с вашим сетевым кодом или вашим сервером: вы можете видеть из имени пакета в трассировке стека (org.gradle.messaging.remote.internal), что он исходит от Gradle. Вот почему порт отличается и не связан с тем, который вы указали.

Не знаю, почему это пройдет с отключенным брандмауэром Windows.

person Regis Alenda    schedule 18.12.2016
comment
В моем весеннем загрузочном приложении я нигде явно не писал System exit. Тем не менее, я получаю ту же ошибку с другим портом. - person Satish Patro; 10.04.2020