运行 Gradle JUnit 测试时出现“地址已在使用:绑定”异常

Posted

技术标签:

【中文标题】运行 Gradle JUnit 测试时出现“地址已在使用:绑定”异常【英文标题】:"Address already in use: bind" exception when running Gradle JUnit tests 【发布时间】:2015-07-26 06:19:55 【问题描述】:

我将 Spring Boot 1.2.1.RELEASE、JUnit4 和 Gradle 2.1 用于 RESTful 服务,并尝试定义一个包含和/或覆盖仅在 JUnit 测试中使用的值的属性文件。 当作为 JUnit 测试调用时,所有测试都会毫无问题地执行。但是,当在 gradle“构建”或“测试”任务期间运行这些相同的测试时,它们会失败并出现异常“原因:java.lang.IllegalStateException:Tomcat 连接器处于失败状态”,根​​本原因是“java.net .BindException: 地址已在使用中:bind"。

有多个测试类需要应用程序上下文才能运行。

为了通过属性文件促进替代值,我已经包含了 TestPropertySource()

是否需要额外的 Gradle 配置才能完成这项工作?

ControllerTest 类

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes = RESTAdapter.class)
@TestPropertySource(locations="classpath:application-junit.properties")
public class ControllerTest 

    @Value("$test.token")
    private String token;

    @Autowired
    private WebApplicationContext wac;

    private MockMvc mockMvc;

    @Before
    public void setup() 
          this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
    

    public void TestMockMvc(String[] strings) throws Exception

        mockMvc.perform(URL_all_paramters, strings)
            .param(Constants.PARAM_TOKEN, token)
            .accept(Constants.APPLICATION_JSON_UTF8))
            .andDo(print())
            .andExpect(status().isOk())
            .andExpect(content().contentType(Constants.APPLICATION_JSON_UTF8))
            .andExpect(content().json(strings[strings.length-1]));
    
   

application.properties (/src/main/resources)

logging.level.org.springframework.web=TRACE
server.port=4040
shape.file=./shape/tl_2014_34_tabblock10_county_muni.shp

application-junit.properties (/src/test/resources)

test.token=..dDKidjwel

build.gradle

buildscript 
    ext 
        springBootVersion = '1.2.1.RELEASE'
    
    repositories 
        mavenCentral()
    
    dependencies 
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion")
    


apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'idea'
apply plugin: 'spring-boot' 

jar 
    baseName = 'RESTfulWebServiceAdapter'
    version = '1.1.1-SNAPSHOT'


springBoot
    mainClass = 'com.myapp.RESTAdapter'


sourceCompatibility = 1.8
targetCompatibility = 1.8

repositories 
    maven  url 'http://download.osgeo.org/webdav/geotools' //order important for jai lib
    mavenCentral()
    maven  url 'https://repo.spring.io/libs-release'



dependencies 
    compile fileTree(dir: 'lib', include: '*.jar')
    compile('org.springframework.boot:spring-boot-starter-actuator')
    compile('org.springframework.boot:spring-boot-starter-ws')  
    compile('org.geotools:gt-shapefile:9.4')
    compile('org.geotools:gt-data:9.4')
    compile('org.geotools:gt-cql:9.4')
    compile('commons-httpclient:commons-httpclient:3.1')
    compile('org.springframework.boot:spring-boot-loader')
    compile('org.springframework:spring-aspects:4.1.6.RELEASE')
    compile('org.aspectj:aspectjweaver:1.8.5')

    testCompile('org.springframework.boot:spring-boot-starter-test')
    testCompile('org.springframework.boot:spring-boot-starter-batch')
    testCompile('org.skyscreamer:jsonassert:1.2.3')
    testCompile('com.jayway.jsonpath:json-path')



eclipse 
    classpath 
         containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER')
         containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8'
    


task wrapper(type: Wrapper) 
    gradleVersion = '2.1'


sourceSets 
    main 

        resources 
            srcDir 'config'
        
    

堆栈跟踪:

2015-05-14 13:51:29.691 ERROR 5652 --- [    Test worker] o.a.coyote.http11.Http11NioProtocol      : Failed to start end point associated with ProtocolHandler ["http-nio-10001"]

java.net.BindException: Address already in use: bind
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:436)
    at sun.nio.ch.Net.bind(Net.java:428)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:343)
    at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:739)
    at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:472)
    at org.apache.coyote.http11.Http11NioProtocol.start(Http11NioProtocol.java:81)
    at org.apache.catalina.connector.Connector.startInternal(Connector.java:986)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    at org.apache.catalina.core.StandardService.addConnector(StandardService.java:237)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.addPreviouslyRemovedConnectors(TomcatEmbeddedServletContainer.java:186)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:149)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration.createChildManagementContext(EndpointWebMvcAutoConfiguration.java:219)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration.afterSingletonsInstantiated(EndpointWebMvcAutoConfiguration.java:141)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:100)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:170)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:110)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:105)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
    at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
    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)

2015-05-14 13:51:29.695 ERROR 5652 --- [    Test worker] o.apache.catalina.core.StandardService   : Failed to start connector [Connector[HTTP/1.1-10001]]

org.apache.catalina.LifecycleException: Failed to start component [Connector[HTTP/1.1-10001]]
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:154)
    at org.apache.catalina.core.StandardService.addConnector(StandardService.java:237)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.addPreviouslyRemovedConnectors(TomcatEmbeddedServletContainer.java:186)
    at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:149)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:483)
    at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration.createChildManagementContext(EndpointWebMvcAutoConfiguration.java:219)
    at org.springframework.boot.actuate.autoconfigure.EndpointWebMvcAutoConfiguration.afterSingletonsInstantiated(EndpointWebMvcAutoConfiguration.java:141)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:775)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:320)
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:100)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:68)
    at org.springframework.test.context.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:86)
    at org.springframework.test.context.DefaultTestContext.getApplicationContext(DefaultTestContext.java:72)
    at org.springframework.test.context.web.ServletTestExecutionListener.setUpRequestContextIfNecessary(ServletTestExecutionListener.java:170)
    at org.springframework.test.context.web.ServletTestExecutionListener.prepareTestInstance(ServletTestExecutionListener.java:110)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:212)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:200)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:259)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:261)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:219)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:86)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:49)
    at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:69)
    at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:48)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
    at org.gradle.messaging.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
    at com.sun.proxy.$Proxy2.processTestClass(Unknown Source)
    at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:105)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
    at org.gradle.messaging.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
    at org.gradle.messaging.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:355)
    at org.gradle.internal.concurrent.DefaultExecutorFactory$StoppableExecutorImpl$1.run(DefaultExecutorFactory.java:64)
    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: org.apache.catalina.LifecycleException: service.getName(): "Tomcat";  Protocol handler start failed
    at org.apache.catalina.connector.Connector.startInternal(Connector.java:993)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
    ... 61 common frames omitted
Caused by: java.net.BindException: Address already in use: bind
    at sun.nio.ch.Net.bind0(Native Method)
    at sun.nio.ch.Net.bind(Net.java:436)
    at sun.nio.ch.Net.bind(Net.java:428)
    at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:214)
    at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74)
    at org.apache.tomcat.util.net.NioEndpoint.bind(NioEndpoint.java:343)
    at org.apache.tomcat.util.net.AbstractEndpoint.start(AbstractEndpoint.java:739)
    at org.apache.coyote.AbstractProtocol.start(AbstractProtocol.java:472)
    at org.apache.coyote.http11.Http11NioProtocol.start(Http11NioProtocol.java:81)
    at org.apache.catalina.connector.Connector.startInternal(Connector.java:986)
    ... 62 common frames omitted

【问题讨论】:

【参考方案1】:

Gradle 正在启动另一个嵌入式 Tomcat 服务器实例,导致绑定异常。将 -debug 标志添加到 Gradle 的执行中揭示了这一点。

Gradle 的测试,forEvery 属性,默认为 0(没有最大值)。它被描述为here

"在一个分叉测试中执行的最大测试类数 过程。达到此限制时,将重新启动分叉测试过程 到达。默认值为 0(没有最大值)。”

JUnit 测试是并行执行的,由于需要运行应用程序上下文的多个控制器测试,Tomcat 初始化时使用相同的端口。

可以将以下内容添加到 build.gradle 中,但会显着减慢测试速度:

build.gradle:

test

    forkEvery = 1

相反,只需在备用属性文件中覆盖 Tomcat 服务器端口(如 here 所述),让 Tomcat 每次启动时都使用未使用的端口进行初始化。

应用程序-junit.properties:

server.port=0

【讨论】:

以上是关于运行 Gradle JUnit 测试时出现“地址已在使用:绑定”异常的主要内容,如果未能解决你的问题,请参考以下文章

使用 Powermock 时出现 NoClassDefFoundError

Junit测试代码时出现initializationError 错误

SpringBoot项目测试时出现程序包org.junit.runner不存在

想要在 jUnit 测试中访问延迟加载的集合时出现 NullPointerException

在Katalon Studio中执行Junit测试时出现内部错误

在 Spring App 中将 MockitoMVC 与 Junit 一起使用时出现 *** 错误