Cleanup and throw exception if bind failed (#12987)
This commit is contained in:
parent
8d9817f8af
commit
0bfd54cea4
|
|
@ -96,7 +96,9 @@ public class QosProtocolWrapper implements Protocol, ScopeModelAware {
|
||||||
return protocol.getServers();
|
return protocol.getServers();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startQosServer(URL url) {
|
private void startQosServer(URL url) throws RpcException {
|
||||||
|
boolean qosCheck = url.getParameter(QOS_CHECK, false);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!hasStarted.compareAndSet(false, true)) {
|
if (!hasStarted.compareAndSet(false, true)) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -132,9 +134,8 @@ public class QosProtocolWrapper implements Protocol, ScopeModelAware {
|
||||||
|
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
logger.warn(QOS_FAILED_START_SERVER, "", "", "Fail to start qos server: ", throwable);
|
logger.warn(QOS_FAILED_START_SERVER, "", "", "Fail to start qos server: ", throwable);
|
||||||
boolean qosCheck = url.getParameter(QOS_CHECK, false);
|
|
||||||
if (qosCheck) {
|
if (qosCheck) {
|
||||||
throw new IllegalStateException("Fail to start qos server: " + throwable.getMessage(), throwable);
|
throw new RpcException(throwable);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership.
|
||||||
|
* The ASF licenses this file to You under the Apache License, Version 2.0
|
||||||
|
* (the "License"); you may not use this file except in compliance with
|
||||||
|
* the License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.dubbo.qos.server;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicate that if Qos Start failed
|
||||||
|
*/
|
||||||
|
public class QosBindException extends RuntimeException {
|
||||||
|
public QosBindException(String message, Throwable cause) {
|
||||||
|
super(message, cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -35,8 +35,6 @@ import io.netty.util.concurrent.DefaultThreadFactory;
|
||||||
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
import static org.apache.dubbo.common.constants.LoggerCodeConstants.QOS_FAILED_START_SERVER;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A server serves for both telnet access and http access
|
* A server serves for both telnet access and http access
|
||||||
* <ul>
|
* <ul>
|
||||||
|
|
@ -105,13 +103,13 @@ public class Server {
|
||||||
@Override
|
@Override
|
||||||
protected void initChannel(Channel ch) throws Exception {
|
protected void initChannel(Channel ch) throws Exception {
|
||||||
ch.pipeline().addLast(new QosProcessHandler(frameworkModel,
|
ch.pipeline().addLast(new QosProcessHandler(frameworkModel,
|
||||||
QosConfiguration.builder()
|
QosConfiguration.builder()
|
||||||
.welcome(welcome)
|
.welcome(welcome)
|
||||||
.acceptForeignIp(acceptForeignIp)
|
.acceptForeignIp(acceptForeignIp)
|
||||||
.acceptForeignIpWhitelist(acceptForeignIpWhitelist)
|
.acceptForeignIpWhitelist(acceptForeignIpWhitelist)
|
||||||
.anonymousAccessPermissionLevel(anonymousAccessPermissionLevel)
|
.anonymousAccessPermissionLevel(anonymousAccessPermissionLevel)
|
||||||
.anonymousAllowCommands(anonymousAllowCommands)
|
.anonymousAllowCommands(anonymousAllowCommands)
|
||||||
.build()
|
.build()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -124,8 +122,7 @@ public class Server {
|
||||||
|
|
||||||
logger.info("qos-server bind localhost:" + port);
|
logger.info("qos-server bind localhost:" + port);
|
||||||
} catch (Throwable throwable) {
|
} catch (Throwable throwable) {
|
||||||
logger.error(QOS_FAILED_START_SERVER, "", "", "qos-server can not bind localhost:" + port, throwable);
|
throw new QosBindException("qos-server can not bind localhost:" + port, throwable);
|
||||||
throw throwable;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,10 @@ public interface Constants {
|
||||||
|
|
||||||
String BIND_PORT_KEY = "bind.port";
|
String BIND_PORT_KEY = "bind.port";
|
||||||
|
|
||||||
|
String BIND_RETRY_TIMES = "bind.retry.times";
|
||||||
|
|
||||||
|
String BIND_RETRY_INTERVAL = "bind.retry.interval";
|
||||||
|
|
||||||
String SENT_KEY = "sent";
|
String SENT_KEY = "sent";
|
||||||
|
|
||||||
String DISPATCHER_KEY = "dispatcher";
|
String DISPATCHER_KEY = "dispatcher";
|
||||||
|
|
|
||||||
|
|
@ -97,14 +97,14 @@ public class NettyPortUnificationServer extends AbstractPortUnificationServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind() {
|
public void bind() throws Throwable {
|
||||||
if (channel == null) {
|
if (channel == null) {
|
||||||
doOpen();
|
doOpen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void doOpen() {
|
public void doOpen() throws Throwable {
|
||||||
bootstrap = new ServerBootstrap();
|
bootstrap = new ServerBootstrap();
|
||||||
|
|
||||||
bossGroup = NettyEventLoopFactory.eventLoopGroup(1, EVENT_LOOP_BOSS_POOL_NAME);
|
bossGroup = NettyEventLoopFactory.eventLoopGroup(1, EVENT_LOOP_BOSS_POOL_NAME);
|
||||||
|
|
@ -138,9 +138,31 @@ public class NettyPortUnificationServer extends AbstractPortUnificationServer {
|
||||||
bindIp = ANYHOST_VALUE;
|
bindIp = ANYHOST_VALUE;
|
||||||
}
|
}
|
||||||
InetSocketAddress bindAddress = new InetSocketAddress(bindIp, bindPort);
|
InetSocketAddress bindAddress = new InetSocketAddress(bindIp, bindPort);
|
||||||
ChannelFuture channelFuture = bootstrap.bind(bindAddress);
|
try {
|
||||||
channelFuture.syncUninterruptibly();
|
ChannelFuture channelFuture = bootstrap.bind(bindAddress);
|
||||||
channel = channelFuture.channel();
|
channelFuture.syncUninterruptibly();
|
||||||
|
channel = channelFuture.channel();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
closeBootstrap();
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeBootstrap() {
|
||||||
|
try {
|
||||||
|
if (bootstrap != null) {
|
||||||
|
long timeout = ConfigurationUtils.reCalShutdownTime(serverShutdownTimeoutMills);
|
||||||
|
long quietPeriod = Math.min(2000L, timeout);
|
||||||
|
Future<?> bossGroupShutdownFuture = bossGroup.shutdownGracefully(quietPeriod,
|
||||||
|
timeout, MILLISECONDS);
|
||||||
|
Future<?> workerGroupShutdownFuture = workerGroup.shutdownGracefully(quietPeriod,
|
||||||
|
timeout, MILLISECONDS);
|
||||||
|
bossGroupShutdownFuture.awaitUninterruptibly(timeout, MILLISECONDS);
|
||||||
|
workerGroupShutdownFuture.awaitUninterruptibly(timeout, MILLISECONDS);
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
@ -176,20 +198,7 @@ public class NettyPortUnificationServer extends AbstractPortUnificationServer {
|
||||||
protocol.close();
|
protocol.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
closeBootstrap();
|
||||||
if (bootstrap != null) {
|
|
||||||
long timeout = ConfigurationUtils.reCalShutdownTime(serverShutdownTimeoutMills);
|
|
||||||
long quietPeriod = Math.min(2000L, timeout);
|
|
||||||
Future<?> bossGroupShutdownFuture = bossGroup.shutdownGracefully(quietPeriod,
|
|
||||||
timeout, MILLISECONDS);
|
|
||||||
Future<?> workerGroupShutdownFuture = workerGroup.shutdownGracefully(quietPeriod,
|
|
||||||
timeout, MILLISECONDS);
|
|
||||||
bossGroupShutdownFuture.awaitUninterruptibly(timeout, MILLISECONDS);
|
|
||||||
workerGroupShutdownFuture.awaitUninterruptibly(timeout, MILLISECONDS);
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -105,10 +105,14 @@ public class NettyServer extends AbstractServer {
|
||||||
initServerBootstrap(nettyServerHandler);
|
initServerBootstrap(nettyServerHandler);
|
||||||
|
|
||||||
// bind
|
// bind
|
||||||
ChannelFuture channelFuture = bootstrap.bind(getBindAddress());
|
try {
|
||||||
channelFuture.syncUninterruptibly();
|
ChannelFuture channelFuture = bootstrap.bind(getBindAddress());
|
||||||
channel = channelFuture.channel();
|
channelFuture.syncUninterruptibly();
|
||||||
|
channel = channelFuture.channel();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
closeBootstrap();
|
||||||
|
throw t;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected EventLoopGroup createBossGroup() {
|
protected EventLoopGroup createBossGroup() {
|
||||||
|
|
@ -172,6 +176,17 @@ public class NettyServer extends AbstractServer {
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
|
closeBootstrap();
|
||||||
|
try {
|
||||||
|
if (channels != null) {
|
||||||
|
channels.clear();
|
||||||
|
}
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeBootstrap() {
|
||||||
try {
|
try {
|
||||||
if (bootstrap != null) {
|
if (bootstrap != null) {
|
||||||
long timeout = ConfigurationUtils.reCalShutdownTime(serverShutdownTimeoutMills);
|
long timeout = ConfigurationUtils.reCalShutdownTime(serverShutdownTimeoutMills);
|
||||||
|
|
@ -184,13 +199,6 @@ public class NettyServer extends AbstractServer {
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
if (channels != null) {
|
|
||||||
channels.clear();
|
|
||||||
}
|
|
||||||
} catch (Throwable e) {
|
|
||||||
logger.warn(TRANSPORT_FAILED_CLOSE, "", "", e.getMessage(), e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
||||||
|
|
@ -21,13 +21,13 @@ import org.apache.dubbo.common.constants.CommonConstants;
|
||||||
import org.apache.dubbo.common.utils.NetUtils;
|
import org.apache.dubbo.common.utils.NetUtils;
|
||||||
import org.apache.dubbo.config.ApplicationConfig;
|
import org.apache.dubbo.config.ApplicationConfig;
|
||||||
import org.apache.dubbo.config.context.ConfigManager;
|
import org.apache.dubbo.config.context.ConfigManager;
|
||||||
import org.apache.dubbo.remoting.RemotingException;
|
|
||||||
import org.apache.dubbo.remoting.api.connection.AbstractConnectionClient;
|
import org.apache.dubbo.remoting.api.connection.AbstractConnectionClient;
|
||||||
import org.apache.dubbo.remoting.api.connection.ConnectionManager;
|
import org.apache.dubbo.remoting.api.connection.ConnectionManager;
|
||||||
import org.apache.dubbo.remoting.api.connection.MultiplexProtocolConnectionManager;
|
import org.apache.dubbo.remoting.api.connection.MultiplexProtocolConnectionManager;
|
||||||
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
||||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
|
@ -50,7 +50,7 @@ public class ConnectionTest {
|
||||||
private static ConnectionManager connectionManager;
|
private static ConnectionManager connectionManager;
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void init() throws RemotingException {
|
public static void init() throws Throwable {
|
||||||
int port = NetUtils.getAvailablePort();
|
int port = NetUtils.getAvailablePort();
|
||||||
url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
||||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||||
|
|
@ -123,7 +123,7 @@ public class ConnectionTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void connectSyncTest() throws RemotingException {
|
void connectSyncTest() throws Throwable {
|
||||||
int port = NetUtils.getAvailablePort();
|
int port = NetUtils.getAvailablePort();
|
||||||
URL url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
URL url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
||||||
NettyPortUnificationServer nettyPortUnificationServer = new NettyPortUnificationServer(url, new DefaultPuHandler());
|
NettyPortUnificationServer nettyPortUnificationServer = new NettyPortUnificationServer(url, new DefaultPuHandler());
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,10 @@ import org.apache.dubbo.common.constants.CommonConstants;
|
||||||
import org.apache.dubbo.common.utils.NetUtils;
|
import org.apache.dubbo.common.utils.NetUtils;
|
||||||
import org.apache.dubbo.config.ApplicationConfig;
|
import org.apache.dubbo.config.ApplicationConfig;
|
||||||
import org.apache.dubbo.config.context.ConfigManager;
|
import org.apache.dubbo.config.context.ConfigManager;
|
||||||
import org.apache.dubbo.remoting.RemotingException;
|
|
||||||
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
||||||
|
|
||||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
|
|
@ -34,7 +33,7 @@ import static org.apache.dubbo.common.constants.CommonConstants.EXECUTOR_MANAGEM
|
||||||
class PortUnificationServerTest {
|
class PortUnificationServerTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testBind() throws RemotingException {
|
void testBind() throws Throwable {
|
||||||
int port = NetUtils.getAvailablePort();
|
int port = NetUtils.getAvailablePort();
|
||||||
URL url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
URL url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
||||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,14 @@ import org.apache.dubbo.common.URL;
|
||||||
import org.apache.dubbo.common.constants.CommonConstants;
|
import org.apache.dubbo.common.constants.CommonConstants;
|
||||||
import org.apache.dubbo.config.ApplicationConfig;
|
import org.apache.dubbo.config.ApplicationConfig;
|
||||||
import org.apache.dubbo.config.context.ConfigManager;
|
import org.apache.dubbo.config.context.ConfigManager;
|
||||||
import org.apache.dubbo.remoting.RemotingException;
|
|
||||||
import org.apache.dubbo.remoting.api.connection.AbstractConnectionClient;
|
import org.apache.dubbo.remoting.api.connection.AbstractConnectionClient;
|
||||||
import org.apache.dubbo.remoting.api.connection.ConnectionManager;
|
import org.apache.dubbo.remoting.api.connection.ConnectionManager;
|
||||||
import org.apache.dubbo.remoting.api.connection.MultiplexProtocolConnectionManager;
|
import org.apache.dubbo.remoting.api.connection.MultiplexProtocolConnectionManager;
|
||||||
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
import org.apache.dubbo.remoting.api.pu.DefaultPuHandler;
|
||||||
import org.apache.dubbo.remoting.transport.netty4.NettyPortUnificationServer;
|
import org.apache.dubbo.remoting.transport.netty4.NettyPortUnificationServer;
|
||||||
|
|
||||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
|
@ -52,7 +51,7 @@ public class MultiplexProtocolConnectionManagerTest {
|
||||||
private static ConnectionManager connectionManager;
|
private static ConnectionManager connectionManager;
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void init() throws RemotingException {
|
public static void init() throws Throwable {
|
||||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||||
ApplicationConfig applicationConfig = new ApplicationConfig("provider-app");
|
ApplicationConfig applicationConfig = new ApplicationConfig("provider-app");
|
||||||
applicationConfig.setExecutorManagementMode(EXECUTOR_MANAGEMENT_MODE_DEFAULT);
|
applicationConfig.setExecutorManagementMode(EXECUTOR_MANAGEMENT_MODE_DEFAULT);
|
||||||
|
|
@ -95,7 +94,7 @@ public class MultiplexProtocolConnectionManagerTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testForEachConnection() throws RemotingException {
|
public void testForEachConnection() throws Throwable {
|
||||||
DefaultPuHandler handler = new DefaultPuHandler();
|
DefaultPuHandler handler = new DefaultPuHandler();
|
||||||
|
|
||||||
NettyPortUnificationServer server2 = new NettyPortUnificationServer(url2, handler);
|
NettyPortUnificationServer server2 = new NettyPortUnificationServer(url2, handler);
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,7 @@ import org.apache.dubbo.remoting.transport.netty4.NettyConnectionClient;
|
||||||
import org.apache.dubbo.remoting.transport.netty4.NettyPortUnificationServer;
|
import org.apache.dubbo.remoting.transport.netty4.NettyPortUnificationServer;
|
||||||
import org.apache.dubbo.rpc.model.ApplicationModel;
|
import org.apache.dubbo.rpc.model.ApplicationModel;
|
||||||
import org.apache.dubbo.rpc.model.ModuleModel;
|
import org.apache.dubbo.rpc.model.ModuleModel;
|
||||||
|
|
||||||
import org.junit.jupiter.api.AfterAll;
|
import org.junit.jupiter.api.AfterAll;
|
||||||
import org.junit.jupiter.api.Assertions;
|
import org.junit.jupiter.api.Assertions;
|
||||||
import org.junit.jupiter.api.BeforeAll;
|
import org.junit.jupiter.api.BeforeAll;
|
||||||
|
|
@ -51,7 +52,7 @@ public class SingleProtocolConnectionManagerTest {
|
||||||
private static ConnectionManager connectionManager;
|
private static ConnectionManager connectionManager;
|
||||||
|
|
||||||
@BeforeAll
|
@BeforeAll
|
||||||
public static void init() throws RemotingException {
|
public static void init() throws Throwable {
|
||||||
int port = NetUtils.getAvailablePort();
|
int port = NetUtils.getAvailablePort();
|
||||||
url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
url = URL.valueOf("empty://127.0.0.1:" + port + "?foo=bar");
|
||||||
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
ApplicationModel applicationModel = ApplicationModel.defaultModel();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue